Testing with Vitest
Testing an Ornata component is usually pretty simple: mount it onto real HTML, interact with it, make assertions, then clean it up.
Most Ornata tests come down to this:
- put real fixture markup in
document.body - call
Component.mount(...) - click, type, or update state
- check the DOM or
instance.state - call
Component.unmountAll()in cleanup
Test through the public API
Section titled “Test through the public API”Test Ornata components the same way other code would use them.
Component.mount(root)to create an instanceinstance.stateto check or update public stateinstance.addStateListener()to observe state changes from outside the componentinstance.dispose()to clean up one mounted instanceComponent.unmount(root)to remove a specific mounted instance by rootComponent.unmountAll()to clean up every mounted instance for that component
Use real HTML
Section titled “Use real HTML”Ornata is built to enhance existing HTML, so your test fixtures should look like the real markup the component expects.
document.body.innerHTML = ` <section data-disclosure> <button type="button" data-trigger>Toggle</button> <div data-panel hidden>Panel</div> </section>`;Mount the component in the test
Section titled “Mount the component in the test”In most Ornata tests, you will start by putting the expected HTML into the document, then mounting the component onto that markup.
const instance = Disclosure.mount('[data-disclosure]');This is usually the most useful way to start a test because it matches how Ornata is used in real pages. The component gets real markup, mounts to a real root element, and returns an instance you can use in the rest of the test.
Assert the component behavior
Section titled “Assert the component behavior”You will usually check one of a few things.
Visible DOM output
Disclosure.mount('[data-disclosure]');
await user.click(screen.getByRole('button', { name: 'Toggle' }));
expect(screen.getByText('Open')).toBeInTheDocument();Public state
const instance = Counter.mount('[data-counter]');
instance.state.count = 1;
expect(instance.state.count).toBe(1);Listener or lifecycle calls
const listener = vi.fn();const instance = Counter.mount(document.createElement('div'));
instance.addStateListener('count', listener);instance.state.count = 1;
expect(listener).toHaveBeenCalledWith({ property: 'count', newValue: 1, oldValue: 0, target: instance,});Clean up between tests
Section titled “Clean up between tests”If a file reuses the same component constructor across multiple tests, unmountAll() is the easiest cleanup.
afterEach(() => { Disclosure.unmountAll(); document.body.innerHTML = '';});This is especially handy when one test mounts more than one root, or when several tests reuse the same component.
If a test only creates one instance and you already have that reference, instance.dispose() is fine too.