Skip to content

@chamberu/test-kit ​

Test helpers for chamberu: a controllable clock and the store contract suite.

bash
npm install --save-dev @chamberu/test-kit @chamberu/core vitest

@chamberu/core and vitest are peer dependencies.

describeStoreContract ​

ts
function describeStoreContract(
    create: (clock: ControllableClock) => IStore | Promise<IStore>,
): void;

Registers the Vitest suite every IStore implementation must pass. create is called once per test with a fresh ControllableClock and must return a fresh, empty store that uses that clock for every expiry decision.

ts
// test/unit/store.spec.ts
import { MemoryStore } from '@chamberu/core';
import { describeStoreContract } from '@chamberu/test-kit';

describeStoreContract((clock) => new MemoryStore({ clock }));

See Writing a Store for what the suite covers.

ControllableClock ​

ts
class ControllableClock implements IClock {
    constructor(start?: Date); // default new Date(0)
    now(): Date;
    setTimeout(fn: () => void, ms: number): { clear(): void };
    advance(ms: number): void;
}

Time moves only through advance(ms), which fires every timer due within the window in order, including timers scheduled by fired callbacks. The keepAlive timer option has no meaning without a real event loop and is ignored.

ts
const clock = new ControllableClock(new Date('2026-01-01T00:00:00Z'));
const store = new MemoryStore({ clock });

await store.acquire('job', 'replica-a', 1_000); // true
await store.acquire('job', 'replica-b', 1_000); // false, held by replica-a

clock.advance(1_000); // a lease expires at exactly T + ttlMs
await store.acquire('job', 'replica-b', 1_000); // true

Pass the same clock to the store and to the engine (new RunEngine({ ..., clock })) to test claim leases, run timeouts and approval expiry without real timers.