insanity
This commit is contained in:
parent
7bcd582dc6
commit
7756306e1d
|
|
@ -53,84 +53,3 @@ signals.trap 'EXIT':
|
||||||
end`).toEvaluateTo(['EXIT', true])
|
end`).toEvaluateTo(['EXIT', true])
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('ribbit', () => {
|
|
||||||
test('head tag', () => {
|
|
||||||
expect(`
|
|
||||||
head:
|
|
||||||
title What up
|
|
||||||
meta charSet=UTF-8
|
|
||||||
meta name=viewport content='width=device-width, initial-scale=1, viewport-fit=cover'
|
|
||||||
end`).toEvaluateTo(`head`, {
|
|
||||||
head: () => 'head'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('li', () => {
|
|
||||||
expect(`
|
|
||||||
list:
|
|
||||||
li border-bottom='1px solid black' one
|
|
||||||
li two
|
|
||||||
li three
|
|
||||||
end`).toEvaluateTo(`list`, {
|
|
||||||
list: () => 'list'
|
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
test('inline expressions', () => {
|
|
||||||
const buffer: string[] = []
|
|
||||||
|
|
||||||
const tagBlock = async (tagName: string, props = {}, fn: Function) => {
|
|
||||||
const attrs = Object.entries(props).map(([key, value]) => `${key}="${value}"`)
|
|
||||||
const space = attrs.length ? ' ' : ''
|
|
||||||
|
|
||||||
buffer.push(`<${tagName}${space}${attrs.join(' ')}>`)
|
|
||||||
await fn()
|
|
||||||
buffer.push(`</${tagName}>`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const tagCall = (tagName: string, atNamed: {}, ...args: any[]) => {
|
|
||||||
const attrs = Object.entries(atNamed).map(([key, value]) => `${key}="${value}"`)
|
|
||||||
const space = attrs.length ? ' ' : ''
|
|
||||||
const children = args
|
|
||||||
.reverse()
|
|
||||||
.map(a => a === null ? buffer.pop() : a)
|
|
||||||
.reverse().join(' ')
|
|
||||||
.replaceAll(' !!ribbit-nospace!! ', '')
|
|
||||||
|
|
||||||
buffer.push(`<${tagName}${space}${attrs.join(' ')}>${children}</${tagName}>`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const tag = async (tagName: string, atNamed: {}, ...args: any[]) => {
|
|
||||||
if (typeof args[0] === 'function')
|
|
||||||
await tagBlock(tagName, atNamed, args[0])
|
|
||||||
else
|
|
||||||
tagCall(tagName, atNamed, ...args)
|
|
||||||
}
|
|
||||||
|
|
||||||
expect(`
|
|
||||||
ribbit:
|
|
||||||
p class=container:
|
|
||||||
h1 class=bright style='font-family: helvetica' Heya
|
|
||||||
h2 man that is (b wild) (nospace) !
|
|
||||||
p Double the fun.
|
|
||||||
end
|
|
||||||
end`).toEvaluateTo(
|
|
||||||
`<p class="container">
|
|
||||||
<h1 class="bright" style="font-family: helvetica">Heya</h1>
|
|
||||||
<h2>man that is <b>wild</b>!</h2>
|
|
||||||
<p>Double the fun.</p>
|
|
||||||
</p>`, {
|
|
||||||
ribbit: async (cb: Function) => {
|
|
||||||
await cb()
|
|
||||||
return buffer.join("\n")
|
|
||||||
},
|
|
||||||
p: (atNamed: {}, ...args: any[]) => tag('p', atNamed, ...args),
|
|
||||||
h1: (atNamed: {}, ...args: any[]) => tag('h1', atNamed, ...args),
|
|
||||||
h2: (atNamed: {}, ...args: any[]) => tag('h2', atNamed, ...args),
|
|
||||||
b: (atNamed: {}, ...args: any[]) => tag('b', atNamed, ...args),
|
|
||||||
nospace: () => '!!ribbit-nospace!!',
|
|
||||||
join: (...args: string[]) => args.join(''),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
|
||||||
113
src/compiler/tests/ribbit.test.ts
Normal file
113
src/compiler/tests/ribbit.test.ts
Normal file
|
|
@ -0,0 +1,113 @@
|
||||||
|
import { expect, describe, test, beforeEach } from 'bun:test'
|
||||||
|
import { type Value } from 'reefvm'
|
||||||
|
|
||||||
|
const buffer: string[] = []
|
||||||
|
|
||||||
|
const ribbitGlobals = {
|
||||||
|
ribbit: async (cb: Function) => {
|
||||||
|
await cb()
|
||||||
|
return buffer.join("\n")
|
||||||
|
},
|
||||||
|
tag: (tagName: string, atDefaults = {}) => {
|
||||||
|
return (atNamed = {}, ...args: any[]) => tag(tagName, Object.assign({}, atDefaults, atNamed), ...args)
|
||||||
|
},
|
||||||
|
head: (atNamed: {}, ...args: any[]) => tag('head', atNamed, ...args),
|
||||||
|
title: (atNamed: {}, ...args: any[]) => tag('title', atNamed, ...args),
|
||||||
|
meta: (atNamed: {}, ...args: any[]) => tag('meta', atNamed, ...args),
|
||||||
|
p: (atNamed: {}, ...args: any[]) => tag('p', atNamed, ...args),
|
||||||
|
h1: (atNamed: {}, ...args: any[]) => tag('h1', atNamed, ...args),
|
||||||
|
h2: (atNamed: {}, ...args: any[]) => tag('h2', atNamed, ...args),
|
||||||
|
b: (atNamed: {}, ...args: any[]) => tag('b', atNamed, ...args),
|
||||||
|
ul: (atNamed: {}, ...args: any[]) => tag('ul', atNamed, ...args),
|
||||||
|
li: (atNamed: {}, ...args: any[]) => tag('li', atNamed, ...args),
|
||||||
|
nospace: () => NOSPACE_TOKEN,
|
||||||
|
echo: (...args: any[]) => console.log(...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
function raw(fn: Function) { (fn as any).raw = true }
|
||||||
|
|
||||||
|
const tagBlock = async (tagName: string, props = {}, fn: Function) => {
|
||||||
|
const attrs = Object.entries(props).map(([key, value]) => `${key}="${value}"`)
|
||||||
|
const space = attrs.length ? ' ' : ''
|
||||||
|
|
||||||
|
buffer.push(`<${tagName}${space}${attrs.join(' ')}>`)
|
||||||
|
await fn()
|
||||||
|
buffer.push(`</${tagName}>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tagCall = (tagName: string, atNamed = {}, ...args: any[]) => {
|
||||||
|
const attrs = Object.entries(atNamed).map(([key, value]) => `${key}="${value}"`)
|
||||||
|
const space = attrs.length ? ' ' : ''
|
||||||
|
const children = args
|
||||||
|
.reverse()
|
||||||
|
.map(a => a === null ? buffer.pop() : a)
|
||||||
|
.reverse().join(' ')
|
||||||
|
.replaceAll(` ${NOSPACE_TOKEN} `, '')
|
||||||
|
|
||||||
|
if (SELF_CLOSING.includes(tagName))
|
||||||
|
buffer.push(`<${tagName}${space}${attrs.join(' ')} />`)
|
||||||
|
else
|
||||||
|
buffer.push(`<${tagName}${space}${attrs.join(' ')}>${children}</${tagName}>`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tag = async (tagName: string, atNamed = {}, ...args: any[]) => {
|
||||||
|
if (typeof args[0] === 'function')
|
||||||
|
await tagBlock(tagName, atNamed, args[0])
|
||||||
|
else
|
||||||
|
tagCall(tagName, atNamed, ...args)
|
||||||
|
}
|
||||||
|
|
||||||
|
const NOSPACE_TOKEN = '!!ribbit-nospace!!'
|
||||||
|
const SELF_CLOSING = ["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]
|
||||||
|
|
||||||
|
describe('ribbit', () => {
|
||||||
|
beforeEach(() => buffer.length = 0)
|
||||||
|
|
||||||
|
test('head tag', () => {
|
||||||
|
expect(`
|
||||||
|
ribbit:
|
||||||
|
head:
|
||||||
|
title What up
|
||||||
|
meta charset=UTF-8
|
||||||
|
meta name=viewport content='width=device-width, initial-scale=1, viewport-fit=cover'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
`).toEvaluateTo(`<head>
|
||||||
|
<title>What up</title>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" />
|
||||||
|
</head>`, ribbitGlobals)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('custom tags', () => {
|
||||||
|
expect(`
|
||||||
|
list = tag 'ul' class=list
|
||||||
|
ribbit:
|
||||||
|
list:
|
||||||
|
li border-bottom='1px solid black' one
|
||||||
|
li two
|
||||||
|
li three
|
||||||
|
end
|
||||||
|
end`).toEvaluateTo(`<ul class="list">
|
||||||
|
<li border-bottom="1px solid black">one</li>
|
||||||
|
<li>two</li>
|
||||||
|
<li>three</li>
|
||||||
|
</ul>`, ribbitGlobals)
|
||||||
|
})
|
||||||
|
|
||||||
|
test('inline expressions', () => {
|
||||||
|
expect(`
|
||||||
|
ribbit:
|
||||||
|
p class=container:
|
||||||
|
h1 class=bright style='font-family: helvetica' Heya
|
||||||
|
h2 man that is (b wild) (nospace) !
|
||||||
|
p Double the fun.
|
||||||
|
end
|
||||||
|
end`).toEvaluateTo(
|
||||||
|
`<p class="container">
|
||||||
|
<h1 class="bright" style="font-family: helvetica">Heya</h1>
|
||||||
|
<h2>man that is <b>wild</b>!</h2>
|
||||||
|
<p>Double the fun.</p>
|
||||||
|
</p>`, ribbitGlobals)
|
||||||
|
})
|
||||||
|
})
|
||||||
Loading…
Reference in New Issue
Block a user