-
-
Notifications
You must be signed in to change notification settings - Fork 34
/
vitest.setup.ts
83 lines (78 loc) · 2.71 KB
/
vitest.setup.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
import type { NewPlugin } from "@vitest/pretty-format";
import { isHttpError } from "http-errors";
import { z } from "zod";
import { ResultHandlerError } from "./src/errors";
import { metaSymbol } from "./src/metadata";
/** Takes statusCode into account */
const compareHttpErrors = (a: unknown, b: unknown) => {
const hasCodeA = isHttpError(a);
const hasCodeB = isHttpError(b);
return hasCodeA && hasCodeB
? a.statusCode === b.statusCode && a.message === b.message
: hasCodeA === hasCodeB
? undefined
: false;
};
/** Takes cause and certain props of custom errors into account */
const errorSerializer: NewPlugin = {
test: (subject) => subject instanceof Error,
serialize: (error: Error, config, indentation, depth, refs, printer) => {
const { name, message, cause } = error;
const { handled } = error instanceof ResultHandlerError ? error : {};
const obj = Object.assign(
{ message },
cause && { cause },
handled && { handled },
);
return `${name}(${printer(obj, config, indentation, depth, refs)})`;
},
};
const makeSchemaSerializer = <
C extends z.ZodType,
T extends { new (...args: any[]): C }[],
>(
subject: T | T[number],
fn: (subject: C) => object,
): NewPlugin => {
const classes = Array.isArray(subject) ? subject : [subject];
return {
test: (subject) => classes.some((Cls) => subject instanceof Cls),
serialize: (subject, config, indentation, depth, refs, printer) => {
const obj = Object.assign(fn(subject as C), {
_type: subject._def.typeName,
});
return printer(obj, config, indentation, depth, refs);
},
};
};
/**
* @see https://vitest.dev/api/expect.html#expect-addequalitytesters
* @see https://jestjs.io/docs/expect#expectaddequalitytesterstesters
* */
expect.addEqualityTesters([compareHttpErrors]);
/**
* @see https://github.com/vitest-dev/vitest/issues/5697
* @see https://vitest.dev/guide/snapshot.html#custom-serializer
*/
const serializers = [
errorSerializer,
makeSchemaSerializer(z.ZodObject, ({ shape }) => ({ shape })),
makeSchemaSerializer(z.ZodLiteral, ({ value }) => ({ value })),
makeSchemaSerializer(z.ZodIntersection, ({ _def: { left, right } }) => ({
left,
right,
})),
makeSchemaSerializer(z.ZodUnion, ({ options }) => ({ options })),
makeSchemaSerializer(z.ZodEffects, ({ _def: { schema: value } }) => ({
value,
})),
makeSchemaSerializer(z.ZodOptional, (schema) => ({ value: schema.unwrap() })),
makeSchemaSerializer(z.ZodBranded, ({ _def }) => ({
brand: _def[metaSymbol]?.brand,
})),
makeSchemaSerializer(
[z.ZodNumber, z.ZodString, z.ZodBoolean, z.ZodNull],
() => ({}),
),
];
for (const serializer of serializers) expect.addSnapshotSerializer(serializer);