leistungsbilanz-ts/tests/support/zod-assertions.ts
Julian Appel a8cc7eca5e Tighten rejection tests to their expected errors
Every assert.throws now names the error it expects, so a broken fixture
or an unrelated failure can no longer satisfy a rejection test. Zod
rejections are matched by issue path and code via tests/support/zod-assertions.ts.

Restore snapshot coverage lost with the release baseline: invalid board
floor, room floor and circuit section references and a reserve state
that contradicts the device rows are rejected again under test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 12:27:46 +01:00

28 lines
1 KiB
TypeScript

import assert from "node:assert/strict";
import { ZodError } from "zod";
/** One expected Zod issue: dotted path ("" for the root), issue code and, for unrecognized keys, the key. */
export type ExpectedZodIssue = [path: string, code: string, key?: string];
/**
* Validation function for `assert.throws` that requires a ZodError reporting
* every expected issue. Any other error, such as a TypeError from a broken
* fixture, fails the assertion instead of passing as "some error".
*/
export function zodIssues(...expected: ExpectedZodIssue[]) {
return (error: unknown) => {
assert.ok(error instanceof ZodError, `expected ZodError, got ${String(error)}`);
for (const [path, code, key] of expected) {
assert.ok(
error.issues.some(
(issue) =>
issue.path.join(".") === path &&
issue.code === code &&
(key === undefined || ("keys" in issue && issue.keys.includes(key)))
),
`missing ${code}${key ? ` (${key})` : ""} at "${path}": ${error.message}`
);
}
return true;
};
}