Testing
Apps run in any test environment with a DOM, such as jsdom. This guide uses Vitest and DOM Testing Library.
Set up#
$ pnpm add -D vitest jsdom @testing-library/dom
Set the test environment in vite.config.js:
export default defineConfig({ // ... test: { environment: "jsdom", }, });
Test the app#
Import the app with ?cursery:store-path and mount it:
import { fireEvent, screen } from "@testing-library/dom"; import { mount, unmount } from "cursery"; import { expect, test } from "vitest"; // The path of the app's `default.nix`, loaded but not mounted. import app from "./app?cursery:store-path"; test("counts clicks", () => { mount(document.body, app); // The app re-renders before `fireEvent` returns. fireEvent.click(screen.getByRole("button", { name: "Increment" })); expect(screen.getByRole("heading").textContent).toBe("Clicked 1 times"); unmount(document.body); });
Test Nix files#
Import the app's files with ?cursery:files, and load them. evaluate can then call any file by its path, with inputs:
count: noun: if count == 1 then "1 ${noun}" else "${toString count} ${noun}s"
import { evaluate, load } from "cursery"; import { expect, test } from "vitest"; import files from "./app?cursery:files"; const app = load(files); test("pluralizes", () => { expect(evaluate(`import ${app}/plural.nix 1 "click"`)).toBe("1 click"); expect(evaluate(`import ${app}/plural.nix 2 "click"`)).toBe("2 clicks"); });
Other test runners#
Import cursery/testing/setup before the tests. It polyfills missing jsdom features.
?cursery:store-path and ?cursery:files imports need the Vite plugin. Without it, load the app's files with load, as in Pre-rendering.