Skip to content

Commit

Permalink
Add custom tests
Browse files Browse the repository at this point in the history
  • Loading branch information
colinhacks committed Feb 28, 2023
1 parent edc3a67 commit e59f639
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 27 deletions.
11 changes: 11 additions & 0 deletions deno/lib/__tests__/custom.test.ts
@@ -0,0 +1,11 @@
// @ts-ignore TS6133
import { expect } from "https://deno.land/x/expect@v0.2.6/mod.ts";
const test = Deno.test;

import * as z from "../index.ts";

test("passing validations", () => {
const example1 = z.custom<number>((x) => typeof x === "number");
example1.parse(1234);
expect(() => example1.parse({})).toThrow();
});
24 changes: 14 additions & 10 deletions deno/lib/types.ts
Expand Up @@ -3722,7 +3722,7 @@ export class ZodFunction<
return this._def.returns;
}

args<Items extends Parameters<typeof ZodTuple["create"]>[0]>(
args<Items extends Parameters<(typeof ZodTuple)["create"]>[0]>(
...items: Items
): ZodFunction<ZodTuple<Items, ZodUnknown>, Returns> {
return new ZodFunction({
Expand Down Expand Up @@ -4709,17 +4709,21 @@ export class ZodPipeline<
}
}

type CustomParams = CustomErrorParams & { fatal?: boolean };
export const custom = <T>(
check?: (data: unknown) => any,
params: Parameters<ZodTypeAny["refine"]>[1] = {},
params: CustomParams | ((input: any) => CustomParams) = {},
/* @deprecated */
fatal?: boolean
): ZodType<T> => {
if (check)
return ZodAny.create().superRefine((data, ctx) => {
if (!check(data)) {
const p = typeof params === "function" ? params(data) : params;
const _fatal = p.fatal ?? fatal ?? true;
const p2 = typeof p === "string" ? { message: p } : p;
ctx.addIssue({ code: "custom", ...p2, fatal });
console.log(`adding issue`);
ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
}
});
return ZodAny.create();
Expand Down Expand Up @@ -4812,10 +4816,10 @@ abstract class Class {
const instanceOfType = <T extends typeof Class>(
// const instanceOfType = <T extends new (...args: any[]) => any>(
cls: T,
params: Parameters<ZodTypeAny["refine"]>[1] = {
params: CustomParams = {
message: `Input not instance of ${cls.name}`,
}
) => custom<InstanceType<T>>((data) => data instanceof cls, params, true);
) => custom<InstanceType<T>>((data) => data instanceof cls, params);

const stringType = ZodString.create;
const numberType = ZodNumber.create;
Expand Down Expand Up @@ -4857,18 +4861,18 @@ const oboolean = () => booleanType().optional();

export const coerce = {
string: ((arg) =>
ZodString.create({ ...arg, coerce: true })) as typeof ZodString["create"],
ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"],
number: ((arg) =>
ZodNumber.create({ ...arg, coerce: true })) as typeof ZodNumber["create"],
ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"],
boolean: ((arg) =>
ZodBoolean.create({
...arg,
coerce: true,
})) as typeof ZodBoolean["create"],
})) as (typeof ZodBoolean)["create"],
bigint: ((arg) =>
ZodBigInt.create({ ...arg, coerce: true })) as typeof ZodBigInt["create"],
ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"],
date: ((arg) =>
ZodDate.create({ ...arg, coerce: true })) as typeof ZodDate["create"],
ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"],
};

export {
Expand Down
33 changes: 26 additions & 7 deletions playground.ts
@@ -1,9 +1,28 @@
import { z } from "./src";
const example1 = z.custom<number>((x) => typeof x === "number");
example1.parse("asdf");
// const example1 = z
// .custom<number>(
// (x) => {
// console.log(`custom`);
// console.log(x);
// return typeof x === "number";
// },
// {},
// true
// )
// .transform((x) => {
// console.log(`transform`);
// console.log(x);
// return String(x);
// })
// .refine((x) => {
// console.log(`refine`);
// console.log(x);
// console.log(typeof x); // prints 'Object'
// console.log("I get called even though I shouldn't!!!");
// return true;
// })
// .safeParse({}); //will fail because it is not a number

// benchmark
// run 10000 times
console.time("bench");
for (let i = 0; i < 10000; i++) {
z.string().catch("asdf").parse(5);
}
console.timeEnd("bench");
// console.log(example1.success); // false (like it should be)
10 changes: 10 additions & 0 deletions src/__tests__/custom.test.ts
@@ -0,0 +1,10 @@
// @ts-ignore TS6133
import { expect, test } from "@jest/globals";

import * as z from "../index";

test("passing validations", () => {
const example1 = z.custom<number>((x) => typeof x === "number");
example1.parse(1234);
expect(() => example1.parse({})).toThrow();
});
24 changes: 14 additions & 10 deletions src/types.ts
Expand Up @@ -3722,7 +3722,7 @@ export class ZodFunction<
return this._def.returns;
}

args<Items extends Parameters<typeof ZodTuple["create"]>[0]>(
args<Items extends Parameters<(typeof ZodTuple)["create"]>[0]>(
...items: Items
): ZodFunction<ZodTuple<Items, ZodUnknown>, Returns> {
return new ZodFunction({
Expand Down Expand Up @@ -4709,17 +4709,21 @@ export class ZodPipeline<
}
}

type CustomParams = CustomErrorParams & { fatal?: boolean };
export const custom = <T>(
check?: (data: unknown) => any,
params: Parameters<ZodTypeAny["refine"]>[1] = {},
params: CustomParams | ((input: any) => CustomParams) = {},
/* @deprecated */
fatal?: boolean
): ZodType<T> => {
if (check)
return ZodAny.create().superRefine((data, ctx) => {
if (!check(data)) {
const p = typeof params === "function" ? params(data) : params;
const _fatal = p.fatal ?? fatal ?? true;
const p2 = typeof p === "string" ? { message: p } : p;
ctx.addIssue({ code: "custom", ...p2, fatal });
console.log(`adding issue`);
ctx.addIssue({ code: "custom", ...p2, fatal: _fatal });
}
});
return ZodAny.create();
Expand Down Expand Up @@ -4812,10 +4816,10 @@ abstract class Class {
const instanceOfType = <T extends typeof Class>(
// const instanceOfType = <T extends new (...args: any[]) => any>(
cls: T,
params: Parameters<ZodTypeAny["refine"]>[1] = {
params: CustomParams = {
message: `Input not instance of ${cls.name}`,
}
) => custom<InstanceType<T>>((data) => data instanceof cls, params, true);
) => custom<InstanceType<T>>((data) => data instanceof cls, params);

const stringType = ZodString.create;
const numberType = ZodNumber.create;
Expand Down Expand Up @@ -4857,18 +4861,18 @@ const oboolean = () => booleanType().optional();

export const coerce = {
string: ((arg) =>
ZodString.create({ ...arg, coerce: true })) as typeof ZodString["create"],
ZodString.create({ ...arg, coerce: true })) as (typeof ZodString)["create"],
number: ((arg) =>
ZodNumber.create({ ...arg, coerce: true })) as typeof ZodNumber["create"],
ZodNumber.create({ ...arg, coerce: true })) as (typeof ZodNumber)["create"],
boolean: ((arg) =>
ZodBoolean.create({
...arg,
coerce: true,
})) as typeof ZodBoolean["create"],
})) as (typeof ZodBoolean)["create"],
bigint: ((arg) =>
ZodBigInt.create({ ...arg, coerce: true })) as typeof ZodBigInt["create"],
ZodBigInt.create({ ...arg, coerce: true })) as (typeof ZodBigInt)["create"],
date: ((arg) =>
ZodDate.create({ ...arg, coerce: true })) as typeof ZodDate["create"],
ZodDate.create({ ...arg, coerce: true })) as (typeof ZodDate)["create"],
};

export {
Expand Down

0 comments on commit e59f639

Please sign in to comment.