/**
* @vitest-environment jsdom
*/
import { compile } from '../src'
const parser: DOMParser = new DOMParser()
function parseHTML(html: string): string {
return parser.parseFromString(html, 'text/html').body.innerHTML
}
function getCompiledTemplates(template: string): string[] {
const { ast } = compile(template)
return Array.from(ast.template.keys())
}
function checkAbbr(
template: string,
abbreviation: string | string[],
expected: string | string[],
): void {
const abbreviations = Array.isArray(abbreviation)
? abbreviation
: [abbreviation]
const expectations = Array.isArray(expected) ? expected : [expected]
// verify compiler generates the abbreviated templates
expect(getCompiledTemplates(template)).toEqual(abbreviations)
// verify browser parses each abbreviation back to expected HTML
abbreviations.forEach((abbr, i) => {
expect(parseHTML(abbr)).toBe(expectations[i])
})
}
test('template abbreviation', () => {
// basic - last child can omit closing tag
checkAbbr('
hello
', 'hello', '
hello
')
checkAbbr(
'
',
'
hello',
'
',
)
// non-last child needs closing tag
checkAbbr(
'
foo
',
'
foo',
'foo
',
)
checkAbbr(
'',
'
',
'
',
)
checkAbbr(
'
',
'
',
'
',
)
// multi-root: each root generates its own template
checkAbbr(
'
hello',
['
', 'hello'],
['', 'hello'],
)
})
test('formatting tags', () => {
// formatting tags on rightmost path can omit closing tag
checkAbbr('bold
', 'bold', 'bold
')
checkAbbr(
'text
',
'text',
'text
',
)
// formatting tags NOT on rightmost path need closing tag
checkAbbr(
'bold
',
'bold',
'bold
',
)
checkAbbr(
'12
',
'12',
'12
',
)
})
test('same-name nested tags', () => {
// same-name on rightmost path can omit
checkAbbr(
'',
'inner',
'
',
)
// same-name NOT on rightmost path needs closing tag
checkAbbr(
'
',
'
a
b',
'
',
)
checkAbbr(
'
12',
'
12',
'12',
)
})
test('void tags', () => {
// void tags never need closing tags
checkAbbr('
', '', '
')
checkAbbr('
', '
', '
')
checkAbbr('
', '
', '
')
checkAbbr('
', '
![]()
', '
')
})
test('deeply nested', () => {
checkAbbr(
'
',
'
deep',
'',
)
checkAbbr(
'',
'ab',
'',
)
})
test('always close tags', () => {
// button always needs closing tag unless on rightmost path
checkAbbr(
'',
'