a post-component library for building user-interfaces on the web.
at main 109 lines 4.1 kB view raw
1import { html } from 'dhtml' 2import { renderToReadableStream, renderToString } from 'dhtml/server' 3import { assert, assert_eq, test } from '../../../scripts/test/test.ts' 4 5test('basic html renders correctly', () => { 6 assert_eq(renderToString(html`<h1>Hello, world!</h1>`), '<?[><h1>Hello, world!</h1><?]>') 7}) 8 9test('basic html renders correctly via stream', async () => { 10 const stream = renderToReadableStream(html`<h1>Hello, world!</h1>`) 11 assert_eq(await new Response(stream).text(), '<?[><h1>Hello, world!</h1><?]>') 12}) 13 14test('inner content renders correctly', () => { 15 assert_eq(renderToString(html`<h1>${html`Inner content!`}</h1>`), '<?[><h1><?[>Inner content!<?]></h1><?]>') 16}) 17 18test('template with number renders correctly', () => { 19 const template = (n: number) => html`<h1>Hello, ${n}!</h1>` 20 assert_eq(renderToString(template(1)), '<?[><h1>Hello, <?[>1<?]>!</h1><?]>') 21 assert_eq(renderToString(template(2)), '<?[><h1>Hello, <?[>2<?]>!</h1><?]>') 22}) 23 24test('lists of items', () => { 25 assert_eq(renderToString([1, 'a', html`<span>thing</span>`]), '<?[><?[>1<?]><?[>a<?]><?[><span>thing</span><?]><?]>') 26}) 27 28test('basic children render correctly', () => { 29 assert_eq( 30 renderToString(html`<span>${'This is a'}</span> ${html`test`} ${html`test`} ${html`test`}`), 31 '<?[><span><?[>This is a<?]></span> <?[>test<?]> <?[>test<?]> <?[>test<?]><?]>', 32 ) 33}) 34 35test('undefined children render empty', () => { 36 assert_eq(renderToString(html`<div>${undefined}</div>`), '<?[><div><?[><?]></div><?]>') 37 assert_eq(renderToString(html`<div>${null}</div>`), '<?[><div><?[><?]></div><?]>') 38}) 39 40if (__DEV__) { 41 test('invalid part placement raises error', () => { 42 try { 43 renderToString(html`<${'div'}>${'text'}</${'div'}>`) 44 assert(false, 'Expected error to be thrown') 45 } catch (error) { 46 assert(error instanceof Error) 47 } 48 }) 49} 50 51test('parts in comments do not throw', () => { 52 renderToString(html`<!-- ${'text'} -->`) 53}) 54 55if (__DEV__) { 56 test('manually specifying internal template syntax throws', () => { 57 try { 58 // why is prettier deleting null bytes? 59 // prettier-ignore 60 renderToString(html`${1} \0`) 61 assert(false, 'Expected error to be thrown') 62 } catch (error) { 63 assert(error instanceof Error) 64 } 65 }) 66} 67 68test('directives', () => { 69 let calls = 0 70 const directive = () => { 71 calls++ 72 } 73 assert_eq(renderToString(html`<p ${directive}></p>`), '<?[><p ></p><?]>') 74 assert_eq(calls, 0) // TODO: what should these look like on the server? 75}) 76 77test('nullish directives are ignored', () => { 78 assert_eq(renderToString(html`<p ${undefined}></p>`), '<?[><p ></p><?]>') 79 assert_eq(renderToString(html`<div ${null}></div>`), '<?[><div ></div><?]>') 80}) 81 82test('unquoted attributes', () => { 83 assert_eq(renderToString(html`<a href=${'/url'}></a>`), '<?[><a href="/url"></a><?]>') 84 assert_eq(renderToString(html`<details hidden=${false}></details>`), '<?[><details ></details><?]>') 85 assert_eq(renderToString(html`<details hidden=${true}></details>`), '<?[><details hidden></details><?]>') 86 assert_eq(renderToString(html`<details hidden=${undefined}></details>`), '<?[><details ></details><?]>') 87}) 88 89test('quoted attributes', () => { 90 assert_eq(renderToString(html`<a href="${'/url'}"></a>`), '<?[><a href="/url"></a><?]>') 91 assert_eq(renderToString(html`<details hidden="${false}"></details>`), '<?[><details ></details><?]>') 92 // prettier-ignore 93 assert_eq(renderToString(html`<details hidden='${true}'></details>`), '<?[><details hidden></details><?]>') 94}) 95 96test('collapses whitespace', () => { 97 // prettier-ignore 98 assert_eq(renderToString(html` <p> </p> `), '<?[> <p> </p> <?]>') 99 100 // prettier-ignore 101 assert_eq(renderToString(html` <p> x </p> `), '<?[> <p> x </p> <?]>') 102}) 103 104test('lexer edge cases', () => { 105 // prettier-ignore 106 assert_eq(renderToString(html`<div attr="value"x>`), '<?[><div attr="value"x><?]>') 107 assert_eq(renderToString(html`<img/attr="value">`), '<?[><img/attr="value"><?]>') 108 assert_eq(renderToString(html`<div attr /other="value"></div>`), '<?[><div attr /other="value"></div><?]>') 109})