Comparing version 1.0.4 to 1.1.0
export declare type Validator<T> = (v: any, path: string) => T; | ||
export declare class ValidationError extends Error { | ||
name: string; | ||
constructor(message: string); | ||
} | ||
export declare const optional: <T>(handler: Validator<T>) => Validator<T | undefined>; | ||
@@ -3,0 +7,0 @@ export declare const defaultValue: <T>(def: T, handler: Validator<T>) => Validator<T>; |
"use strict"; | ||
var __extends = (this && this.__extends) || (function () { | ||
var extendStatics = function (d, b) { | ||
extendStatics = Object.setPrototypeOf || | ||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || | ||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; }; | ||
return extendStatics(d, b); | ||
}; | ||
return function (d, b) { | ||
if (typeof b !== "function" && b !== null) | ||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); | ||
extendStatics(d, b); | ||
function __() { this.constructor = d; } | ||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); | ||
}; | ||
})(); | ||
exports.__esModule = true; | ||
exports.exact = exports.oneOf = exports.transform = exports.email = exports.UUID = exports.arrayOf = exports.alternatives = exports.strToFloat = exports.float = exports.strToInt = exports.int = exports.string = exports.strToBoolean = exports.boolean = exports.object = exports.nullable = exports.defaultValue = exports.optional = void 0; | ||
exports.exact = exports.oneOf = exports.transform = exports.email = exports.UUID = exports.arrayOf = exports.alternatives = exports.strToFloat = exports.float = exports.strToInt = exports.int = exports.string = exports.strToBoolean = exports.boolean = exports.object = exports.nullable = exports.defaultValue = exports.optional = exports.ValidationError = void 0; | ||
var ValidationError = (function (_super) { | ||
__extends(ValidationError, _super); | ||
function ValidationError(message) { | ||
var _this = _super.call(this, message) || this; | ||
_this.name = 'ValidationError'; | ||
Object.setPrototypeOf(_this, ValidationError.prototype); | ||
return _this; | ||
} | ||
return ValidationError; | ||
}(Error)); | ||
exports.ValidationError = ValidationError; | ||
function assertValueInRange(actual, min, max, path) { | ||
if (min !== undefined && actual < min) { | ||
throw new ValidationError("[" + path + "] is smaller than the allowed minimum (" + min + ")"); | ||
} | ||
if (max !== undefined && actual > max) { | ||
throw new ValidationError("[" + path + "] is larger than the allowed maximum (" + max + ")"); | ||
} | ||
} | ||
var optional = function (handler) { return function (v, path) { | ||
@@ -29,3 +63,3 @@ if (v === undefined) { | ||
if (typeof v !== 'object' || !v || Array.isArray(v)) { | ||
throw new Error("[" + path + "] should be an object"); | ||
throw new ValidationError("[" + path + "] should be an object"); | ||
} | ||
@@ -36,5 +70,3 @@ var res = {}; | ||
} | ||
if ((min !== undefined && Object.keys(v).length < min) || (max !== undefined && Object.keys(v).length > max)) { | ||
throw new Error("[" + path + "] size isn't in allowed range"); | ||
} | ||
assertValueInRange(Object.keys(v).length, min, max, "size(" + path + ")"); | ||
for (var key in v) { | ||
@@ -46,3 +78,3 @@ if (!desc[key]) { | ||
else { | ||
throw new Error("Property [" + path + "." + key + "] is unknown"); | ||
throw new ValidationError("Property [" + path + "." + key + "] is unknown"); | ||
} | ||
@@ -57,3 +89,3 @@ } | ||
if (typeof v !== 'boolean') { | ||
throw new Error("[" + path + "] should be a boolean"); | ||
throw new ValidationError("[" + path + "] should be a boolean"); | ||
} | ||
@@ -74,10 +106,8 @@ return v; | ||
if (typeof v !== 'string') { | ||
throw new Error("[" + path + "] should be a string"); | ||
throw new ValidationError("[" + path + "] should be a string"); | ||
} | ||
if (pattern && !pattern.test(v)) { | ||
throw new Error("[" + path + "] doesn't match the pattern"); | ||
throw new ValidationError("[" + path + "] doesn't match the pattern"); | ||
} | ||
if ((min && v.length < min) || (max && v.length > max)) { | ||
throw new Error("[" + path + "] length isn't in allowed range"); | ||
} | ||
assertValueInRange(v.length, min, max, "length(" + path + ")"); | ||
return v; | ||
@@ -91,7 +121,5 @@ }; | ||
if (!Number.isInteger(v)) { | ||
throw new Error("[" + path + "] should be an integer"); | ||
throw new ValidationError("[" + path + "] should be an integer"); | ||
} | ||
if ((min !== undefined && v < min) || (max !== undefined && v > max)) { | ||
throw new Error("[" + path + "] isn't in allowed range"); | ||
} | ||
assertValueInRange(v, min, max, path); | ||
return v; | ||
@@ -113,7 +141,5 @@ }; | ||
if (!Number.isFinite(n)) { | ||
throw new Error("[" + path + "] should be a float"); | ||
throw new ValidationError("[" + path + "] should be a float"); | ||
} | ||
if ((min !== undefined && n < min) || (max !== undefined && n > max)) { | ||
throw new Error("[" + path + "] isn't in allowed range"); | ||
} | ||
assertValueInRange(v, min, max, path); | ||
return n; | ||
@@ -134,9 +160,14 @@ }; | ||
try { | ||
return alts[i](v, path + ".@alternative(" + i + ")"); | ||
return alts[i](v, "*"); | ||
} | ||
catch (err) { | ||
errs.push(err.message); | ||
if (err instanceof ValidationError) { | ||
errs.push("\n " + i + ": " + err.message.replace(/\n/g, '\n ')); | ||
} | ||
else { | ||
throw err; | ||
} | ||
} | ||
} | ||
throw new Error("All alternatives failed for [" + path + "]:\n\t" + errs.join('\n\t')); | ||
throw new ValidationError("[" + path + "] doesn't match any of allowed alternatives:" + errs.join('')); | ||
}; }; | ||
@@ -148,7 +179,5 @@ exports.alternatives = alternatives; | ||
if (!Array.isArray(v)) { | ||
throw new Error("[" + path + "] should be an array"); | ||
throw new ValidationError("[" + path + "] should be an array"); | ||
} | ||
if ((min !== undefined && v.length < min) || (max !== undefined && v.length > max)) { | ||
throw new Error("[" + path + "] length isn't in allowed range"); | ||
} | ||
assertValueInRange(v.length, min, max, "length(" + path + ")"); | ||
return v.map(function (item, index) { return itemValidator(item, path + "[" + index + "]"); }); | ||
@@ -172,3 +201,3 @@ }; | ||
if (values.indexOf(v) === -1) { | ||
throw new Error("[" + path + "] isn't equal to any of predefined values"); | ||
throw new ValidationError("[" + path + "] isn't equal to any of the expected values"); | ||
} | ||
@@ -180,3 +209,3 @@ return v; | ||
if (value !== v) { | ||
throw new Error("[" + path + "] isn't equal to predefined value"); | ||
throw new ValidationError("[" + path + "] isn't equal to the expected value"); | ||
} | ||
@@ -183,0 +212,0 @@ return v; |
{ | ||
"name": "checkeasy", | ||
"version": "1.0.4", | ||
"version": "1.1.0", | ||
"description": "Light, expressive and type-safe data validation in typescript", | ||
@@ -5,0 +5,0 @@ "main": "dist/index.js", |
131
README.md
@@ -1,4 +0,4 @@ | ||
checkeasy | ||
---------- | ||
# checkeasy | ||
Light, expressive and type-safe data validation in typescript. | ||
@@ -11,4 +11,3 @@ | ||
Why I need one more type validator? | ||
----------------------------------- | ||
# Why I need one more type validator? | ||
@@ -35,4 +34,3 @@ Because I wanted to have type validation which: | ||
Documentation | ||
------------- | ||
# Documentation | ||
@@ -61,5 +59,5 @@ - [Validators](#validators) | ||
Validators | ||
---------- | ||
# Validators | ||
Although, it's really easy to create your own validators, library exports few ready to go ones. | ||
@@ -80,7 +78,7 @@ | ||
const validator2 = int({min: 1}) // returns: 5 | ||
validator2(5, 'myValue'); // returns: 5 | ||
const validator2 = int() // returns: 5 | ||
validator2('5', 'myValue'); // throws: [myValue] should be an integer | ||
const validator3 = int({min: 0, max: 4}); | ||
validator3(5, 'myValue'); // throws: [myValue] isn't in allowed range | ||
validator3(5, 'myValue'); // throws: [myValue] is larger than the allowed maximum (4) | ||
``` | ||
@@ -106,7 +104,7 @@ | ||
const validator2 = float({min: 1}); | ||
validator2(5.2, 'myValue'); // returns: 5 | ||
const validator2 = float(); | ||
validator2('5.2', 'myValue'); // throws: [myValue] should be a float | ||
const validator3 = float({min: 0, max: 4}); | ||
validator3(5.2, 'myValue'); // throws: [myValue] isn't in allowed range | ||
validator3(5.2, 'myValue'); // throws: [myValue] is larger than the allowed maximum (4) | ||
``` | ||
@@ -138,3 +136,3 @@ | ||
const validator3 = string({max: 3}); | ||
validator3('aaaa', 'myValue'); // throws: [myValue] length isn't in allowed range | ||
validator3('aaaa', 'myValue'); // throws: [length(myValue)] is larger than the allowed maximum (4) | ||
@@ -223,3 +221,3 @@ const validator4 = string({patten: /^[a-z]{3}$/i}); | ||
const validator4 = arrayOf(int(), {max: 2}); | ||
validator4([1, 2, 3, 'abc'], 'myValue'); // throws: [myValue] length isn't in allowed range | ||
validator4([1, 2, 3, 'abc'], 'myValue'); // throws: [length(myValue)] is larger than the allowed maximum (2) | ||
@@ -244,7 +242,7 @@ const validator5 = arrayOf( | ||
const validator2 = exact(1) | ||
validator2('1', 'myValue'); // throws: [myValue] isn't equal to predefined value | ||
validator2('1', 'myValue'); // throws: [myValue] isn't equal to the expected value | ||
const validator3 = exact({a: 1}); | ||
validator3({a: 1}, 'myValue'); // throws: [myValue] isn't equal to predefined value | ||
// it's because it doesn't make deepEqual | ||
validator3({a: 1}, 'myValue'); // throws: [myValue] isn't equal to the expected value | ||
// it's because it doesn't call deepEqual, but uses with strict equality | ||
``` | ||
@@ -261,7 +259,7 @@ | ||
const validator2 = oneOf([1, 2, '3'] as const) | ||
validator2(3, 'myValue'); // throws: [myValue] isn't equal to any of predefined values | ||
validator2(3, 'myValue'); // throws: [myValue] isn't equal to any of the expected values | ||
const validator3 = oneOf([1, 2, {a: 1}] as const); | ||
validator3({a: 1}, 'myValue'); // throws: [myValue] isn't equal to any of predefined values | ||
// it's because it doesn't make deepEqual | ||
validator3({a: 1}, 'myValue'); // throws: [myValue] isn't equal to any of the expected values | ||
// it's because it doesn't call deepEqual, but uses with strict equality | ||
``` | ||
@@ -281,3 +279,2 @@ | ||
// as typescript recognizes type of your values array as Array<string | number> in this case | ||
// (pls let me know, if you have a solution to avoid "as const" here) | ||
``` | ||
@@ -287,3 +284,3 @@ | ||
Checks value with the help of each passed validator one by one. Returns value from first validator, which doesn't fail. | ||
Checks a value with the help of every of passed validators, one by one. Returns value from first validator, which doesn't fail. | ||
@@ -302,5 +299,5 @@ If all validators failed, throws an error. | ||
validator({a: 5}, 'myValue'); | ||
// throws: All alternatives failed for [myValue]: | ||
// [myValue.@alternative(0)] should be a string | ||
// [myValue.@alternative(1).a] should be a string | ||
// throws: [myValue] doesn't match any of allowed alternatives: | ||
// 0: [*] should be a string | ||
// 1: [*.a] should be a string | ||
``` | ||
@@ -351,7 +348,7 @@ | ||
Checks if value is uuid. | ||
Checks if value is a valid uuid string. | ||
Checks if value is email. | ||
Checks if value is a valid email string. | ||
@@ -392,15 +389,43 @@ ## any | ||
validator({type: 'user'}, 'myValue'); | ||
// throws: All alternatives failed for [myValue]: | ||
// [myValue.@alternative(0)] should be a string | ||
// [myValue.@alternative(1).id] should be a string | ||
// throws: [myValue] doesn't match any of allowed alternatives: | ||
// 0: [*] should be a string | ||
// 1: [*.id] should be a string | ||
validator('asd', 'myValue'); | ||
// throws: All alternatives failed for [myValue]: | ||
// [myValue.@alternative(0)] doesn't match the pattern | ||
// [myValue.@alternative(1)] should be an object | ||
// throws: [myValue] doesn't match any of allowed alternatives: | ||
// 0: [*] doesn't match the pattern | ||
// 1: [*] should be an object | ||
``` | ||
Custom validators | ||
----------------- | ||
Error handling | ||
-------------- | ||
In the case of validation failed, validator throws instance of ValidationError. So, it's easy to catch it. | ||
```ts | ||
import {ValidationError, int} from './index'; | ||
const validator = int(); | ||
try { | ||
validator('a', 'myValue'); | ||
} catch (err) { | ||
if (err instanceof ValidationError) { | ||
//... | ||
} | ||
// OR | ||
if (err.name === 'ValidationError') { | ||
//... | ||
} | ||
} | ||
``` | ||
# Custom validators | ||
The idea here is simple. To check any type of value you should to create a validator. | ||
@@ -414,6 +439,9 @@ | ||
In case of validation error, validator should throw an error, using _path_ to point at a place of shape, where validation | ||
failed. In case of success validator should return a value. Validator can return the same value which was received, or | ||
modify it if needed. | ||
In case of validation error, validator should throw a ValidationError, | ||
using _path_ to point at a place of shape, where validation failed. | ||
In case of success validator should return a value. | ||
Validator can return the same value which was received. | ||
Or some another value, if it should be modified on the fly. | ||
You can make inline validators. E.g.: | ||
@@ -426,3 +454,3 @@ | ||
if (typeof v !== 'string' || !v.startsWith('TYPE__')) { | ||
throw new Error(`[${path}] is not correct type`); | ||
throw new ValidationError(`[${path}] is not correct type`); | ||
} | ||
@@ -435,3 +463,3 @@ return v; | ||
If you want to crate reusable validator, the convention is to wrap it into one more function, which can additionally | ||
receive options as parameters. E.g. _int_ validator looks like: | ||
receive options as parameters. E.g. _int_ validator can look like: | ||
@@ -441,6 +469,6 @@ ```ts | ||
if (!Number.isInteger(v)) { | ||
throw new Error(`[${path}] should be an integer`); | ||
throw new ValidationError(`[${path}] should be an integer`); | ||
} | ||
if ((min !== undefined && v < min) || (max !== undefined && v > max)) { | ||
throw new Error(`[${path}] isn\'t in allowed range`); | ||
throw new ValidationError(`[${path}] isn\'t in allowed range`); | ||
} | ||
@@ -462,3 +490,3 @@ return v; | ||
We can use itself: | ||
We can use it itself: | ||
@@ -484,5 +512,14 @@ ```ts | ||
License | ||
------- | ||
# Changelog | ||
## [1.1.0] - 2022-05-20 | ||
- Added ValidationError, improved error messages. | ||
- Changed some error messages | ||
- Changes in README | ||
Thank you [joshuafcole](https://github.com/joshuafcole) for some changes here | ||
# License | ||
ISC | ||
@@ -489,0 +526,0 @@ |
@@ -5,2 +5,20 @@ // common | ||
export class ValidationError extends Error { | ||
public name = 'ValidationError'; | ||
constructor(message: string) { | ||
super(message); | ||
// fix custom error prototype in case of using with ES5 | ||
Object.setPrototypeOf(this, ValidationError.prototype); | ||
} | ||
} | ||
function assertValueInRange(actual: number, min: number | undefined, max: number | undefined, path: string) { | ||
if (min !== undefined && actual < min) { | ||
throw new ValidationError(`[${path}] is smaller than the allowed minimum (${min})`); | ||
} | ||
if (max !== undefined && actual > max) { | ||
throw new ValidationError(`[${path}] is larger than the allowed maximum (${max})`); | ||
} | ||
} | ||
export const optional = <T>(handler: Validator<T>): Validator<T | undefined> => (v, path) => { | ||
@@ -38,3 +56,3 @@ if (v === undefined) { | ||
if(typeof v !== 'object' || !v || Array.isArray(v)) { | ||
throw new Error(`[${path}] should be an object`); | ||
throw new ValidationError(`[${path}] should be an object`); | ||
} | ||
@@ -45,5 +63,3 @@ const res: any = {}; | ||
} | ||
if ((min !== undefined && Object.keys(v).length < min) || (max !== undefined && Object.keys(v).length > max)) { | ||
throw new Error(`[${path}] size isn\'t in allowed range`); | ||
} | ||
assertValueInRange(Object.keys(v).length, min, max, `size(${path})`); | ||
for (const key in v) { | ||
@@ -54,3 +70,3 @@ if (!desc[key]) { | ||
} else { | ||
throw new Error(`Property [${path}.${key}] is unknown`); | ||
throw new ValidationError(`Property [${path}.${key}] is unknown`); | ||
} | ||
@@ -64,3 +80,3 @@ } | ||
if (typeof v !== 'boolean') { | ||
throw new Error(`[${path}] should be a boolean`); | ||
throw new ValidationError(`[${path}] should be a boolean`); | ||
} | ||
@@ -83,10 +99,8 @@ return v; | ||
if(typeof v !== 'string') { | ||
throw new Error(`[${path}] should be a string`); | ||
throw new ValidationError(`[${path}] should be a string`); | ||
} | ||
if (pattern && !pattern.test(v)) { | ||
throw new Error(`[${path}] doesn't match the pattern`); | ||
throw new ValidationError(`[${path}] doesn't match the pattern`); | ||
} | ||
if ((min && v.length < min) || (max && v.length > max)) { | ||
throw new Error(`[${path}] length isn\'t in allowed range`); | ||
} | ||
assertValueInRange(v.length, min, max, `length(${path})`); | ||
return v; | ||
@@ -97,7 +111,5 @@ } | ||
if (!Number.isInteger(v)) { | ||
throw new Error(`[${path}] should be an integer`); | ||
throw new ValidationError(`[${path}] should be an integer`); | ||
} | ||
if ((min !== undefined && v < min) || (max !== undefined && v > max)) { | ||
throw new Error(`[${path}] isn\'t in allowed range`); | ||
} | ||
assertValueInRange(v, min, max, path); | ||
return v; | ||
@@ -116,7 +128,5 @@ }; | ||
if (!Number.isFinite(n)) { | ||
throw new Error(`[${path}] should be a float`); | ||
throw new ValidationError(`[${path}] should be a float`); | ||
} | ||
if ((min !== undefined && n < min) || (max !== undefined && n > max)) { | ||
throw new Error(`[${path}] isn\'t in allowed range`); | ||
} | ||
assertValueInRange(v, min, max, path); | ||
return n; | ||
@@ -138,8 +148,12 @@ }; | ||
try { | ||
return alts[i](v, `${path}.@alternative(${i})`); | ||
return alts[i](v, `*`); | ||
} catch (err: any) { | ||
errs.push(err.message); | ||
if (err instanceof ValidationError) { | ||
errs.push(`\n ${i}: ${err.message.replace(/\n/g, '\n ')}`); | ||
} else { | ||
throw err; | ||
} | ||
} | ||
} | ||
throw new Error(`All alternatives failed for [${path}]:\n\t${errs.join('\n\t')}`); | ||
throw new ValidationError(`[${path}] doesn't match any of allowed alternatives:${errs.join('')}`); | ||
}; | ||
@@ -152,7 +166,5 @@ | ||
if (!Array.isArray(v)) { | ||
throw new Error(`[${path}] should be an array`); | ||
throw new ValidationError(`[${path}] should be an array`); | ||
} | ||
if ((min !== undefined && v.length < min) || (max !== undefined && v.length > max)) { | ||
throw new Error(`[${path}] length isn\'t in allowed range`); | ||
} | ||
assertValueInRange(v.length, min, max, `length(${path})`); | ||
return v.map((item, index) => itemValidator(item, `${path}[${index}]`)); | ||
@@ -177,3 +189,3 @@ }; | ||
if (values.indexOf(v) === -1) { | ||
throw new Error(`[${path}] isn't equal to any of predefined values`); | ||
throw new ValidationError(`[${path}] isn't equal to any of the expected values`); | ||
} | ||
@@ -187,5 +199,5 @@ return v; | ||
if (value !== v) { | ||
throw new Error(`[${path}] isn't equal to predefined value`); | ||
throw new ValidationError(`[${path}] isn't equal to the expected value`); | ||
} | ||
return v; | ||
}; |
@@ -13,2 +13,3 @@ import { | ||
strToInt, transform, | ||
ValidationError, | ||
} from '../src'; | ||
@@ -38,7 +39,7 @@ | ||
int({min: 5})(4, 'test'); | ||
}).toThrow('[test] isn\'t in allowed range'); | ||
}).toThrow('[test] is smaller than the allowed minimum (5)'); | ||
expect(() => { | ||
int({max: 10})(12, 'test'); | ||
}).toThrow('[test] isn\'t in allowed range'); | ||
}).toThrow('[test] is larger than the allowed maximum (10)'); | ||
@@ -85,7 +86,7 @@ expect(() => { | ||
float({min: 5})(4, 'test'); | ||
}).toThrow('[test] isn\'t in allowed range'); | ||
}).toThrow('[test] is smaller than the allowed minimum (5)'); | ||
expect(() => { | ||
float({max: 10})(12, 'test'); | ||
}).toThrow('[test] isn\'t in allowed range'); | ||
}).toThrow('[test] is larger than the allowed maximum (10)'); | ||
@@ -132,7 +133,7 @@ expect(float()(0.5, 'test')).toEqual(0.5); | ||
string({min: 2, max: 4})('value', 'test'); | ||
}).toThrow('[test] length isn\'t in allowed range'); | ||
}).toThrow('[length(test)] is larger than the allowed maximum (4)'); | ||
expect(() => { | ||
string({min: 2, max: 4})('', 'test'); | ||
}).toThrow('[test] length isn\'t in allowed range'); | ||
}).toThrow('[length(test)] is smaller than the allowed minimum (2)'); | ||
@@ -181,3 +182,3 @@ expect(() => { | ||
})({a: 5}, 'test'); | ||
}).toThrow('[test] size isn\'t in allowed range'); | ||
}).toThrow('[size(test)] is smaller than the allowed minimum (2)'); | ||
@@ -190,3 +191,3 @@ expect(() => { | ||
})({a: 5, b: 5, c: 5, d: 5}, 'test'); | ||
}).toThrow('[test] size isn\'t in allowed range'); | ||
}).toThrow('[size(test)] is larger than the allowed maximum (3)'); | ||
@@ -227,3 +228,3 @@ expect(object({}, { | ||
arrayOf(int(), {max: 2})([1, 2, 3, 'abc'], 'test'); | ||
}).toThrow('[test] length isn\'t in allowed range'); | ||
}).toThrow('[length(test)] is larger than the allowed maximum (2)'); | ||
@@ -243,3 +244,3 @@ expect(arrayOf(optional(string()))(['1', '2', '3'], 'test')).toEqual(['1', '2', '3']); | ||
exact(1)(2, 'test'); | ||
}).toThrow('[test] isn\'t equal to predefined value'); | ||
}).toThrow('[test] isn\'t equal to the expected value'); | ||
}); | ||
@@ -252,11 +253,11 @@ | ||
oneOf([1, 2, '3'])(3, 'test'); | ||
}).toThrow('[test] isn\'t equal to any of predefined values'); | ||
}).toThrow('[test] isn\'t equal to any of the expected values'); | ||
expect(() => { | ||
oneOf([1, 2, '3'])(undefined, 'test'); | ||
}).toThrow('[test] isn\'t equal to any of predefined values'); | ||
}).toThrow('[test] isn\'t equal to any of the expected values'); | ||
expect(() => { | ||
oneOf([1, 2, {a: 1}])({a: 1}, 'test'); | ||
}).toThrow('[test] isn\'t equal to any of predefined values'); | ||
}).toThrow('[test] isn\'t equal to any of the expected values'); | ||
}); | ||
@@ -269,3 +270,3 @@ | ||
alternatives([string(), int()])(undefined, 'test'); | ||
}).toThrow('All alternatives failed for [test]:\n\t[test.@alternative(0)] should be a string\n\t[test.@alternative(1)] should be an integer'); | ||
}).toThrow('[test] doesn\'t match any of allowed alternatives:\n 0: [*] should be a string\n 1: [*] should be an integer'); | ||
@@ -276,3 +277,19 @@ expect(alternatives([string(), object({a: string()})])({a: '5'}, 'test')).toEqual({a: '5'}); | ||
alternatives([string(), object({a: string()})])({a: 5}, 'test'); | ||
}).toThrow('All alternatives failed for [test]:\n\t[test.@alternative(0)] should be a string\n\t[test.@alternative(1).a] should be a string'); | ||
}).toThrow('[test] doesn\'t match any of allowed alternatives:\n 0: [*] should be a string\n 1: [*.a] should be a string'); | ||
expect(() => { | ||
alternatives([ | ||
string(), | ||
int(), | ||
object({id: alternatives([ | ||
string(), | ||
int(), | ||
])}), | ||
])({a: 5}, 'test'); | ||
}).toThrow('[test] doesn\'t match any of allowed alternatives:\n' + | ||
' 0: [*] should be a string\n' + | ||
' 1: [*] should be an integer\n' + | ||
' 2: [*.id] doesn\'t match any of allowed alternatives:\n' + | ||
' 0: [*] should be a string\n' + | ||
' 1: [*] should be an integer'); | ||
}); | ||
@@ -359,7 +376,16 @@ | ||
validator({type: 'user'}, 'myValue'); | ||
}).toThrow('All alternatives failed for [myValue]:\n\t[myValue.@alternative(0)] should be a string\n\t[myValue.@alternative(1).id] should be a string'); | ||
}).toThrow('[myValue] doesn\'t match any of allowed alternatives:\n 0: [*] should be a string\n 1: [*.id] should be a string'); | ||
expect(() => { | ||
validator('asd', 'myValue'); | ||
}).toThrow('All alternatives failed for [myValue]:\n\t[myValue.@alternative(0)] doesn\'t match the pattern\n\t[myValue.@alternative(1)] should be an object'); | ||
}).toThrow('[myValue] doesn\'t match any of allowed alternatives:\n 0: [*] doesn\'t match the pattern\n 1: [*] should be an object'); | ||
}); | ||
}); | ||
it('should throw with ValidateError', () => { | ||
try { | ||
int()("a", 'test'); | ||
} catch (err) { | ||
expect(err).toBeInstanceOf(ValidationError); | ||
expect(err.name).toEqual('ValidationError'); | ||
} | ||
}); | ||
}); |
152866
732
512