Client Unit Testing
Unit-test the plain TypeScript in your client plane — helpers, validation, and registration logic — without a browser.
Client unit tests cover pure TypeScript logic — validation functions, formatters, utility modules, etc. They run in a happy-dom environment with mocked RED and $ globals, but without rendering Vue components.
Setup
1. Install dependencies
bash
pnpm add -D vitest happy-domhappy-dom provides the DOM environment the client unit config runs in (environment: "happy-dom").
2. Create a tsconfig
json
// tests/client/unit/tsconfig.json
{
"extends": "@bonsae/nrg/tsconfig/test/client/unit.json",
"include": ["**/*.ts", "../../../src/client/**/*.ts"]
}3. Create a vitest config
typescript
// vitest.client.unit.config.ts
import { defineConfig, mergeConfig } from "vitest/config";
import { nrg } from "@bonsae/nrg/test/client/unit/config";
export default mergeConfig(
nrg,
defineConfig({
test: {
include: ["tests/client/unit/**/*.test.ts"],
},
}),
);The nrg config provides:
testTimeout: 30_000environment: "happy-dom"forwindow,document, and other browser globalssetupFilespointing to the built-in setup that installsREDand$mocks onwindow@alias pointing tosrc/in your project root@bonsae/nrg/clientalias resolved to the test library (souseFormNodeimports work without a runtime bundle)- a default
includeoftests/client/unit/**/*.test.ts
4. Add a test script
json
{
"scripts": {
"test:client:unit": "vitest run --config vitest.client.unit.config.ts"
}
}Quick Start
typescript
import { describe, it, expect } from "vitest";
import { validateNode } from "../../../src/client/validation";
describe("validateNode", () => {
it("returns true for valid config", () => {
const schema = {
type: "object",
properties: {
name: { type: "string", minLength: 1 },
},
required: ["name"],
};
const subject = { type: "my-node", name: "test" };
expect(validateNode(subject, schema)).toBe(true);
});
it("returns errors for missing required field", () => {
const schema = {
type: "object",
properties: {
name: { type: "string", minLength: 1 },
},
required: ["name"],
};
const subject = { type: "my-node", name: "" };
const result = validateNode(subject, schema);
expect(result).not.toBe(true);
expect((result as string[])[0]).toContain(
"must NOT have fewer than 1 characters",
);
});
});