Skip to content

Commit a868987

Browse files
committed
test(schema2ui): align tests with Render module and new tags 🎢
- Add Constant tests for boolean attrs and containerTags (semantic and inline) - Add DOM globals for HTMLImageElement, HTMLAnchorElement, HTMLDetailsElement, HTMLDialogElement - Add Helper tests for new el.* tags (details, dialog, figure, fieldset, select, meter, audio, video, etc.) - Update Render import to Render/index and reorder Constant assertions to match source
1 parent 24afb12 commit a868987

File tree

5 files changed

+376
-35
lines changed

5 files changed

+376
-35
lines changed

tests/Constant.test.ts

Lines changed: 69 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ import Constant from '@app/Constant.ts'
33

44
Deno.test('Constant.allowedNodeKeys contains all required keys', () => {
55
const requiredKeys = [
6-
'type',
7-
'id',
8-
'layout',
9-
'style',
6+
'alt',
107
'attrs',
8+
'children',
119
'content',
10+
'id',
11+
'layout',
1212
'src',
13-
'alt',
14-
'children'
13+
'style',
14+
'type'
1515
]
1616
assertEquals(Constant.allowedNodeKeys.size, requiredKeys.length)
1717
for (const key of requiredKeys) {
@@ -27,9 +27,20 @@ Deno.test('Constant.allowedPropsKeys excludes type and children', () => {
2727
})
2828

2929
Deno.test('Constant.booleanAttrKeys contains expected boolean attributes', () => {
30-
const expected = ['checked', 'disabled', 'readonly', 'selected', 'inert', 'hidden']
31-
assertEquals(Constant.booleanAttrKeys.size, expected.length)
32-
for (const key of expected) {
30+
const expectedBooleanAttrs = [
31+
'autofocus',
32+
'checked',
33+
'disabled',
34+
'hidden',
35+
'inert',
36+
'multiple',
37+
'open',
38+
'readonly',
39+
'required',
40+
'selected'
41+
]
42+
assertEquals(Constant.booleanAttrKeys.size, expectedBooleanAttrs.length)
43+
for (const key of expectedBooleanAttrs) {
3344
assertEquals(Constant.booleanAttrKeys.has(key), true)
3445
}
3546
})
@@ -40,6 +51,55 @@ Deno.test('Constant.containerTags does not include void tags', () => {
4051
}
4152
})
4253

54+
Deno.test('Constant.containerTags includes new form table semantic tags', () => {
55+
const expectedSemanticTags = [
56+
'address',
57+
'blockquote',
58+
'caption',
59+
'colgroup',
60+
'dd',
61+
'dl',
62+
'dt',
63+
'fieldset',
64+
'legend',
65+
'menu',
66+
'optgroup',
67+
'option',
68+
'output',
69+
'pre',
70+
'progress',
71+
'search',
72+
'select',
73+
'textarea',
74+
'tfoot'
75+
]
76+
for (const tag of expectedSemanticTags) {
77+
assertEquals(Constant.containerTags.includes(tag), true)
78+
}
79+
})
80+
81+
Deno.test('Constant.containerTags includes meter audio video hgroup and inline tags', () => {
82+
const expectedInlineTags = [
83+
'abbr',
84+
'audio',
85+
'cite',
86+
'code',
87+
'del',
88+
'em',
89+
'hgroup',
90+
'ins',
91+
'mark',
92+
'meter',
93+
'q',
94+
'strong',
95+
'time',
96+
'video'
97+
]
98+
for (const tag of expectedInlineTags) {
99+
assertEquals(Constant.containerTags.includes(tag), true)
100+
}
101+
})
102+
43103
Deno.test('Constant.svgNamespace is SVG namespace string', () => {
44104
assertEquals(Constant.svgNamespace, 'http://www.w3.org/2000/svg')
45105
})

tests/DOM.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ globalScope['HTMLButtonElement'] = window.HTMLButtonElement
99
globalScope['HTMLTextAreaElement'] = window.HTMLTextAreaElement
1010
globalScope['HTMLSelectElement'] = window.HTMLSelectElement
1111
globalScope['HTMLFieldSetElement'] = window.HTMLFieldSetElement
12+
globalScope['HTMLImageElement'] = window.HTMLImageElement
13+
globalScope['HTMLAnchorElement'] = window.HTMLAnchorElement
14+
globalScope['HTMLDetailsElement'] = window.HTMLDetailsElement
15+
globalScope['HTMLDialogElement'] = window.HTMLDialogElement
1216
globalScope['HTMLOptGroupElement'] = window.HTMLOptGroupElement
1317
globalScope['HTMLOptionElement'] = window.HTMLOptionElement
1418

tests/Helper.test.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,59 @@ Deno.test('create(el.root(...)) produces valid schema', () => {
2323
assertEquals(schema.root[1]?.children?.[0]?.content, 'Home')
2424
})
2525

26+
Deno.test('el.blockquote and el.pre exist', () => {
27+
const quoteNode = el.blockquote('Quote')
28+
assertEquals(quoteNode.type, 'blockquote')
29+
assertEquals(quoteNode.content, 'Quote')
30+
const preNode = el.pre('code')
31+
assertEquals(preNode.type, 'pre')
32+
assertEquals(preNode.content, 'code')
33+
})
34+
35+
Deno.test('el.cite el.q el.del el.ins el.em exist', () => {
36+
assertEquals(el.cite('Source').type, 'cite')
37+
assertEquals(el.q('short quote').type, 'q')
38+
assertEquals(el.del('removed').type, 'del')
39+
assertEquals(el.ins('added').type, 'ins')
40+
assertEquals(el.em('emphasis').type, 'em')
41+
})
42+
43+
Deno.test('el.datalist exists and returns node with type datalist', () => {
44+
const node = el.datalist()
45+
assertEquals(node.type, 'datalist')
46+
})
47+
48+
Deno.test('el.details exists and returns node with type details', () => {
49+
const node = el.details(el.summary('Toggle'), el.p('Content'))
50+
assertEquals(node.type, 'details')
51+
assertEquals(node.children?.length, 2)
52+
assertEquals(node.children?.[0]?.type, 'summary')
53+
assertEquals(node.children?.[1]?.type, 'p')
54+
})
55+
56+
Deno.test('el.details with open attr and el.dialog with open', () => {
57+
const details = el.details({ attrs: { open: true } }, el.summary('Open'), el.p('Content'))
58+
assertEquals(details.type, 'details')
59+
assertEquals(details.attrs?.['open'], true)
60+
const dialog = el.dialog({ attrs: { open: false } }, 'Close')
61+
assertEquals(dialog.type, 'dialog')
62+
assertEquals(dialog.attrs?.['open'], false)
63+
})
64+
65+
Deno.test('el.dialog exists and returns node with type dialog', () => {
66+
const node = el.dialog('Close')
67+
assertEquals(node.type, 'dialog')
68+
assertEquals(node.content, 'Close')
69+
})
70+
71+
Deno.test('el.dl el.dt el.dd exist', () => {
72+
const node = el.dl(el.dt('Term'), el.dd('Definition'))
73+
assertEquals(node.type, 'dl')
74+
assertEquals(node.children?.length, 2)
75+
assertEquals(node.children?.[0]?.type, 'dt')
76+
assertEquals(node.children?.[1]?.type, 'dd')
77+
})
78+
2679
Deno.test('el.div with children returns children array', () => {
2780
const node = el.div(el.span('a'), el.span('b'))
2881
assertEquals(node.type, 'div')
@@ -70,6 +123,44 @@ Deno.test('el.div() returns node with type div', () => {
70123
assertEquals(node.type, 'div')
71124
})
72125

126+
Deno.test('el.fieldset exists and returns node with type fieldset', () => {
127+
const node = el.fieldset(el.legend('Label'), el.input())
128+
assertEquals(node.type, 'fieldset')
129+
assertEquals(node.children?.length, 2)
130+
assertEquals(node.children?.[0]?.type, 'legend')
131+
})
132+
133+
Deno.test('el.figcaption exists and returns node with type figcaption', () => {
134+
const node = el.figcaption('Figure 1')
135+
assertEquals(node.type, 'figcaption')
136+
assertEquals(node.content, 'Figure 1')
137+
})
138+
139+
Deno.test('el.figure exists and returns node with type figure', () => {
140+
const node = el.figure(el.figcaption('Caption'), el.img({ src: '/x.png', alt: 'x' }))
141+
assertEquals(node.type, 'figure')
142+
assertEquals(node.children?.length, 2)
143+
assertEquals(node.children?.[0]?.type, 'figcaption')
144+
assertEquals(node.children?.[1]?.type, 'img')
145+
})
146+
147+
Deno.test('el.hgroup el.abbr el.code el.strong el.mark el.time exist', () => {
148+
const hg = el.hgroup(el.h1('Title'), el.p('Subtitle'))
149+
assertEquals(hg.type, 'hgroup')
150+
assertEquals(hg.children?.length, 2)
151+
assertEquals(el.abbr('WWW').type, 'abbr')
152+
assertEquals(el.abbr('WWW').content, 'WWW')
153+
assertEquals(el.code('const x = 1').type, 'code')
154+
assertEquals(el.strong('bold').type, 'strong')
155+
assertEquals(el.mark('highlight').type, 'mark')
156+
assertEquals(el.time({ attrs: { datetime: '2024-01-01' } }, 'Jan 1').type, 'time')
157+
})
158+
159+
Deno.test('el.iframe exists and returns node with type iframe', () => {
160+
const node = el.iframe()
161+
assertEquals(node.type, 'iframe')
162+
})
163+
73164
Deno.test('el.img with no args returns img node', () => {
74165
const node = el.img()
75166
assertEquals(node.type, 'img')
@@ -90,6 +181,19 @@ Deno.test('el.img with props returns img with src alt', () => {
90181
assertEquals(node.alt, 'image')
91182
})
92183

184+
Deno.test('el.meter el.audio el.video exist', () => {
185+
const meter = el.meter({ attrs: { value: 75, min: 0, max: 100 } }, '75%')
186+
assertEquals(meter.type, 'meter')
187+
assertEquals(meter.content, '75%')
188+
const audio = el.audio(el.source({ attrs: { src: '/audio.mp3', type: 'audio/mpeg' } }))
189+
assertEquals(audio.type, 'audio')
190+
assertEquals(audio.children?.length, 1)
191+
assertEquals(audio.children?.[0]?.type, 'source')
192+
const video = el.video(el.source({ attrs: { src: '/video.mp4', type: 'video/mp4' } }))
193+
assertEquals(video.type, 'video')
194+
assertEquals(video.children?.length, 1)
195+
})
196+
93197
Deno.test('el.node container with string and children throws', () => {
94198
assertThrows(
95199
() => el.node('div', 'text', el.span('x')),
@@ -127,6 +231,13 @@ Deno.test('el.node with first child then array of children', () => {
127231
assertEquals(node.children?.[2]?.content, 'c')
128232
})
129233

234+
Deno.test('el.picture exists and returns node with type picture', () => {
235+
const node = el.picture(el.img({ src: '/x.png', alt: 'x' }))
236+
assertEquals(node.type, 'picture')
237+
assertEquals(node.children?.length, 1)
238+
assertEquals(node.children?.[0]?.type, 'img')
239+
})
240+
130241
Deno.test('el.root with single node returns definition with one node', () => {
131242
const rootDefinition = el.root(el.p('only'))
132243
assertEquals(rootDefinition.root.length, 1)
@@ -153,13 +264,39 @@ Deno.test('el.root(n1, n2) returns definition with two nodes', () => {
153264
assertEquals(rootDefinition.root[1]?.type, 'span')
154265
})
155266

267+
Deno.test('el.search exists and returns node with type search', () => {
268+
const node = el.search(el.input({ attrs: { type: 'search', placeholder: 'Search' } }))
269+
assertEquals(node.type, 'search')
270+
assertEquals(node.children?.length, 1)
271+
assertEquals(node.children?.[0]?.type, 'input')
272+
})
273+
156274
Deno.test('el.section exists and returns node with type section', () => {
157275
const node = el.section(el.header('Header'))
158276
assertEquals(node.type, 'section')
159277
assertEquals(node.children?.length, 1)
160278
assertEquals(node.children?.[0]?.type, 'header')
161279
})
162280

281+
Deno.test('el.select and el.option exist', () => {
282+
const node = el.select(el.option('A'), el.option('B'))
283+
assertEquals(node.type, 'select')
284+
assertEquals(node.children?.length, 2)
285+
assertEquals(node.children?.[0]?.type, 'option')
286+
assertEquals(node.children?.[0]?.content, 'A')
287+
})
288+
289+
Deno.test('el.slot exists and returns node with type slot', () => {
290+
const node = el.slot()
291+
assertEquals(node.type, 'slot')
292+
})
293+
294+
Deno.test('el.summary exists and returns node with type summary', () => {
295+
const node = el.summary('Summary text')
296+
assertEquals(node.type, 'summary')
297+
assertEquals(node.content, 'Summary text')
298+
})
299+
163300
Deno.test('Helper.node() static equals Helper.el.node()', () => {
164301
const resultA = Helper.node('span', 'text')
165302
const resultB = Helper.el.node('span', 'text')

tests/Index.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,12 @@ Deno.test('create() throws when root is not array', () => {
1515
})
1616

1717
Deno.test('default export call returns object with create, render, el', () => {
18-
const api = Schema2UI()
19-
assertEquals(typeof api.create, 'function')
20-
assertEquals(typeof api.render, 'function')
21-
assertEquals(api.el != null, true)
22-
assertEquals(api.el.root != null, true)
23-
assertEquals(api.el.node != null, true)
18+
const publicApi = Schema2UI()
19+
assertEquals(typeof publicApi.create, 'function')
20+
assertEquals(typeof publicApi.render, 'function')
21+
assertEquals(publicApi.el != null, true)
22+
assertEquals(publicApi.el.root != null, true)
23+
assertEquals(publicApi.el.node != null, true)
2424
})
2525

2626
Deno.test('named create() equals Schema2UI.create()', () => {

0 commit comments

Comments
 (0)