@chamberu/test-kit
Test helpers for chamberu: a controllable clock and the store contract suite.
npm install --save-dev @chamberu/test-kit @chamberu/core vitest@chamberu/core and vitest are peer dependencies.
describeStoreContract
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.
// 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
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.
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); // truePass 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.