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>
28 lines
1 KiB
TypeScript
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;
|
|
};
|
|
}
|