build revisions and layout updates for toast
This commit is contained in:
parent
b341a3675e
commit
39235193e6
1116 changed files with 130517 additions and 12 deletions
595
node_modules/zod/src/v4/classic/tests/error-utils.test.ts
generated
vendored
Normal file
595
node_modules/zod/src/v4/classic/tests/error-utils.test.ts
generated
vendored
Normal file
|
|
@ -0,0 +1,595 @@
|
|||
import { expect, expectTypeOf, test } from "vitest";
|
||||
import * as z from "zod/v4";
|
||||
|
||||
declare const iss: z.core.$ZodIssueCode;
|
||||
|
||||
const Test = z.object({
|
||||
f1: z.number(),
|
||||
f2: z.string().optional(),
|
||||
f3: z.string().nullable(),
|
||||
f4: z.array(z.object({ t: z.union([z.string(), z.boolean()]) })),
|
||||
});
|
||||
// type TestFlattenedErrors = core.inferFlattenedErrors<typeof Test, { message: string; code: number }>;
|
||||
// type TestFormErrors = core.inferFlattenedErrors<typeof Test>;
|
||||
const parsed = Test.safeParse({});
|
||||
|
||||
test("regular error", () => {
|
||||
expect(parsed).toMatchInlineSnapshot(`
|
||||
{
|
||||
"error": [ZodError: [
|
||||
{
|
||||
"expected": "number",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"f1"
|
||||
],
|
||||
"message": "Invalid input: expected number, received undefined"
|
||||
},
|
||||
{
|
||||
"expected": "string",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"f3"
|
||||
],
|
||||
"message": "Invalid input: expected string, received undefined"
|
||||
},
|
||||
{
|
||||
"expected": "array",
|
||||
"code": "invalid_type",
|
||||
"path": [
|
||||
"f4"
|
||||
],
|
||||
"message": "Invalid input: expected array, received undefined"
|
||||
}
|
||||
]],
|
||||
"success": false,
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(".flatten()", () => {
|
||||
const flattened = parsed.error!.flatten();
|
||||
// flattened.
|
||||
expectTypeOf(flattened).toMatchTypeOf<{
|
||||
formErrors: string[];
|
||||
fieldErrors: {
|
||||
f2?: string[];
|
||||
f1?: string[];
|
||||
f3?: string[];
|
||||
f4?: string[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(flattened).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"f1": [
|
||||
"Invalid input: expected number, received undefined",
|
||||
],
|
||||
"f3": [
|
||||
"Invalid input: expected string, received undefined",
|
||||
],
|
||||
"f4": [
|
||||
"Invalid input: expected array, received undefined",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("custom .flatten()", () => {
|
||||
type ErrorType = { message: string; code: number };
|
||||
const flattened = parsed.error!.flatten((iss) => ({ message: iss.message, code: 1234 }));
|
||||
expectTypeOf(flattened).toMatchTypeOf<{
|
||||
formErrors: ErrorType[];
|
||||
fieldErrors: {
|
||||
f2?: ErrorType[];
|
||||
f1?: ErrorType[];
|
||||
f3?: ErrorType[];
|
||||
f4?: ErrorType[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(flattened).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"f1": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected number, received undefined",
|
||||
},
|
||||
],
|
||||
"f3": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected string, received undefined",
|
||||
},
|
||||
],
|
||||
"f4": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected array, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test(".format()", () => {
|
||||
const formatted = parsed.error!.format();
|
||||
expectTypeOf(formatted).toMatchTypeOf<{
|
||||
_errors: string[];
|
||||
f2?: { _errors: string[] };
|
||||
f1?: { _errors: string[] };
|
||||
f3?: { _errors: string[] };
|
||||
f4?: {
|
||||
[x: number]: {
|
||||
_errors: string[];
|
||||
t?: {
|
||||
_errors: string[];
|
||||
};
|
||||
};
|
||||
_errors: string[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(formatted).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"f1": {
|
||||
"_errors": [
|
||||
"Invalid input: expected number, received undefined",
|
||||
],
|
||||
},
|
||||
"f3": {
|
||||
"_errors": [
|
||||
"Invalid input: expected string, received undefined",
|
||||
],
|
||||
},
|
||||
"f4": {
|
||||
"_errors": [
|
||||
"Invalid input: expected array, received undefined",
|
||||
],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("custom .format()", () => {
|
||||
type ErrorType = { message: string; code: number };
|
||||
const formatted = parsed.error!.format((iss) => ({ message: iss.message, code: 1234 }));
|
||||
expectTypeOf(formatted).toMatchTypeOf<{
|
||||
_errors: ErrorType[];
|
||||
f2?: { _errors: ErrorType[] };
|
||||
f1?: { _errors: ErrorType[] };
|
||||
f3?: { _errors: ErrorType[] };
|
||||
f4?: {
|
||||
[x: number]: {
|
||||
_errors: ErrorType[];
|
||||
t?: {
|
||||
_errors: ErrorType[];
|
||||
};
|
||||
};
|
||||
_errors: ErrorType[];
|
||||
};
|
||||
}>();
|
||||
|
||||
expect(formatted).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"f1": {
|
||||
"_errors": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected number, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
"f3": {
|
||||
"_errors": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected string, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
"f4": {
|
||||
"_errors": [
|
||||
{
|
||||
"code": 1234,
|
||||
"message": "Invalid input: expected array, received undefined",
|
||||
},
|
||||
],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("all errors", () => {
|
||||
const propertySchema = z.string();
|
||||
const schema = z
|
||||
.object({
|
||||
a: propertySchema,
|
||||
b: propertySchema,
|
||||
})
|
||||
.refine(
|
||||
(val) => {
|
||||
return val.a === val.b;
|
||||
},
|
||||
{ message: "Must be equal" }
|
||||
);
|
||||
|
||||
const r1 = schema.safeParse({
|
||||
a: "asdf",
|
||||
b: "qwer",
|
||||
});
|
||||
|
||||
expect(z.core.flattenError(r1.error!)).toEqual({
|
||||
formErrors: ["Must be equal"],
|
||||
fieldErrors: {},
|
||||
});
|
||||
|
||||
const r2 = schema.safeParse({
|
||||
a: null,
|
||||
b: null,
|
||||
});
|
||||
|
||||
// const error = _error as z.ZodError;
|
||||
expect(z.core.flattenError(r2.error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
"Invalid input: expected string, received null",
|
||||
],
|
||||
"b": [
|
||||
"Invalid input: expected string, received null",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
|
||||
expect(z.core.flattenError(r2.error!, (iss) => iss.message.toUpperCase())).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
"INVALID INPUT: EXPECTED STRING, RECEIVED NULL",
|
||||
],
|
||||
"b": [
|
||||
"INVALID INPUT: EXPECTED STRING, RECEIVED NULL",
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
// Test identity
|
||||
|
||||
expect(z.core.flattenError(r2.error!, (i: z.ZodIssue) => i)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received null",
|
||||
"path": [
|
||||
"a",
|
||||
],
|
||||
},
|
||||
],
|
||||
"b": [
|
||||
{
|
||||
"code": "invalid_type",
|
||||
"expected": "string",
|
||||
"message": "Invalid input: expected string, received null",
|
||||
"path": [
|
||||
"b",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
|
||||
// Test mapping
|
||||
const f1 = z.core.flattenError(r2.error!, (i: z.ZodIssue) => i.message.length);
|
||||
expect(f1).toMatchInlineSnapshot(`
|
||||
{
|
||||
"fieldErrors": {
|
||||
"a": [
|
||||
45,
|
||||
],
|
||||
"b": [
|
||||
45,
|
||||
],
|
||||
},
|
||||
"formErrors": [],
|
||||
}
|
||||
`);
|
||||
// expect(f1.fieldErrors.a![0]).toEqual("Invalid input: expected string".length);
|
||||
// expect(f1).toMatchObject({
|
||||
// formErrors: [],
|
||||
// fieldErrors: {
|
||||
// a: ["Invalid input: expected string".length],
|
||||
// b: ["Invalid input: expected string".length],
|
||||
// },
|
||||
// });
|
||||
});
|
||||
|
||||
const schema = z.strictObject({
|
||||
username: z.string().brand<"username">(),
|
||||
favoriteNumbers: z.array(z.number()),
|
||||
nesting: z.object({
|
||||
a: z.string(),
|
||||
}),
|
||||
});
|
||||
const result = schema.safeParse({
|
||||
username: 1234,
|
||||
favoriteNumbers: [1234, "4567"],
|
||||
nesting: {
|
||||
a: 123,
|
||||
},
|
||||
extra: 1234,
|
||||
});
|
||||
|
||||
const tree = z.treeifyError(result.error!);
|
||||
|
||||
expectTypeOf(tree).toEqualTypeOf<{
|
||||
errors: string[];
|
||||
properties?: {
|
||||
username?: {
|
||||
errors: string[];
|
||||
};
|
||||
favoriteNumbers?: {
|
||||
errors: string[];
|
||||
items?: {
|
||||
errors: string[];
|
||||
}[];
|
||||
};
|
||||
nesting?: {
|
||||
errors: string[];
|
||||
properties?: {
|
||||
a?: {
|
||||
errors: string[];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}>();
|
||||
|
||||
test("z.treeifyError", () => {
|
||||
expect(tree).toMatchInlineSnapshot(`
|
||||
{
|
||||
"errors": [
|
||||
"Unrecognized key: "extra"",
|
||||
],
|
||||
"properties": {
|
||||
"favoriteNumbers": {
|
||||
"errors": [],
|
||||
"items": [
|
||||
,
|
||||
{
|
||||
"errors": [
|
||||
"Invalid input: expected number, received string",
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"nesting": {
|
||||
"errors": [],
|
||||
"properties": {
|
||||
"a": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received number",
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
"username": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received number",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.treeifyError 2", () => {
|
||||
const schema = z.strictObject({
|
||||
name: z.string(),
|
||||
logLevel: z.union([z.string(), z.number()]),
|
||||
env: z.literal(["production", "development"]),
|
||||
});
|
||||
|
||||
const data = {
|
||||
name: 1000,
|
||||
logLevel: false,
|
||||
extra: 1000,
|
||||
};
|
||||
|
||||
const result = schema.safeParse(data);
|
||||
const err = z.treeifyError(result.error!);
|
||||
expect(err).toMatchInlineSnapshot(`
|
||||
{
|
||||
"errors": [
|
||||
"Unrecognized key: "extra"",
|
||||
],
|
||||
"properties": {
|
||||
"env": {
|
||||
"errors": [
|
||||
"Invalid option: expected one of "production"|"development"",
|
||||
],
|
||||
},
|
||||
"logLevel": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received boolean",
|
||||
"Invalid input: expected number, received boolean",
|
||||
],
|
||||
},
|
||||
"name": {
|
||||
"errors": [
|
||||
"Invalid input: expected string, received number",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.prettifyError", () => {
|
||||
expect(z.prettifyError(result.error!)).toMatchInlineSnapshot(`
|
||||
"✖ Unrecognized key: "extra"
|
||||
✖ Invalid input: expected string, received number
|
||||
→ at username
|
||||
✖ Invalid input: expected number, received string
|
||||
→ at favoriteNumbers[1]
|
||||
✖ Invalid input: expected string, received number
|
||||
→ at nesting.a"
|
||||
`);
|
||||
});
|
||||
|
||||
test("z.toDotPath", () => {
|
||||
expect(z.core.toDotPath(["a", "b", 0, "c"])).toMatchInlineSnapshot(`"a.b[0].c"`);
|
||||
|
||||
expect(z.core.toDotPath(["a", Symbol("b"), 0, "c"])).toMatchInlineSnapshot(`"a["Symbol(b)"][0].c"`);
|
||||
|
||||
// Test with periods in keys
|
||||
expect(z.core.toDotPath(["user.name", "first.last"])).toMatchInlineSnapshot(`"["user.name"]["first.last"]"`);
|
||||
|
||||
// Test with special characters
|
||||
expect(z.core.toDotPath(["user", "$special", Symbol("#symbol")])).toMatchInlineSnapshot(
|
||||
`"user.$special["Symbol(#symbol)"]"`
|
||||
);
|
||||
|
||||
// Test with dots and quotes
|
||||
expect(z.core.toDotPath(["search", `query("foo.bar"="abc")`])).toMatchInlineSnapshot(
|
||||
`"search["query(\\"foo.bar\\"=\\"abc\\")"]"`
|
||||
);
|
||||
|
||||
// Test with newlines
|
||||
expect(z.core.toDotPath(["search", `foo\nbar`])).toMatchInlineSnapshot(`"search["foo\\nbar"]"`);
|
||||
|
||||
// Test with empty strings
|
||||
expect(z.core.toDotPath(["", "empty"])).toMatchInlineSnapshot(`".empty"`);
|
||||
|
||||
// Test with array indices
|
||||
expect(z.core.toDotPath(["items", 0, 1, 2])).toMatchInlineSnapshot(`"items[0][1][2]"`);
|
||||
|
||||
// Test with mixed path elements
|
||||
expect(z.core.toDotPath(["users", "user.config", 0, "settings.theme"])).toMatchInlineSnapshot(
|
||||
`"users["user.config"][0]["settings.theme"]"`
|
||||
);
|
||||
|
||||
// Test with square brackets in keys
|
||||
expect(z.core.toDotPath(["data[0]", "value"])).toMatchInlineSnapshot(`"["data[0]"].value"`);
|
||||
|
||||
// Test with empty path
|
||||
expect(z.core.toDotPath([])).toMatchInlineSnapshot(`""`);
|
||||
});
|
||||
|
||||
test("inheritance", () => {
|
||||
const e1 = new z.ZodError([]);
|
||||
expect(e1).toBeInstanceOf(z.core.$ZodError);
|
||||
expect(e1).toBeInstanceOf(z.ZodError);
|
||||
// expect(e1).not.toBeInstanceOf(Error);
|
||||
|
||||
const e2 = new z.ZodRealError([]);
|
||||
expect(e2).toBeInstanceOf(z.ZodError);
|
||||
expect(e2).toBeInstanceOf(z.ZodRealError);
|
||||
expect(e2).toBeInstanceOf(Error);
|
||||
});
|
||||
|
||||
test("disc union treeify/format", () => {
|
||||
const schema = z.discriminatedUnion(
|
||||
"foo",
|
||||
[
|
||||
z.object({
|
||||
foo: z.literal("x"),
|
||||
x: z.string(),
|
||||
}),
|
||||
z.object({
|
||||
foo: z.literal("y"),
|
||||
y: z.string(),
|
||||
}),
|
||||
],
|
||||
{
|
||||
error: "Invalid discriminator",
|
||||
}
|
||||
);
|
||||
|
||||
const error = schema.safeParse({ foo: "invalid" }).error;
|
||||
expect(z.treeifyError(error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"errors": [],
|
||||
"properties": {
|
||||
"foo": {
|
||||
"errors": [
|
||||
"Invalid discriminator",
|
||||
],
|
||||
},
|
||||
},
|
||||
}
|
||||
`);
|
||||
expect(z.prettifyError(error!)).toMatchInlineSnapshot(`
|
||||
"✖ Invalid discriminator
|
||||
→ at foo"
|
||||
`);
|
||||
expect(z.formatError(error!)).toMatchInlineSnapshot(`
|
||||
{
|
||||
"_errors": [],
|
||||
"foo": {
|
||||
"_errors": [
|
||||
"Invalid discriminator",
|
||||
],
|
||||
},
|
||||
}
|
||||
`);
|
||||
});
|
||||
|
||||
test("update message after adding issues", () => {
|
||||
const e = new z.ZodError([]);
|
||||
e.addIssue({
|
||||
code: "custom",
|
||||
message: "message",
|
||||
input: "asdf",
|
||||
path: [],
|
||||
});
|
||||
expect(e.message).toMatchInlineSnapshot(`
|
||||
"[
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "message",
|
||||
"input": "asdf",
|
||||
"path": []
|
||||
}
|
||||
]"
|
||||
`);
|
||||
|
||||
e.addIssue({
|
||||
code: "custom",
|
||||
message: "message",
|
||||
input: "asdf",
|
||||
path: [],
|
||||
});
|
||||
expect(e.message).toMatchInlineSnapshot(`
|
||||
"[
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "message",
|
||||
"input": "asdf",
|
||||
"path": []
|
||||
},
|
||||
{
|
||||
"code": "custom",
|
||||
"message": "message",
|
||||
"input": "asdf",
|
||||
"path": []
|
||||
}
|
||||
]"
|
||||
`);
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue