feat(core-testing): scaffold shared testing utilities package

Adds @repo/core-testing (tag: tooling) with:
- factory/defineFactory: monotonic-sequence object factories with overrides
- contract/defineContractSuite: shared test suites runnable against multiple impls
- react/renderWithProviders + createMockTrpcClient: RTL helpers
- payload/stubPayloadConfig + mockPayloadModule: Payload mocking helpers
- setup/{jsdom,node}: vitest setup files

Spec: docs/superpowers/specs/2026-05-05-tdd-foundation-design.md §5

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-05 13:37:35 +02:00
parent 1ab3a3274f
commit 4ca083690f
25 changed files with 946 additions and 10 deletions

View File

@@ -0,0 +1,27 @@
import { describe, it, expect } from "vitest";
import { defineContractSuite } from "@/contract/define-contract-suite";
interface Adder {
add(a: number, b: number): number;
}
const adderContract = defineContractSuite<Adder>("Adder", ({ buildSubject }) => {
it("adds two positive numbers", async () => {
const subject = await buildSubject();
expect(subject.add(2, 3)).toBe(5);
});
it("handles zero", async () => {
const subject = await buildSubject();
expect(subject.add(0, 0)).toBe(0);
});
});
class RealAdder implements Adder {
add(a: number, b: number) {
return a + b;
}
}
describe("RealAdder satisfies Adder contract", () => {
adderContract.run(() => new RealAdder());
});

View File

@@ -0,0 +1,22 @@
import { describe } from "vitest";
export interface ContractContext<T> {
buildSubject: () => Promise<T> | T;
}
export interface ContractSuite<T> {
run(buildSubject: () => Promise<T> | T): void;
}
export function defineContractSuite<T>(
name: string,
suite: (ctx: ContractContext<T>) => void,
): ContractSuite<T> {
return {
run(buildSubject) {
describe(`Contract: ${name}`, () => {
suite({ buildSubject });
});
},
};
}

View File

@@ -0,0 +1 @@
export { defineContractSuite, type ContractContext, type ContractSuite } from "./define-contract-suite.js";