Files
agentic-dev/packages/core-shared/src/conformance/define-feature.test.ts
Danijel Martinek c62de6fce9 feat(core-shared): add rate-limit type primitives and manifest field
Adds IRateLimit, RateLimitBudget, RateLimitDecision to a new
rate-limit sub-module; adds RateLimited<F> brand and isRateLimited
predicate following the Captured/ConsentChecked pattern; extends
UseCaseManifest with rateLimit?: readonly RateLimitBudget[] so
features can declare rate-limit gates in their manifests.

Exports new types from @repo/core-shared/rate-limit and
@repo/core-shared/conformance. Blocks stories 02, 03, and 04.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-20 08:21:42 +00:00

307 lines
8.3 KiB
TypeScript

import { describe, it, expect, expectTypeOf } from "vitest";
import {
defineFeature,
type FeatureManifest,
type UseCaseManifest,
} from "@/conformance/define-feature";
import type { RateLimitBudget } from "@/rate-limit/rate-limit.interface";
import {
DEFAULT_COVERAGE_BANDS,
DEFAULT_MUTATION_SCORE,
DEFAULT_MUTATION_TARGETS,
getCoverageBands,
getMutationConfig,
vitestThresholdsFromBands,
vitestThresholdsFromManifest,
type CoverageBand,
} from "@/conformance/coverage";
describe("defineFeature", () => {
it("preserves literal types of a manifest declared with `as const`", () => {
const manifest = defineFeature({
name: "auth",
requiredCores: ["audit"],
useCases: {
signIn: {
mutates: false,
audits: [],
publishes: [],
consumes: [],
},
signUp: {
mutates: true,
audits: ["user.created"],
publishes: ["auth.signed-up"],
consumes: [],
},
},
realtimeChannels: [],
jobs: [],
} as const);
// Literal preservation: name is the literal "auth", not string
expectTypeOf(manifest.name).toEqualTypeOf<"auth">();
// Use-case keys preserved
expectTypeOf(manifest.useCases.signUp.audits).toEqualTypeOf<
readonly ["user.created"]
>();
expectTypeOf(manifest.useCases.signUp.mutates).toEqualTypeOf<true>();
expectTypeOf(manifest.useCases.signIn.mutates).toEqualTypeOf<false>();
});
it("FeatureManifest type accepts the shape", () => {
const manifest = defineFeature({
name: "blog",
requiredCores: [],
useCases: {},
realtimeChannels: [],
jobs: [],
} as const);
expectTypeOf(manifest).toMatchTypeOf<FeatureManifest>();
});
it("accepts an optional rateLimit array on a use case", () => {
const manifest = defineFeature({
name: "auth",
requiredCores: [],
useCases: {
signIn: {
mutates: false,
audits: [],
publishes: [],
consumes: [],
rateLimit: [{ name: "login", window: "1m", budget: 5 }],
},
},
realtimeChannels: [],
jobs: [],
} as const);
expectTypeOf(manifest).toMatchTypeOf<FeatureManifest>();
expectTypeOf(manifest.useCases.signIn.rateLimit).toMatchTypeOf<
readonly RateLimitBudget[] | undefined
>();
});
it("use case without rateLimit satisfies UseCaseManifest", () => {
const uc: UseCaseManifest = {
mutates: false,
audits: [],
publishes: [],
consumes: [],
};
expectTypeOf(uc.rateLimit).toEqualTypeOf<
readonly RateLimitBudget[] | undefined
>();
});
it("accepts an optional coverage section", () => {
const manifest = defineFeature({
name: "auth",
requiredCores: [],
useCases: {},
realtimeChannels: [],
jobs: [],
coverage: {
bands: {
baseline: { statements: 80, branches: 75, functions: 80, lines: 80 },
entities: {
statements: 100,
branches: 100,
functions: 100,
lines: 100,
},
},
mutationTargets: ["entities"],
mutationScore: 85,
},
} as const);
expectTypeOf(manifest.coverage).toMatchTypeOf<
| undefined
| {
readonly bands: {
readonly baseline: CoverageBand;
readonly entities?: CoverageBand;
readonly "use-cases"?: CoverageBand;
readonly controllers?: CoverageBand;
};
}
>();
expect(manifest.coverage?.mutationScore).toBe(85);
});
});
describe("getCoverageBands", () => {
const blankManifest: FeatureManifest = {
name: "test",
requiredCores: [],
useCases: {},
realtimeChannels: [],
jobs: [],
};
it("returns DEFAULT_COVERAGE_BANDS when manifest has no coverage section", () => {
expect(getCoverageBands(blankManifest)).toEqual(DEFAULT_COVERAGE_BANDS);
});
it("returns DEFAULT_COVERAGE_BANDS when coverage section is undefined", () => {
expect(getCoverageBands({ ...blankManifest, coverage: undefined })).toEqual(
DEFAULT_COVERAGE_BANDS,
);
});
it("uses declared baseline + fills missing layers from defaults", () => {
const result = getCoverageBands({
...blankManifest,
coverage: {
bands: {
baseline: { statements: 90, branches: 85, functions: 90, lines: 90 },
},
},
});
expect(result.baseline).toEqual({
statements: 90,
branches: 85,
functions: 90,
lines: 90,
});
expect(result.entities).toEqual(DEFAULT_COVERAGE_BANDS.entities);
expect(result["use-cases"]).toEqual(DEFAULT_COVERAGE_BANDS["use-cases"]);
expect(result.controllers).toEqual(DEFAULT_COVERAGE_BANDS.controllers);
});
it("uses declared layer bands when present", () => {
const customEntities: CoverageBand = {
statements: 95,
branches: 90,
functions: 95,
lines: 95,
};
const result = getCoverageBands({
...blankManifest,
coverage: {
bands: {
baseline: DEFAULT_COVERAGE_BANDS.baseline,
entities: customEntities,
},
},
});
expect(result.entities).toEqual(customEntities);
});
});
describe("getMutationConfig", () => {
const blankManifest: FeatureManifest = {
name: "test",
requiredCores: [],
useCases: {},
realtimeChannels: [],
jobs: [],
};
it("returns defaults when manifest has no coverage section", () => {
const config = getMutationConfig(blankManifest);
expect(config.targets).toEqual(DEFAULT_MUTATION_TARGETS);
expect(config.score).toBe(DEFAULT_MUTATION_SCORE);
});
it("honors declared mutationTargets + mutationScore", () => {
const config = getMutationConfig({
...blankManifest,
coverage: {
bands: { baseline: DEFAULT_COVERAGE_BANDS.baseline },
mutationTargets: ["entities"],
mutationScore: 90,
},
});
expect(config.targets).toEqual(["entities"]);
expect(config.score).toBe(90);
});
});
describe("DEFAULT_COVERAGE_BANDS", () => {
it("matches the ADR-011 / ADR-020 documented bands", () => {
expect(DEFAULT_COVERAGE_BANDS.baseline).toEqual({
statements: 80,
branches: 75,
functions: 80,
lines: 80,
});
expect(DEFAULT_COVERAGE_BANDS.entities).toEqual({
statements: 100,
branches: 100,
functions: 100,
lines: 100,
});
expect(DEFAULT_COVERAGE_BANDS["use-cases"]).toEqual({
statements: 100,
branches: 95,
functions: 100,
lines: 100,
});
expect(DEFAULT_COVERAGE_BANDS.controllers).toEqual({
statements: 100,
branches: 95,
functions: 100,
lines: 100,
});
});
});
describe("vitestThresholdsFromBands", () => {
it("emits baseline at the top level and each declared layer under its glob", () => {
const result = vitestThresholdsFromBands(DEFAULT_COVERAGE_BANDS);
expect(result.statements).toBe(80);
expect(result.branches).toBe(75);
expect(result["src/entities/**"]).toEqual({
statements: 100,
branches: 100,
functions: 100,
lines: 100,
});
expect(result["src/application/use-cases/**"]).toEqual({
statements: 100,
branches: 95,
functions: 100,
lines: 100,
});
expect(result["src/interface-adapters/controllers/**"]).toEqual({
statements: 100,
branches: 95,
functions: 100,
lines: 100,
});
});
it("omits layer glob when its band is undefined", () => {
const result = vitestThresholdsFromBands({
baseline: DEFAULT_COVERAGE_BANDS.baseline,
entities: DEFAULT_COVERAGE_BANDS.entities,
});
expect(result["src/entities/**"]).toBeDefined();
expect(result["src/application/use-cases/**"]).toBeUndefined();
expect(result["src/interface-adapters/controllers/**"]).toBeUndefined();
});
});
describe("vitestThresholdsFromManifest", () => {
it("uses DEFAULT_COVERAGE_BANDS when the manifest omits coverage", () => {
const manifest: FeatureManifest = {
name: "test",
requiredCores: [],
useCases: {},
realtimeChannels: [],
jobs: [],
};
const result = vitestThresholdsFromManifest(manifest);
expect(result.statements).toBe(80);
expect(result["src/entities/**"]).toEqual({
statements: 100,
branches: 100,
functions: 100,
lines: 100,
});
});
});