Testing
Rivet itself is tested with bun test and happy-dom. The same setup works for components in your project.
DOM environment
Section titled “DOM environment”happy-dom provides a DOM in Node/Bun. A setup file registers the global
document/window before tests run.
import { GlobalRegistrator } from "@happy-dom/global-registrator";
GlobalRegistrator.register();bun test --preload ./test/setup.tsTesting a component
Section titled “Testing a component”Build the markup in the DOM, mount the app and assert behaviour.
import { afterEach, expect, test } from "bun:test";import { createRivet, defineComponent } from "@fullhaus/rivet";
const counter = defineComponent(({ part, signal, on, effect }) => { const output = part("output"); const count = signal(0); on(part("inc"), "click", () => count.update((v) => v + 1)); effect(() => { output.textContent = String(count()); }); return { reset: () => count.set(0) };});
let app: ReturnType<typeof createRivet>;afterEach(() => app?.unmount());
test("counts up and can be reset", () => { document.body.innerHTML = ` <div data-rivet="counter" data-rivet-id="c1"> <output data-rivet-part="output">0</output> <button data-rivet-part="inc">+1</button> </div>`;
app = createRivet().component("counter", counter).mount();
const btn = document.querySelector<HTMLButtonElement>('[data-rivet-part="inc"]')!; btn.click(); btn.click();
expect(document.querySelector('[data-rivet-part="output"]')!.textContent).toBe("2");
app.require<{ reset(): void }>("c1").reset(); expect(document.querySelector('[data-rivet-part="output"]')!.textContent).toBe("0");});Testing signals in isolation
Section titled “Testing signals in isolation”The reactive system works without a DOM:
import { expect, test } from "bun:test";import { computed, effect, signal } from "@fullhaus/rivet";
test("computed updates", () => { const a = signal(1); const b = computed(() => a() * 2); expect(b()).toBe(2); a.set(5); expect(b()).toBe(10);});
test("effect runs on change", () => { const s = signal(0); const seen: number[] = []; const stop = effect(() => seen.push(s())); s.set(1); s.set(2); expect(seen).toEqual([0, 1, 2]); stop();});Testing the logger
Section titled “Testing the logger”memoryTransport() collects entries in memory — perfect for assertions.
import { expect, test } from "bun:test";import { createLogger, memoryTransport } from "@fullhaus/rivet/logger";
test("logs messages", () => { const mem = memoryTransport(); const log = createLogger({ transports: [mem.transport] });
log.info("hello");
expect(mem.entries[0].entry.message).toBe("hello"); expect(mem.entries[0].formatted).toMatch(/hello$/);});memoryTransport() returns entries (each { formatted, entry }) and a
clear() to reset between tests.