Testing

Snapshot-test markup and CSS, run the engine in unit tests, and test components with the runtime.

1 min readv1

Deterministic snapshots#

Class names are hashes of their rules, so snapshots are stable across machines and runs. A snapshot only changes when a style actually changes.

Unit-test styles with the engine#

TypeScript
import { createEngine } from "@nibcss/core";
import config from "../nibcss.config";
import { describe, expect, it } from "vitest";

describe("button recipe", () => {
  const engine = createEngine({ ...config, preflight: false });

  it("has no warnings", () => {
    expect(engine.process("btn-primary").warnings).toEqual([]);
  });

  it("compiles to the expected CSS", () => {
    engine.process("btn-primary");
    expect(engine.css()).toMatchSnapshot();
  });
});

Lint every recipe in CI#

A cheap safety net — fail the build if any recipe produces a warning:

TypeScript
import { createEngine } from "@nibcss/core";
import config from "../nibcss.config";

const engine = createEngine({ ...config, preflight: false });
const problems = Object.keys(config.components ?? {}).flatMap((name) =>
  engine.process(name).warnings.map((w) => `${name}: ${w}`),
);
if (problems.length) {
  console.error(problems.join("\n"));
  process.exit(1);
}

Component tests with jsdom#

Start a runtime against the test document to get real class names on rendered elements:

TypeScript
import { init } from "@nibcss/runtime";

const rt = init({ ...config, gc: false });
render(<Button />);
rt.scan();
expect(screen.getByRole("button").className).toMatch(/nib-/);

Next steps#