UNPKG

@zeix/ui-element

Version:

UIElement - a HTML-first library for reactive Web Components

365 lines (340 loc) 9 kB
<!doctype html> <html> <head> <title>insertOrRemoveElement Tests</title> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> </head> <body> <create-element before="0" prepend="0" append="0" after="0"> <ul></ul> </create-element> <remove-element> <li data-key="1">Item 1</li> <li data-key="2">Item 2</li> <li data-key="3">Item 3</li> </remove-element> <insert-template id="insert-light" before="0" prepend="0" append="0" after="0" > <ul></ul> <template class="p"> <p>Template paragraph</p> </template> <template class="li"> <li>Template list item</li> </template> </insert-template> <script type="module"> import { runTests } from '@web/test-runner-mocha' import { assert } from '@esm-bundle/chai' import { component, asNumber, insertOrRemoveElement, } from '../../index.dev.js' const animationFrame = async () => new Promise(requestAnimationFrame) component( 'create-element', { before: asNumber(), prepend: asNumber(), append: asNumber(), after: asNumber(), }, (el, { first }) => [ first( 'ul', insertOrRemoveElement('before', { create: () => { const p = document.createElement('p') p.textContent = 'Before' return p }, position: 'beforebegin', }), insertOrRemoveElement('prepend', { create: () => { const li = document.createElement('li') li.textContent = 'Prepend' li.setAttribute('value', 'foo') return li }, position: 'afterbegin', }), insertOrRemoveElement('append', { create: () => document.createElement('li'), }), insertOrRemoveElement('after', { create: () => { const p = document.createElement('p') p.setAttribute('value', 'bar') return p }, position: 'afterend', }), ), ], ) component( 'remove-element', { items: [1, 2, 3], }, (el, { all }) => [ all( 'li', insertOrRemoveElement(li => el.items.includes(parseInt(li.dataset.key)) ? 0 : -1, ), ), ], ) component( 'insert-template', { before: asNumber(), prepend: asNumber(), append: asNumber(), after: asNumber(), }, (el, { first }) => { const pTemplate = el.querySelector('.p') const liTemplate = el.querySelector('.li') return [ first( 'ul', insertOrRemoveElement('before', { create: () => document.importNode(pTemplate.content, true) .firstElementChild, position: 'beforebegin', }), insertOrRemoveElement('prepend', { create: () => document.importNode( liTemplate.content, true, ).firstElementChild, position: 'afterbegin', }), insertOrRemoveElement('append', { create: () => document.importNode( liTemplate.content, true, ).firstElementChild, }), insertOrRemoveElement('after', { create: () => document.importNode(pTemplate.content, true) .firstElementChild, position: 'afterend', }), ), ] }, ) runTests(() => { describe('insertOrRemoveElement()', function () { describe('createElement', function () { let createElementComponent before(() => { createElementComponent = document.querySelector('create-element') }) it('should insert a paragraph before the UL', async function () { createElementComponent.before = 1 const insertedParagraph = createElementComponent.querySelector( 'p:first-child', ) assert.isNotNull( insertedParagraph, 'Paragraph should be inserted before the UL', ) assert.equal( insertedParagraph.textContent, 'Before', 'Paragraph should have correct text content', ) assert.equal( createElementComponent.before, 0, 'Before signal should be reset to 0', ) }) it('should insert a LI at the beginning of the UL', async function () { createElementComponent.prepend = 1 const insertedLi = createElementComponent.querySelector( 'ul li:first-child', ) assert.isNotNull( insertedLi, 'LI should be inserted at the beginning of the UL', ) assert.equal( insertedLi.textContent, 'Prepend', 'LI should have correct text content', ) assert.equal( insertedLi.getAttribute('value'), 'foo', 'LI should have correct attribute', ) assert.equal( createElementComponent.prepend, 0, 'Prepend signal should be reset to 0', ) }) it('should insert a LI at the end of the UL', async function () { createElementComponent.append = 1 const insertedLi = createElementComponent.querySelector( 'ul li:last-child', ) assert.isNotNull( insertedLi, 'LI should be inserted at the end of the UL', ) assert.equal( insertedLi.textContent, '', 'LI should have empty text content', ) assert.equal( createElementComponent.append, 0, 'Append signal should be reset to 0', ) }) it('should insert a paragraph after the UL', async function () { createElementComponent.after = 1 const insertedParagraph = createElementComponent.querySelector('ul + p') assert.isNotNull( insertedParagraph, 'Paragraph should be inserted after the UL', ) assert.equal( insertedParagraph.textContent, '', 'Paragraph should have empty text content', ) assert.equal( insertedParagraph.getAttribute('value'), 'bar', 'Paragraph should have correct attribute', ) assert.equal( createElementComponent.after, 0, 'After signal should be reset to 0', ) }) it('should insert multiple elements when value is greater than 1', async function () { createElementComponent.append = 3 const insertedLis = createElementComponent.querySelectorAll('ul li') assert.equal( insertedLis.length, 4, // 3 new + 1 from previous test 'Should insert 3 new LI elements', ) assert.equal( createElementComponent.append, 0, 'Append signal should be reset to 0', ) }) }) describe('removeElement', function () { let removeElementComponent before(() => { removeElementComponent = document.querySelector('remove-element') }) it('should remove an item using immutable update', async function () { const originalItems = removeElementComponent.items removeElementComponent.items = originalItems.toSpliced(1, 1) const items = removeElementComponent.querySelectorAll('li') assert.equal( items.length, 2, 'Should have 2 items after removal', ) assert.equal( items[0].textContent, 'Item 1', 'First item should remain', ) assert.equal( items[1].textContent, 'Item 3', 'Third item should now be second', ) }) it('should handle removing all items', async function () { removeElementComponent.items = [] const items = removeElementComponent.querySelectorAll('li') assert.equal( items.length, 0, 'Should remove all items', ) }) }) describe('insertTemplate', function () { it('should work with template elements', async function () { const component = document.getElementById('insert-light') const ul = component.querySelector('ul') await customElements.whenDefined('insert-template') assert.equal( ul.children.length, 0, 'Initially, ul should be empty', ) component.before = 1 assert.equal( ul.previousElementSibling.tagName, 'P', 'Should insert p element before ul', ) component.prepend = 1 assert.equal( ul.firstElementChild.tagName, 'LI', 'Should prepend li element to ul', ) component.append = 1 assert.equal( ul.lastElementChild.tagName, 'LI', 'Should append li element to ul', ) component.after = 1 assert.equal( ul.nextElementSibling.tagName, 'P', 'Should insert p element after ul', ) }) }) }) }) </script> </body> </html>