Module
x/value_schema/test/index.test.ts
simple, easy-to-use, and declarative input validator; supports Node.js, TypeScript, and Deno
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368import vs from "value-schema";
{ describe("applySchemaObject", testApplySchemaObject); describe("error", testError);}
/** * test applySchemaObject() */function testApplySchemaObject(): void{ it("should be adjusted", () => { const schemaObject: vs.SchemaObject = { id: vs.number({ minValue: 1, }), name: vs.string({ maxLength: { length: 16, trims: true, }, }), age: vs.number({ integer: vs.NUMBER.INTEGER.FLOOR_RZ, minValue: 0, }), email: vs.email(), state: vs.string({ only: ["active", "inactive"], }), classes: vs.array({ separatedBy: ",", each: { schema: vs.number(), ignoresErrors: true, }, }), skills: vs.array({ separatedBy: ",", each: { schema: vs.string(), ignoresErrors: true, }, }), creditCard: vs.numericString({ separatedBy: "-", checksum: vs.NUMERIC_STRING.CHECKSUM_ALGORITHM.CREDIT_CARD, }), remoteAddr: vs.string({ pattern: vs.STRING.PATTERN.IPV4, }), remoteAddrIpv6: vs.string({ pattern: vs.STRING.PATTERN.IPV6, }), limit: vs.number({ integer: true, ifUndefined: 10, minValue: { value: 1, adjusts: true, }, maxValue: { value: 100, adjusts: true, }, }), offset: vs.number({ integer: true, ifUndefined: 0, minValue: { value: 0, adjusts: true, }, }), }; const input = { id: "1", name: "Pablo Diego José Francisco de Paula Juan Nepomuceno María de los Remedios Ciprin Cipriano de la Santísima Trinidad Ruiz y Picasso", age: 20.5, email: "picasso@example.com", state: "active", classes: "1,3,abc,4", skills: "c,c++,javascript,python,,swift,kotlin", creditCard: "4111-1111-1111-1111", remoteAddr: "127.0.0.1", remoteAddrIpv6: "::1", limit: "0", }; const expected = { id: 1, name: "Pablo Diego José", age: 20, email: "picasso@example.com", state: "active", classes: [1, 3, 4], skills: ["c", "c++", "javascript", "python", "swift", "kotlin"], creditCard: "4111111111111111", remoteAddr: "127.0.0.1", remoteAddrIpv6: "::1", limit: 1, offset: 0, };
const actual = vs.applySchemaObject(schemaObject, input); expect(actual).toEqual(expected); });}
/** * error handling */function testError(): void{ it("should be adjusted", () => { const schemaObject: vs.SchemaObject = { id: vs.number({ minValue: 1, }), name: vs.string({ maxLength: { length: 16, trims: true, }, }), email: vs.email(), }; const input = { id: 0, // error! (>= 1) name: "", // error! (empty string is not allowed) email: "john@example.com", // OK }; const expected = { id: 100, name: "John", email: "john@example.com", };
const actual = vs.applySchemaObject(schemaObject, input, (err) => { switch(err.keyStack.shift()) { case "id": return 100;
default: return "John"; } }); expect(actual).toEqual(expected); }); it("should cause error(s)", () => { expect(() => { // input must be an object vs.applySchemaObject({}, null, (err) => { expect(err.cause).toEqual(vs.CAUSE.TYPE); return null; }); }).toThrow(vs.CAUSE.TYPE);
expect( // input must be an object vs.applySchemaObject({}, null, (err) => { expect(err.cause).toEqual(vs.CAUSE.TYPE); return {}; }) ).toEqual({});
expect(() => { const schemaObject: vs.SchemaObject = {}; const input = 0;
vs.applySchemaObject(schemaObject, input); }).toThrow(vs.CAUSE.TYPE); // input must be an object
expect(() => { const schemaObject: vs.SchemaObject = {}; const input = null;
vs.applySchemaObject(schemaObject, input); }).toThrow(vs.CAUSE.TYPE); // input must be an object; typeof null === "object"
expect(() => { const schemaObject: vs.SchemaObject = {}; const input: number[] = [];
vs.applySchemaObject(schemaObject, input); }).toThrow(vs.CAUSE.TYPE); // input must be an object; typeof [] === "object"
expect(() => { const schemaObject: vs.SchemaObject = { id: vs.number({ minValue: 1, }), name: vs.string({ maxLength: { length: 16, trims: true, }, }), email: vs.email(), }; const input = { id: 0, // error! (>= 1) name: "", // error! (empty string is not allowed) email: "john@example.com", // OK };
const keys: (string | number)[] = []; vs.applySchemaObject(schemaObject, input, (err) => { if(err.keyStack.length === 0) { return; } // append key name keys.push(err.keyStack[0]); }, () => { // finished; join key name as message throw new Error(keys.join(",")); }); }).toThrow("id,name");
expect(() => { const schemaObject: vs.SchemaObject = { id: vs.number({ minValue: 1, }), name: vs.string({ maxLength: { length: 16, trims: true, }, }), email: vs.email(), }; const input = { id: 0, // error! (>= 1) name: "", // error! (empty string is not allowed) email: "john@example.com", // OK };
vs.applySchemaObject(schemaObject, input); }).toThrow(); // throw a first error if error handler is omitted
try { const schemaObject: vs.SchemaObject = { id: vs.number({ minValue: 1, }), name: vs.string({ maxLength: { length: 4, trims: true, }, }), }; const input = { id: "0", name: "John Doe", dummy: true, }; vs.object({ schemaObject: schemaObject, }).applyTo(input); expect(true).toEqual(false); } catch(err) { expect(vs.ValueSchemaError.is(err)).toBeTruthy(); if(!vs.ValueSchemaError.is(err)) { return; } expect(err.cause).toEqual(vs.CAUSE.MIN_VALUE); expect(err.keyStack).toEqual(["id"]); }
try { const schemaObject: vs.SchemaObject = { ids: vs.array({ each: vs.number({ minValue: 1, }), }), }; const input = { ids: [true, "2", "+3", "four", 5], }; vs.object({ schemaObject: schemaObject, }).applyTo(input); expect(true).toEqual(false); } catch(err) { expect(vs.ValueSchemaError.is(err)).toBeTruthy(); if(!vs.ValueSchemaError.is(err)) { return; } expect(err.cause).toEqual(vs.CAUSE.TYPE); expect(err.keyStack).toEqual(["ids", 3]); }
try { // complex schema const schemaObject: vs.SchemaObject = { infoList: vs.array({ each: vs.object({ schemaObject: { id: vs.number(), name: vs.string({ maxLength: 8, }), }, }), }), }; const input = { infoList: [ { id: "1", name: "John Doe", }, { id: "two", // ERROR! name: "John Doe", }, { id: 3, name: "John Doe 2", // ERROR! }, ], }; vs.object({ schemaObject: schemaObject, }).applyTo(input); expect(true).toEqual(false); } catch(err) { expect(vs.ValueSchemaError.is(err)).toBeTruthy(); if(!vs.ValueSchemaError.is(err)) { return; } expect(err.cause).toEqual(vs.CAUSE.TYPE); expect(err.keyStack).toEqual(["infoList", 1, "id"]); } });}