more validators

This commit is contained in:
Sebastian Seedorf
2020-05-26 16:52:26 +02:00
parent 7367af7fe4
commit 9fa06685ba
13 changed files with 340 additions and 14 deletions

View File

@@ -9,6 +9,7 @@ import {
isString,
isNumber,
isInteger,
isRequired,
} from "./mod.ts";
Deno.test("validate schema (match)", async () => {
@@ -17,6 +18,11 @@ Deno.test("validate schema (match)", async () => {
["string", [isString]],
[["arr", "ay"], { [ArraySymbol]: isString }],
[{ foo: 3.1415, lorem: "ipsum" }, { foo: isNumber, lorem: [isString] }],
[{}, { optional: [isString] }],
[{ foo: { bar: "" } }, { foo: { bar: [isRequired, isString] } }],
[{ foo: { bar: "" } }, { foo: { bar: [isString] } }],
[{ foo: {} }, { foo: { bar: [isString] } }],
[{}, { foo: { bar: [isString] } }],
];
for (const [value, constraints] of values) {
assertEquals([], await validate(value, constraints));
@@ -29,6 +35,10 @@ Deno.test("validate schema (no match)", async () => {
[false, [isString]],
[["arr", ["ay"]], { [ArraySymbol]: isString }],
[{ foo: 3.1415, lorem: "ipsum" }, { foo: isInteger, lorem: [isString] }],
[{}, { required: [isRequired, isString] }],
[{ foo: { bar: 1 } }, { foo: { bar: [isRequired, isString] } }],
[{ foo: {} }, { foo: { bar: [isRequired, isString] } }],
[{}, { foo: { bar: [isRequired, isString] } }],
];
for (const [value, constraints] of values) {
assertNotEquals([], await validate(value, constraints));

View File

@@ -99,17 +99,8 @@ async function validateSchema(
if (!validators.hasOwnProperty(prop)) {
continue;
}
if (value.hasOwnProperty(prop)) {
const errors = await validate(value[prop], v[prop]);
valErrors.push(...(errors ?? []));
} else {
valErrors.push({
type: "property",
param: [prop],
message: `Property '${prop}' expected but not found!`,
args: { property: prop },
});
}
const errors = await validate(value && value[prop], v[prop]);
valErrors.push(...(errors ?? []));
}
return valErrors;
}

4
mod.ts
View File

@@ -8,4 +8,8 @@ export {
} from "./Validator.ts";
export { isString } from "./validators/string.ts";
export { isNumber, isInteger } from "./validators/number.ts";
export { isArray } from "./validators/array.ts";
export { or } from "./validators/logic.ts";
export { isRequired, isDefined, isNotEmpty } from "./validators/empty.ts";
export { isSymbol } from "./validators/symbol.ts";
export { isBoolean } from "./validators/boolean.ts";

38
validators/array.test.ts Normal file
View File

@@ -0,0 +1,38 @@
import { isArray } from "./array.ts";
import { validate } from "../mod.ts";
import {
assertEquals,
assertNotEquals,
} from "https://deno.land/std@0.53.0/testing/asserts.ts";
Deno.test("isArray (match)", async () => {
const values = [
undefined,
null,
[],
["foo"],
];
for (const value of values) {
assertEquals(await validate(value, isArray), []);
}
});
Deno.test("isArray (no match)", async () => {
const values = [
0,
1,
false,
true,
"",
"foo",
new String(),
new String("bar"),
() => {},
function named() {},
new Object(),
Symbol(),
];
for (const value of values) {
assertNotEquals(await validate(value, isArray), []);
}
});

14
validators/array.ts Normal file
View File

@@ -0,0 +1,14 @@
import { Validator, Args } from "../mod.ts";
export const isArray: Validator = {
type: "isArray",
check: (value: any) => {
if (value === null || value === undefined) return;
if (!Array.isArray(value)) {
return {};
}
},
message: (value: any, args?: Args) => {
return `This value has to be an array.`;
},
};

View File

@@ -0,0 +1,36 @@
import { isBoolean } from "./boolean.ts";
import { validate } from "../mod.ts";
import {
assertEquals,
assertNotEquals,
} from "https://deno.land/std@0.53.0/testing/asserts.ts";
Deno.test("isBoolean (match)", async () => {
const values = [
undefined,
null,
true,
false,
];
for (const value of values) {
assertEquals(await validate(value, isBoolean), []);
}
});
Deno.test("isBoolean (no match)", async () => {
const values = [
0,
1,
"",
"foo",
new String(),
new String("bar"),
() => {},
function named() {},
new Object(),
Symbol(),
];
for (const value of values) {
assertNotEquals(await validate(value, isBoolean), []);
}
});

14
validators/boolean.ts Normal file
View File

@@ -0,0 +1,14 @@
import { Validator, Args } from "../mod.ts";
export const isBoolean: Validator = {
type: "isBoolean",
check: (value: any) => {
if (value === null || value === undefined) return;
if (value !== true && value !== false) {
return {};
}
},
message: (value: any, args?: Args) => {
return `This value has to be a boolean.`;
},
};

99
validators/empty.test.ts Normal file
View File

@@ -0,0 +1,99 @@
import { isRequired, isDefined, isNotEmpty } from "./empty.ts";
import { validate } from "../mod.ts";
import {
assertEquals,
assertNotEquals,
} from "https://deno.land/std@0.53.0/testing/asserts.ts";
Deno.test("isRequired (match)", async () => {
const values = [
"",
" ",
"foo",
0,
1,
true,
false,
NaN,
{},
{ foo: "bar" },
[],
["foo"],
Symbol("foo"),
];
for (const value of values) {
assertEquals(await validate(value, isRequired), []);
}
});
Deno.test("isRequired (no match)", async () => {
const values = [
undefined,
null,
];
for (const value of values) {
assertNotEquals(await validate(value, isRequired), []);
}
});
Deno.test("isDefined (match)", async () => {
const values = [
null,
"",
" ",
"foo",
0,
1,
true,
false,
NaN,
{},
{ foo: "bar" },
[],
["foo"],
Symbol("foo"),
];
for (const value of values) {
assertEquals(await validate(value, isDefined), []);
}
});
Deno.test("isDefined (no match)", async () => {
const values = [
undefined,
];
for (const value of values) {
assertNotEquals(await validate(value, isDefined), []);
}
});
Deno.test("isNotEmpty (match)", async () => {
const values = [
"foo",
0,
1,
true,
false,
NaN,
{ foo: "bar" },
["foo"],
Symbol("foo"),
];
for (const value of values) {
assertEquals(await validate(value, isNotEmpty), []);
}
});
Deno.test("isNotEmpty (no match)", async () => {
const values = [
undefined,
null,
"",
" ",
{},
[],
];
for (const value of values) {
assertNotEquals(await validate(value, isNotEmpty), []);
}
});

70
validators/empty.ts Normal file
View File

@@ -0,0 +1,70 @@
import {
Validator,
Args,
isString,
isArray,
isNumber,
isSymbol,
isBoolean,
} from "../mod.ts";
export const isRequired: Validator = {
type: "isRequired",
check: (value: any) => {
if (value === null || value === undefined) {
return {};
}
},
message: (value: any, args?: Args) => {
return `This value is required.`;
},
};
export const isDefined: Validator = {
type: "isDefined",
check: (value: any) => {
if (value === undefined) {
return {};
}
},
message: (value: any, args?: Args) => {
return `This value has to be defined.`;
},
};
export const isNotEmpty: Validator = {
type: "isNotEmpty",
check: async (value: any) => {
if (value === null || value === undefined) {
return {};
}
if ((await isString.check(value)) === undefined) {
if (/^\s*$/.test(value)) {
return {};
}
return;
}
if ((await isNumber.check(value)) === undefined || Number.isNaN(value)) {
return;
}
if (await isSymbol.check(value) === undefined) {
return;
}
if (await isBoolean.check(value) === undefined) {
return;
}
if ((await isArray.check(value)) === undefined) {
if (value.length > 0) {
return;
}
return {};
}
for (const key in value) {
return;
}
return {};
},
message: (value: any, args?: Args) => {
return `This value has to be non-empty.`;
},
};

View File

@@ -9,7 +9,7 @@ export const isNumber: Validator = {
}
},
message: (value: any, args?: Args) => {
return `The value '${value && value.toString()}' has to be a number.`;
return `This value has to be a number.`;
},
};
@@ -22,6 +22,6 @@ export const isInteger: Validator = {
}
},
message: (value: any, args?: Args) => {
return `The value '${value && value.toString()}' has to be an integer.`;
return `This value has to be an integer.`;
},
};

View File

@@ -9,6 +9,6 @@ export const isString: Validator = {
}
},
message: (value: any, args?: Args) => {
return `The value '${value && value.toString()}' has to be a string.`;
return `This value has to be a string.`;
},
};

36
validators/symbol.test.ts Normal file
View File

@@ -0,0 +1,36 @@
import { isSymbol } from "./symbol.ts";
import { validate } from "../mod.ts";
import {
assertEquals,
assertNotEquals,
} from "https://deno.land/std@0.53.0/testing/asserts.ts";
Deno.test("isSymbol (match)", async () => {
const values = [
undefined,
null,
Symbol(),
];
for (const value of values) {
assertEquals(await validate(value, isSymbol), []);
}
});
Deno.test("isSymbol (no match)", async () => {
const values = [
0,
1,
true,
false,
"",
"foo",
new String(),
new String("bar"),
() => {},
function named() {},
new Object(),
];
for (const value of values) {
assertNotEquals(await validate(value, isSymbol), []);
}
});

14
validators/symbol.ts Normal file
View File

@@ -0,0 +1,14 @@
import { Validator, Args } from "../mod.ts";
export const isSymbol: Validator = {
type: "isSymbol",
check: (value: any) => {
if (value === null || value === undefined) return;
if (typeof value !== "symbol") {
return {};
}
},
message: (value: any, args?: Args) => {
return `This value has to be a symbol.`;
},
};