diff --git a/packages/route/test/route-validation.test.ts b/packages/route/test/route-validation.test.ts index fcbbae1..5142c61 100644 --- a/packages/route/test/route-validation.test.ts +++ b/packages/route/test/route-validation.test.ts @@ -2,103 +2,106 @@ import { expect, test } from "vitest"; import z from "zod"; import { dredgeRoute } from "../source/route"; import { useValidate } from "../source/route-invocation"; +import { describe } from "node:test"; -test("simple validation", async () => { - const route = dredgeRoute() - .path("/a/:string/:number/:boolean") - .params({ - string: z.string(), - number: z.number(), - boolean: z.boolean(), - }) - .queries({ - sstring: z.string(), - snumber: z.number(), - sboolean: z.boolean(), - }) - .post() - .input(z.enum(["a", "b", "c"])); +describe("useValidate", () => { + test("resolves", async () => { + const route = dredgeRoute() + .path("/a/:string/:number/:boolean") + .params({ + string: z.string(), + number: z.number(), + boolean: z.boolean(), + }) + .queries({ + sstring: z.string(), + snumber: z.number(), + sboolean: z.boolean(), + }) + .post() + .input(z.enum(["a", "b", "c"])); - const validated = await useValidate(route)({ - method: "POST", - url: "", - queries: { - sstring: ["world"], - snumber: [2], - sboolean: [false], - }, - data: "a", - params: { + const validated = await useValidate(route)({ + method: "POST", + url: "", + queries: { + sstring: ["world"], + snumber: [2], + sboolean: [false], + }, + data: "a", + params: { + string: "hello", + number: 1, + boolean: true, + }, + headers: {}, + }); + + expect(validated.params).toStrictEqual({ string: "hello", number: 1, boolean: true, - }, - headers: {}, - }); + }); - expect(validated.params).toStrictEqual({ - string: "hello", - number: 1, - boolean: true, + expect(validated.queries).toStrictEqual({ + sstring: ["world"], + snumber: [2], + sboolean: [false], + }); }); - expect(validated.queries).toStrictEqual({ - sstring: ["world"], - snumber: [2], - sboolean: [false], + test("resolves given the optional searchParam", async () => { + const route = dredgeRoute() + .path("/test") + .queries({ + required: z.string(), + optional: z.string().optional(), + }) + .get(); + + expect( + useValidate(route)({ + method: "GET", + url: "/test?required=i am required", + queries: { + required: ["i am required"], + }, + params: {}, + headers: {}, + }), + ).resolves.toMatchObject({ + queries: { + required: ["i am required"], + }, + }); }); -}); -test("optional searchParam should work", async () => { - const route = dredgeRoute() - .path("/test") - .queries({ - required: z.string(), - optional: z.string().optional(), - }) - .get(); + test("returns along with unspecified query in schema", async () => { + const route = dredgeRoute() + .path("/test") + .queries({ + i: z.number(), + o: z.string().optional(), + }) + .get(); - expect( - useValidate(route)({ + const validated = await useValidate(route)({ method: "GET", - url: "/test?required=i am required", + url: "/test", queries: { - required: ["i am required"], + i: [1], + a: ["apple"], + b: ["ball"], }, params: {}, headers: {}, - }), - ).resolves.toMatchObject({ - queries: { - required: ["i am required"], - }, - }); -}); - -test("unSpecified searchParam should work", async () => { - const route = dredgeRoute() - .path("/test") - .queries({ - i: z.number(), - o: z.string().optional(), - }) - .get(); + }); - const validated = await useValidate(route)({ - method: "GET", - url: "/test", - queries: { + expect(validated.queries).toStrictEqual({ i: [1], a: ["apple"], b: ["ball"], - }, - params: {}, - headers: {}, - }); - - expect(validated.queries).toStrictEqual({ - i: [1], - a: ["apple"], - b: ["ball"], + }); }); }); diff --git a/packages/types/test/route.test-d.ts b/packages/types/test/route.test-d.ts index 7ba58df..bc22dc2 100644 --- a/packages/types/test/route.test-d.ts +++ b/packages/types/test/route.test-d.ts @@ -43,8 +43,8 @@ describe("route.options()", () => { }); }); -describe("req", () => { - test("data should be any, if middleware is defined before defining the method", () => { +describe("req.data", () => { + test("infers `any` when middleware is defined before defining method", () => { dredgeRoute() .path("/test") .use((req) => { @@ -52,7 +52,7 @@ describe("req", () => { }); }); - test("req.data for get, delete and head should be undefined", () => { + test("infers `undefined` when method is get, delete or head", () => { dredgeRoute() .path("/test") .get() @@ -84,7 +84,7 @@ describe("req", () => { }); }); - test("req.data should always be any in error for method which takes data", () => { + test("infers `any` for error middleware", () => { dredgeRoute() .path("/test") .error((_err, req) => { @@ -119,7 +119,7 @@ describe("req", () => { }); }); - test("req.data for post, put and patch should be any, if parser is not given", () => { + test("infers `any` when parser is not provided and method is post, put or patch", () => { dredgeRoute() .path("/test") .post() @@ -145,7 +145,7 @@ describe("req", () => { }); }); - test("req.data should have correct type", () => { + test("infers the type provided to input for usual middleware", () => { dredgeRoute() .path("/test") .post() @@ -173,7 +173,9 @@ describe("req", () => { expectTypeOf(req.data).toBeNull(); }); }); +}); +describe("req", () => { test("req.param()", () => { dredgeRoute() .path("/test/:paramI/a/:paramII") @@ -340,16 +342,23 @@ describe("req", () => { }); describe("res", () => { - test("res.header", () => { + test("res.header() returns `Record` when given no argument", () => { dredgeRoute() .use((_req, res) => { expectTypeOf(res.header()).toEqualTypeOf>(); + }) + .error((_err, _req, res) => { + expectTypeOf(res.header()).toEqualTypeOf>(); + }); + }); + test("res.header() returns `string | undefined` when given a string argument", () => { + dredgeRoute() + .use((_req, res) => { expectTypeOf(res.header("content-type")).toEqualTypeOf< string | undefined >(); }) .error((_err, _req, res) => { - expectTypeOf(res.header()).toEqualTypeOf>(); expectTypeOf(res.header("content-type")).toEqualTypeOf< string | undefined >(); @@ -638,7 +647,7 @@ describe("res", () => { expectTypeOf().toBeNever(); }); - test("res.end and responseData", () => { + test("responseData infers the type provided to res.end() when output has not been called", () => { const route = dredgeRoute() .path("/test") .get() @@ -652,7 +661,7 @@ describe("res", () => { expectTypeOf().toEqualTypeOf<"this is string">(); }); - test("route.output and responseData", () => { + test("responseData infers the type provided to route.output()", () => { const route = dredgeRoute() .path("/test") .get() @@ -667,7 +676,7 @@ describe("res", () => { expectTypeOf().toEqualTypeOf<"a" | "b" | "c">(); }); - test("res.data should always be `any`", () => { + test("res.data infers `any`", () => { dredgeRoute() .path("/test") .get() @@ -707,16 +716,26 @@ describe("res", () => { }); }); - test("res.status and res.statusText", () => { + test("res.status infers `number | undefined`", () => { dredgeRoute() .path("/test") .get() .use((_req, res) => { expectTypeOf(res.status).toEqualTypeOf(); - expectTypeOf(res.statusText).toEqualTypeOf(); }) .error((_err, _req, res) => { expectTypeOf(res.status).toEqualTypeOf(); + }); + }); + + test("res.statusText infers `string | undefined`", () => { + dredgeRoute() + .path("/test") + .get() + .use((_req, res) => { + expectTypeOf(res.statusText).toEqualTypeOf(); + }) + .error((_err, _req, res) => { expectTypeOf(res.statusText).toEqualTypeOf(); }); });