From d86763d5c7042ea5b9457d173823abe0bd349018 Mon Sep 17 00:00:00 2001 From: "Sebastian L. K. Sorensen" Date: Mon, 20 May 2024 22:41:16 +0200 Subject: [PATCH] add tests for `walker.ts` --- src/__tests__/walker.test.ts | 112 +++++++++++++++++++++++++++++++++++ 1 file changed, 112 insertions(+) create mode 100644 src/__tests__/walker.test.ts diff --git a/src/__tests__/walker.test.ts b/src/__tests__/walker.test.ts new file mode 100644 index 0000000..1ab5f3a --- /dev/null +++ b/src/__tests__/walker.test.ts @@ -0,0 +1,112 @@ +import { fireEvent, getByRole, getByText } from '@testing-library/dom'; +import { Component, mount } from '../main'; +import { tags } from '../tags'; + +const { div, p, button, ul, li } = tags; + +afterEach(() => { + document.body.innerHTML = ''; +}); + +describe('walker', () => { + test('that it replaces when tagName differs', () => { + mount(document.body, { + state: { count: 0 }, + view: ({ state }) => { + return div([ + state.count === 0 ? p('Hello, world!') : div('Adios, world!'), + button('Click me', { + onclick: () => state.count++, + }), + ]); + }, + }); + + const btn = getByRole(document.body, 'button'); + + expect(getByText(document.body, /Hello, world!/).tagName).toBe('P'); + + fireEvent.click(btn); + + expect(getByText(document.body, /Adios, world!/).tagName).toBe('DIV'); + }); + + test('when node type is a text node', () => { + mount(document.body, { + state: { count: 0 }, + view: ({ state }) => { + return div([ + state.count === 0 ? 'Hello, world!' : 'Adios, world!', + button('Click me', { + onclick: () => state.count++, + }), + ]); + }, + }); + + const btn = getByRole(document.body, 'button'); + + expect(getByText(document.body, /Hello, world!/)).toBeDefined(); + + fireEvent.click(btn); + + expect(getByText(document.body, /Adios, world!/)).toBeDefined(); + }); + + test('attributes are removed', () => { + mount(document.body, { + state: { count: 0 }, + view: ({ state }) => + button('Click me', { + onclick: () => state.count++, + ['data-test']: state.count === 0, + }), + }); + + const btn = getByRole(document.body, 'button'); + + expect(btn.hasAttribute('data-test')).toBe(true); + + fireEvent.click(btn); + + expect(btn.hasAttribute('data-test')).toBe(false); + }); + + test('appending/removing children', () => { + type State = { items: string[] }; + + const Component: Component = { + state: { items: ['one', 'two', 'three'] }, + view: ({ state }) => { + return div([ + ul(state.items.map((item) => li(item))), + button('Add item', { + onclick: () => { + if (state.items.length === 4) { + state.items = ['one']; + } else { + state.items = [...state.items, 'four']; + } + }, + }), + ]); + }, + }; + + mount(document.body, Component); + + const btn = getByRole(document.body, 'button'); + + expect(getByText(document.body, /one/)).toBeDefined(); + + fireEvent.click(btn); + + expect(getByText(document.body, /four/)).toBeDefined(); + expect(document.querySelectorAll('li').length).toBe(4); + + fireEvent.click(btn); + + expect(getByText(document.body, /one/)).toBeDefined(); + expect(document.querySelectorAll('li').length).toBe(1); + }); +});