Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

blork

Package Overview
Dependencies
Maintainers
1
Versions
56
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

blork - npm Package Compare versions

Comparing version 8.0.0 to 8.1.1

52

lib/classes/Blorker.js

@@ -153,3 +153,3 @@ const ValueError = require("../errors/ValueError");

* Checker function should take in a value, check it and return `true` (success) or `false` (fail).
* This format is chosen because it allows buttery constructions like `check.add(const str = v => (typeof v === 'string' || 'must be string');
* This format is chosen because it allows buttery constructions like `check.add(const str = v => typeof v === 'string', 'string');
*

@@ -308,3 +308,3 @@ * @param {string} name The type reference for the checker in kebab-case format.

if (stack.indexOf(type) >= 0)
throwError(BlorkError, "Blork type must not contain circular references", type);
throwError(BlorkError, "Blork array type must not contain circular references", type);

@@ -315,3 +315,4 @@ // Value can have circular references, but don't keep checking it over and over.

// Push type and value into the stack.
stack = [...stack, type, value];
stack.push(type);
stack.push(value);
} else {

@@ -326,10 +327,15 @@ // First loop. Start a stack.

// Loop through items and check they match type[0]
value.forEach((v, i) => this._check(v, type[0], `${prefix}[${i}]`, error, stack));
} else {
// Tuple array
for (let i = 0, l = value.length; i < l; i++)
this._check(value[i], type[0], `${prefix}[${i}]`, error, stack);
} else if (type.length > 1) {
// Tuple array (more than
// Loop through types and match each with a value recursively.
type.forEach((t, i) => this._check(value[i], t, `${prefix}[${i}]`, error, stack));
for (let i = 0, l = type.length; i < l; i++)
this._check(value[i], type[i], `${prefix}[${i}]`, error, stack);
// No excess items in a tuple.
if (value.length > type.length) throwError(error, `Must have ${type.length} items`, value.length, prefix);
} else {
// Must have at least one item.
throwError(BlorkError, `Blork array type must have one or more items`, value.length, prefix);
}

@@ -365,3 +371,3 @@ }

if (stack.indexOf(type) >= 0)
throwError(BlorkError, "Blork type must not contain circular references", type);
throwError(BlorkError, "Blork object type must not contain circular references", type);

@@ -372,3 +378,4 @@ // Value can have circular references, but don't keep checking it over and over.

// Push type and value into the stack.
stack = [...stack, type, value];
stack.push(type);
stack.push(value);
} else {

@@ -379,10 +386,11 @@ // First loop. Kick off a stack.

// Vars.
// Loop through each key in the types object (must match exactly).
const typeKeys = Object.keys(type);
for (let i = 0, l = typeKeys.length; i < l; i++) {
// Vars.
const key = typeKeys[i];
// Loop through each item in the types object.
typeKeys.forEach(key => {
// Check that the value matches the specified key.
this._check(value[key], type[key], `${prefix}.${key}`, error, stack);
});
}

@@ -403,9 +411,15 @@ // Get the KEYS and VALUES types.

// Loop through excess keys (that are in valueKeys but not in typeKeys).
valueKeys.filter(v => !~typeKeys.indexOf(v)).forEach(key => {
// If there's a KEYS type, check the key against that.
if (keysType) this._check(key, keysType, `${prefix}.${key}: Key`, error, stack);
for (let i = 0, l = valueKeys.length; i < l; i++) {
// Vars.
const key = valueKeys[i];
// Check the value against the VALUES type.
if (valuesType) this._check(value[key], valuesType, `${prefix}.${key}`, error, stack);
});
// Ignore ones in type.
if (!type.hasOwnProperty(key)) {
// If there's a KEYS type, check the key against that.
if (keysType) this._check(key, keysType, `${prefix}.${key}: Key`, error, stack);
// Check the value against the VALUES type.
if (valuesType) this._check(value[key], valuesType, `${prefix}.${key}`, error, stack);
}
}
}

@@ -412,0 +426,0 @@ }

const BlorkError = require("./errors/BlorkError");
// Regexs.
// `&` ampersand with possible whitespace either side that isn't not enclosed in parenthesis or braces (via `(?!` lookahead).
// `&` ampersand with possible whitespace either side that isn't enclosed in `([{` any parenthesis (via `(?!` lookahead).
const R_AND_SPLIT = /\s*&+\s*(?![^(]*\))(?![^{]*\})(?![^[]*\])/;
// `|` ampersand with possible whitespace either side that isn't not enclosed in parenthesis or braces (via `(?!` lookahead).
// `|` ampersand with possible whitespace either side that isn't enclosed in `([{` any parenthesis (via `(?!` lookahead).
const R_OR_SPLIT = /\s*\|+\s*(?![^(]*\))(?![^{]*\})(?![^[]*\])/;

@@ -65,3 +65,3 @@ // Split commas in a tuple.

// Loop through and call each checker.
for (let i = 0; i < ands.length; i++) if (!ands[i](v)) return false; // Fail.
for (let i = 0, l = ands.length; i < l; i++) if (!ands[i](v)) return false; // Fail.
return true; // Otherwise pass.

@@ -95,3 +95,3 @@ };

// Loop through and call each checker.
for (let i = 0; i < ors.length; i++) if (ors[i](v)) return true; // Pass.
for (let i = 0, l = ors.length; i < l; i++) if (ors[i](v)) return true; // Pass.
return false; // Otherwise fail.

@@ -222,3 +222,3 @@ };

// Create an optional checker for this optional type.
// Create an optional checker for this inverted type.
// Returns 0 if undefined, or passes through to the normal checker.

@@ -238,3 +238,3 @@ const checker = v => !valueChecker(v);

{
// One or more non-whitespace followed by `+` plus.
// One or more chars followed by `+` plus.
regex: /^(.+)\+$/,

@@ -246,3 +246,3 @@ callback(matches, find) {

// Create a length checker for this optional type.
// Create a length checker for this non-empty type.
// Returns true if checker passes and there's a numeric length or size property with a value of >0.

@@ -265,5 +265,57 @@ const checker = v => {

// Size type.
// e.g. `str{12}` (string with exactly 12 chars)
// e.g. `num{64,128}` (nums between 64 and 128)
// e.g. `arr{4,}` (arrays with a minimum of 4 itmes)
{
// One or more chars followed by {12} or {12,} or {,12} or {6,12}
regex: /^(.+)\{(?:([0-9]+)|([0-9]+),([0-9]*)|,([0-9]+))\}$/,
callback(matches, find) {
// Get normal checker.
const valueChecker = find(matches[1]);
// Vars.
const min = matches[2] ? parseInt(matches[2], 10) : matches[3] ? parseInt(matches[3], 10) : null;
const max = matches[2]
? parseInt(matches[2], 10)
: matches[4] ? parseInt(matches[4], 10) : matches[5] ? parseInt(matches[5]) : null;
// Create a length checker for this type.
const checker = v => {
// Must pass the checker first.
if (!valueChecker(v)) return false;
// Numbers use exact number
if (typeof v === "number") return (min === null || v >= min) && (max === null || v <= max);
// String and Array use .length
if (typeof v === "string" || v instanceof Array)
return (min === null || v.length >= min) && (max === null || v.length <= max);
// Map and set use .size
if (v instanceof Map || v instanceof Set)
return (min === null || v.size >= min) && (max === null || v.size <= max);
// Objects use the number of keys.
if (typeof v === "object" && v !== null) {
const l = Object.keys(v).length;
return (min === null || l >= min) && (max === null || l <= max);
}
// Nothing else has length to check.
return false;
};
// Checker settings.
checker.modified = true;
checker.desc = wrapCombined(valueChecker);
if (min === max) checker.desc += ` with size ${min}`;
else if (typeof min === "number") {
if (typeof max === "number") checker.desc += ` with size between ${min} and ${max}`;
else checker.desc += ` with minimum size ${min}`;
} else checker.desc += ` with maximum size ${max}`;
// Return it.
return checker;
}
},
// Optional type, e.g. `num?`
{
// One or more non-whitespace followed by `?` question mark.
// One or more chars followed by `?` question mark.
regex: /^(.+)\?$/,

@@ -270,0 +322,0 @@ callback(matches, find) {

{
"name": "blork",
"description": "Blork! Mini runtime type checking in Javascript",
"version": "8.0.0",
"version": "8.1.1",
"license": "0BSD",

@@ -6,0 +6,0 @@ "author": "Dave Houlbrooke <dave@shax.com>",

@@ -19,38 +19,5 @@ # Blork! Mini runtime type checking in Javascript

### args(): Check function arguments
The primary use case of Blork is validating function input arguments. The `args()` function is provided for this purpose, and can be passed four arguments:
1. `arguments` | The **arguments** object provided automatically to functions in Javascript
2. `types` | An array identifying the types for the arguments (list of types is available below)
3. `prefix` An optional string name/prefix for the value, which is prepended to any error message thrown to help debugging
4. `error` An optional custom error type to throw if the check fails
```js
import { args } from "blork";
// An exported function other (untrusted) developers may use.
export default function myFunc(definitelyString, optionalNumber)
{
// Check the args.
args(arguments, ["string", "number?"]);
// Rest of the function.
return "It passed!";
}
// Call with good args.
myFunc("abc", 123); // Returns "It passed!"
myFunc("abc"); // Returns "It passed!"
// Call with invalid args.
myFunc(123); // Throws ValueError "myFunc(): arguments[0]: Must be string (received 123)"
myFunc("abc", "abc"); // Throws ValueError "myFunc(): arguments[1]: Must be number (received "abc")"
myFunc(); // Throws ValueError "myFunc(): arguments[0]: Must be string (received undefined)"
myFunc("abc", 123, true); // Throws ValueError "myFunc(): arguments: Too many arguments (expected 2) (received 3)"
```
### check(): Check individual values
The `check()` function allows you to test individual values with more granularity. The `check()` function is more versatile and allows more use cases than validating function input arguments.
The `check()` function allows you to test that individual values correspond to a type, and throw a `TypeError` if not. This is primarily designed for checking function arguments but can be used for any purpose.

@@ -60,3 +27,3 @@ `check()` accepts four arguments:

1. `value` The value to check
2. `type` The type to check the value against (list of types is available below)
2. `type` The type to check the value against (full reference list of types is available below)
3. `prefix` An optional string name/prefix for the value, which is prepended to any error message thrown to help debugging

@@ -84,30 +51,19 @@ 4. `error` An optional custom error type to throw if the check fails

Another common use for `check()` is to validate an options object:
## Type modifiers
```js
import { check } from "blork";
`type` will mostly be specified with a type string (a full list of string types is available below), and these string types can also be modified using other characters:
// Make a custom function.
function myFunc(options)
{
// Check all the options with a literal type (note that keepAlive is optional).
check(options, { name: "string", required: "boolean", keepAlive: "number?" }, "options");
}
- Appending `?` question mark to any type string makes it optional (which means it also allows `undefined`).
- Prepending a `!` exclaimation mark to any type string makes it inverted (e.g. `!string` means anything except string).
- Multiple types can be combined with `|` and `&` for OR and AND conditions (optionally grouped with `()` parens to resolve ambiguity).
- Appending a `+` means non-empty (e.g. `arr+` `str+` means non-empty arrays and strings respectively).
// Checks that pass.
myFunc({ name: "Dog", required: true }); // No error.
// Checks that fail.
myFunc({ name: 123, required: false }); // Throws ValueError "myFunc(): options.name: Must be string (received 123)"
```
There are more complex types available: Appending `?` question mark to any type string makes it optional (which means it also allows `undefined`). Prepending a `!` exclaimation mark to any type string makes it inverted. Multiple types can be combined with `|` and `&` for OR and AND conditions.
```js
// Optional types.
check(undefined, "number"); // Throws ValueError "Must be number (received undefined)"
check(undefined, "number"); // Throws ValueError "Must be finite number (received undefined)"
check(undefined, "number?"); // No error.
// Note that null does not count as optional.
check(null, "number?"); // Throws ValueError "Must be number (received null)"
check(null, "number?"); // Throws ValueError "Must be finite number (received null)"

@@ -119,4 +75,4 @@ // Inverted types.

// Combined OR types.
check(1234, "num | str"); // No error.
check(null, "num | str"); // Throws ValueError "Must be number or string (received null)"
check(1234, "int | str"); // No error.
check(null, "int | str"); // Throws ValueError "Must be integer or string (received null)"

@@ -126,2 +82,24 @@ // Combined AND types.

check("", "string & !falsy"); // Throws ValueError "Must be string and not falsy (received "")"
// Non-empty types.
check("abc", "str+"); // No error.
check("", "str+"); // Throws ValueError "Must be non-empty string (received "")"
// Size types.
check([1, 2, 3], "arr{2,4}"); // No error.
check([1], "arr{2,3}"); // Throws ValueError "Must be plain array (minimum 2) (maximum 3) (received [1])"
check([1, 3, 3, 4], "arr{,3}"); // Throws ValueError "Must be plain array (maximum 3) (received [1])"
check([1, 2], "arr{3,}"); // Throws ValueError "Must be plain array (minimum 2) (received [1])"
// Array types.
check([1, 2, 3], "num[]"); // No error.
check(["a", "b"], "num[]"); // Throws ValueError "Must be plain array containing finite number (received ["a", "b"])"
// Tuple types.
check([1, "a"], "[int, str]"); // No error.
check([1, false], "[int, str]"); // Throws ValueError "Must be plain array tuple containing integer, string (received [1, false])"
// Object types.
check({ a: 1 }, "{ camel: integer }"); // No error.
check({ "$": 1 }, "{ camel: integer }"); // Throws ValueError "Must be plain object with camelCase string keys containing integer (received { "$": 1 })"
```

@@ -131,3 +109,3 @@

Blork can perform deep checks on objects and arrays to ensure the schema is correct. To do object or array checks pass literal arrays or literal objects to `check()` or `args()`:
Blork can also perform deep checks on objects and arrays to ensure the schema is correct deeply. You can use literal arrays or literal objects with `check()` or `args()` to do so:

@@ -179,2 +157,35 @@ ```js

### args(): Check function arguments
The primary use case of Blork is validating function input arguments. The `args()` function is provided for this purpose and can be passed four arguments:
1. `arguments` | The **arguments** object provided automatically to functions in Javascript
2. `types` | An array identifying the types for the arguments (list of types is available below)
3. `prefix` An optional string name/prefix for the value, which is prepended to any error message thrown to help debugging
4. `error` An optional custom error type to throw if the check fails
```js
import { args } from "blork";
// An exported function other (untrusted) developers may use.
export default function myFunc(definitelyString, optionalNumber)
{
// Check the args.
args(arguments, ["string", "number?"]);
// Rest of the function.
return "It passed!";
}
// Call with good args.
myFunc("abc", 123); // Returns "It passed!"
myFunc("abc"); // Returns "It passed!"
// Call with invalid args.
myFunc(123); // Throws ValueError "myFunc(): arguments[0]: Must be string (received 123)"
myFunc("abc", "abc"); // Throws ValueError "myFunc(): arguments[1]: Must be number (received "abc")"
myFunc(); // Throws ValueError "myFunc(): arguments[0]: Must be string (received undefined)"
myFunc("abc", 123, true); // Throws ValueError "myFunc(): arguments: Too many arguments (expected 2) (received 3)"
```
### assert(): Check a random true/false statement.

@@ -417,3 +428,3 @@

| `any`, `mixed` | Allow any value (transparently passes through with no error)
| `json`, `jsonable` | **JSON-friendly** values (null, true, false, finite numbers, strings, plain objects, plain arrays)
| `json`, `jsonable` | Values that can be successfully converted to JSON _and back again!_ (null, true, false, finite numbers, strings, plain objects, plain arrays)

@@ -524,6 +535,22 @@ ### String modifiers

Any string type can be made optional by prepending a `!` question mark to the type reference. This means the check will only pass if the _inverse_ of its type is true.
To specify a size for the type, you can prepend minimum/maximum with e.g. `{12}`, `{4,8}`, `{4,}` or `{,8}` (e.g. RegExp style quantifiers). This allows you to specify e.g. a string with 12 characters, an array with between 10 and 20 items, or an integer with a minimum value of 4.
```js
// Pass.
check("abc", "str{3}"); // No error (string with exact length 3 characters).
check(4, "num{,4}"); // No error (number with maximum value 4).
check(["a", "b"], "arr{1,}"); // No error (array with more than 1 item).
check([1, 2, 3], "num[]{2,4}"); // No error (array of numbers with between 2 and 4 items).
// Fail.
check("ab", "str{3}"); // Throws ValueError "Must be string with size 3"
check(4, "num{,4}"); // Throws ValueError "Must be finite number with maximum size 4"
check(["a", "b"], "arr{1,}"); // Throws ValueError "Must be array with minimum size 1"
check([1, 2, 3], "num[]{2,4}"); // Throws ValueError "Must be plain array containing finite number with size between 2 and 4"
```
Any string type can inverted by prepending a `!` exclamation mark to the type reference. This means the check will only pass if the _inverse_ of its type is true.
```js
// Pass.
check(undefined, "!str"); // No error.

@@ -761,2 +788,4 @@ check("Abc", "!lower"); // No error.

- 8.1.0
- Add min/max size constraints on types via e.g. `{4,8}` suffix
- 8.0.0

@@ -763,0 +792,0 @@ - Remove `props()` functionality (bloat)

@@ -15,2 +15,12 @@ const isJSONable = require("../../lib/checkers/isJSONable");

expect(isJSONable("abc")).toBe(true);
expect(isJSONable({ a: true })).toBe(true);
expect(isJSONable({ a: false })).toBe(true);
expect(isJSONable({ a: null })).toBe(true);
expect(isJSONable({ a: 123 })).toBe(true);
expect(isJSONable({ a: -123 })).toBe(true);
expect(isJSONable({ a: 1.5 })).toBe(true);
expect(isJSONable({ a: -1.5 })).toBe(true);
expect(isJSONable({ a: "" })).toBe(true);
expect(isJSONable({ a: "a" })).toBe(true);
expect(isJSONable({ a: "abc" })).toBe(true);
});

@@ -20,2 +30,4 @@ test("Plain arrays are JSON friendly", () => {

expect(isJSONable(arr)).toBe(true);
const deepArr = [[1, 2, 3]];
expect(isJSONable(deepArr)).toEqual(true);
});

@@ -25,30 +37,53 @@ test("Plain objects are JSON friendly", () => {

expect(isJSONable(obj)).toBe(true);
const deepObj = { deep: { a: 1, b: 2, c: 3 } };
expect(isJSONable(deepObj)).toEqual(true);
});
test("Deep plain arrays are JSON friendly", () => {
const arr = [[1, 2, 3]];
expect(isJSONable(arr)).toEqual(true);
});
test("Deep plain objects are JSON friendly", () => {
const obj = { deep: { a: 1, b: 2, c: 3 } };
expect(isJSONable(obj)).toEqual(true);
});
test("Undefined is not JSON friendly", () => {
expect(isJSONable(undefined)).toBe(false);
expect(isJSONable({ a: undefined })).toBe(false);
});
test("Symbols is not JSON friendly", () => {
test("Symbols are not JSON friendly", () => {
expect(isJSONable(Symbol("abc"))).toBe(false);
expect(isJSONable({ a: Symbol("abc") })).toBe(false);
});
test("Infinite numbers is not JSON friendly", () => {
test("Infinite numbers are not JSON friendly", () => {
expect(isJSONable(Infinity)).toBe(false);
expect(isJSONable(-Infinity)).toBe(false);
expect(isJSONable(NaN)).toBe(false);
expect(isJSONable({ a: Infinity })).toBe(false);
expect(isJSONable({ a: -Infinity })).toBe(false);
expect(isJSONable({ a: NaN })).toBe(false);
});
test("Complex objects is not JSON friendly", () => {
expect(isJSONable({ complex: new class Something {}() })).toBe(false);
expect(isJSONable({ arr: new class Megarray extends Array {}() })).toBe(false);
expect(isJSONable({ str: new String("abc") })).toBe(false);
expect(isJSONable({ date: new Date() })).toBe(false);
expect(isJSONable({ func: () => {} })).toBe(false);
test("Functions are not JSON friendly", () => {
expect(isJSONable(() => {})).toBe(false);
expect(isJSONable({ a: () => {} })).toBe(false);
expect(isJSONable(String)).toBe(false);
expect(isJSONable({ a: String })).toBe(false);
});
test("Circular references in objects are not JSON friendly", () => {
test("Constructors are not JSON friendly", () => {
expect(isJSONable(new String("abc"))).toBe(false);
expect(isJSONable({ a: new String("abc") })).toBe(false);
expect(isJSONable(new Number(123))).toBe(false);
expect(isJSONable({ a: new Number(123) })).toBe(false);
});
test("Class instances are not JSON friendly", () => {
class Something {}
class Megarray extends Array {}
expect(isJSONable(new Something())).toBe(false);
expect(isJSONable(new Megarray())).toBe(false);
expect(isJSONable({ a: new Something() })).toBe(false);
expect(isJSONable({ a: new Megarray() })).toBe(false);
});
test("Class instances are not JSON friendly", () => {
expect(isJSONable(new Date())).toBe(false);
expect(isJSONable({ a: new Date() })).toBe(false);
class MyClass {
toJSON() {
return "whatever";
}
}
expect(isJSONable(new MyClass())).toBe(false);
expect(isJSONable({ a: new MyClass() })).toBe(false);
});
test("Circular references are not JSON friendly", () => {
const obj1 = {};

@@ -60,4 +95,2 @@ obj1.circular = obj1;

expect(isJSONable(obj2)).toBe(false);
});
test("Circular references in arrays are not JSON friendly", () => {
const arr1 = [];

@@ -64,0 +97,0 @@ arr1[0] = arr1;

@@ -15,2 +15,6 @@ const BlorkError = require("../lib/errors/BlorkError");

});
test("Throw BlorkError if array type is empty", () => {
const arr = ["abc"];
expect(() => check(arr, [])).toThrow(BlorkError);
});
test("Array literal types pass correctly", () => {

@@ -17,0 +21,0 @@ expect(check([1, 2, 3], [Number])).toBe(undefined);

@@ -32,3 +32,3 @@ const BlorkError = require("../lib/errors/BlorkError");

});
test("Optional types have correct error message", () => {
test("Correct error message", () => {
expect(() => check(true, "string?")).toThrow(/Must be string or empty/);

@@ -54,3 +54,3 @@ expect(() => check("abc", "boolean?")).toThrow(/Must be boolean or empty/);

});
test("Invert types have correct error message", () => {
test("Correct error message", () => {
expect(() => check("abc", "!string")).toThrow(/Must be anything except string/);

@@ -91,3 +91,138 @@ expect(() => check(true, "!boolean")).toThrow(/Must be anything except boolean/);

});
test("Correct error message", () => {
expect(() => check(true, "str+")).toThrow(/Must be non-empty string/);
expect(() => check([], "arr+")).toThrow(/Must be non-empty plain array/);
});
});
describe("Size types", () => {
describe("Exact size types", () => {
test("Size types pass correctly", () => {
expect(check("a", "string{1}")).toBe(undefined);
expect(check("aaaa", "lower{4}")).toBe(undefined);
expect(check("AAAAA", "upper{5}")).toBe(undefined);
expect(check({ a: 1, b: 2 }, "obj{2}")).toBe(undefined);
expect(check([1, "b", true], "array{3}")).toBe(undefined);
expect(check(new Map([[1, 1], [2, 2]]), "map{2}")).toBe(undefined);
expect(check(new Set([1, 2, "c", 4]), "set{4}")).toBe(undefined);
expect(check(123, "number{123}")).toBe(undefined);
});
test("Size types fail correctly", () => {
expect(() => check("", "string{1}")).toThrow(TypeError);
expect(() => check("aa", "string{1}")).toThrow(TypeError);
expect(() => check("aaa", "lower{4}")).toThrow(TypeError);
expect(() => check("aaaaa", "lower{4}")).toThrow(TypeError);
expect(() => check("AAAA", "lower{4}")).toThrow(TypeError);
expect(() => check({ a: 1 }, "obj{2}")).toThrow(TypeError);
expect(() => check({ a: 1, b: 2, c: 3 }, "obj{2}")).toThrow(TypeError);
expect(() => check([1, "b"], "array{3}")).toThrow(TypeError);
expect(() => check([1, "b", 3, 4], "array{3}")).toThrow(TypeError);
expect(() => check(new Map([[1, 1]]), "map{2}")).toThrow(TypeError);
expect(() => check(new Map([[1, 1], [2, 2], [3, 3]]), "map{2}")).toThrow(TypeError);
expect(() => check(new Set([1, 2, 3]), "set{4}")).toThrow(TypeError);
expect(() => check(new Set([1, 2, 3, 4, 5]), "set{4}")).toThrow(TypeError);
expect(() => check(122, "number{123}")).toThrow(TypeError);
expect(() => check(124, "number{123}")).toThrow(TypeError);
});
test("Correct error message", () => {
expect(() => check("a", "str{10}")).toThrow(/Must be string with size 10/);
expect(() => check(1, "int{12}")).toThrow(/Must be integer with size 12/);
});
});
describe("Minimum size types", () => {
test("Size types pass correctly", () => {
expect(check("a", "string{1,}")).toBe(undefined);
expect(check("aa", "string{1,}")).toBe(undefined);
expect(check("aaaaaaaa", "lower{4,}")).toBe(undefined);
expect(check("AAAAA", "upper{5,}")).toBe(undefined);
expect(check({ a: 1, b: 2, c: 3 }, "obj{2,}")).toBe(undefined);
expect(check([1, "b", true, 4], "array{3,}")).toBe(undefined);
expect(check(new Map([[1, 1], [2, 2]]), "map{1,}")).toBe(undefined);
expect(check(new Set([1, 2, "c", 4]), "set{4,}")).toBe(undefined);
expect(check(124, "number{123,}")).toBe(undefined);
});
test("Size types fail correctly", () => {
expect(() => check("", "string{1,}")).toThrow(TypeError);
expect(() => check("aaa", "lower{4,}")).toThrow(TypeError);
expect(() => check("AAAAA", "lower{4,}")).toThrow(TypeError);
expect(() => check({ a: 1 }, "obj{2,}")).toThrow(TypeError);
expect(() => check([1, "b"], "array{3,}")).toThrow(TypeError);
expect(() => check(new Map([]), "map{1,}")).toThrow(TypeError);
expect(() => check(new Set([1, 2]), "set{4,}")).toThrow(TypeError);
expect(() => check(122, "number{123,}")).toThrow(TypeError);
});
test("Correct error message", () => {
expect(() => check("a", "str{10,}")).toThrow(/Must be string with minimum size 10/);
expect(() => check(1, "int{12,}")).toThrow(/Must be integer with minimum size 12/);
});
});
describe("Maximum size types", () => {
test("Size types pass correctly", () => {
expect(check("a", "string{,2}")).toBe(undefined);
expect(check("aa", "string{,2}")).toBe(undefined);
expect(check("aaaaaaaa", "lower{,12}")).toBe(undefined);
expect(check("AAAAA", "upper{,5}")).toBe(undefined);
expect(check({ a: 1, b: 2, c: 3 }, "obj{,3}")).toBe(undefined);
expect(check([1, "b", true, 4], "array{,4}")).toBe(undefined);
expect(check(new Map([[1, 1], [2, 2]]), "map{,2}")).toBe(undefined);
expect(check(new Set([1, 2, "c", 4]), "set{,4}")).toBe(undefined);
expect(check(124, "number{,124}")).toBe(undefined);
});
test("Size types fail correctly", () => {
expect(() => check("aa", "string{,1}")).toThrow(TypeError);
expect(() => check("aaaaa", "lower{,4}")).toThrow(TypeError);
expect(() => check("AAAA", "lower{,4}")).toThrow(TypeError);
expect(() => check({ a: 1, b: 2, c: 3 }, "obj{,2}")).toThrow(TypeError);
expect(() => check([1, "b", 3, 4], "array{,3}")).toThrow(TypeError);
expect(() => check(new Map([["a", 1]]), "map{,0}")).toThrow(TypeError);
expect(() => check(new Set([1, 2, 3, 4, 5]), "set{,4}")).toThrow(TypeError);
expect(() => check(122, "number{,121}")).toThrow(TypeError);
});
test("Correct error message", () => {
expect(() => check("abcdefgh", "str{,6}")).toThrow(/Must be string with maximum size 6/);
expect(() => check(123456789, "int{,12}")).toThrow(/Must be integer with maximum size 12/);
});
});
describe("Minimum and maximum size types", () => {
test("Size types pass correctly", () => {
expect(check("a", "string{1,2}")).toBe(undefined);
expect(check("aa", "string{1,2}")).toBe(undefined);
expect(check("aaaaa", "lower{4,6}")).toBe(undefined);
expect(check("AAAAA", "upper{5,6}")).toBe(undefined);
expect(check({ a: 1, b: 2, c: 3 }, "obj{2,6}")).toBe(undefined);
expect(check([1, "b", true, 4], "array{3,6}")).toBe(undefined);
expect(check(new Map([[1, 1], [2, 2]]), "map{1,6}")).toBe(undefined);
expect(check(new Set([1, 2, "c", 4]), "set{4,6}")).toBe(undefined);
expect(check(124, "number{123,125}")).toBe(undefined);
});
test("Size types fail correctly", () => {
expect(() => check("", "string{1,2}")).toThrow(TypeError);
expect(() => check("aaa", "string{1,2}")).toThrow(TypeError);
expect(() => check("aaa", "lower{4,6}")).toThrow(TypeError);
expect(() => check("AAAAA", "lower{4,6}")).toThrow(TypeError);
expect(() => check({ a: 1 }, "obj{2,3}")).toThrow(TypeError);
expect(() => check({ a: 1, b: 2, c: 3, d: 4 }, "obj{2,3}")).toThrow(TypeError);
expect(() => check([1, "b"], "array{3,4}")).toThrow(TypeError);
expect(() => check([1, "b", 3, 4, 5], "array{3,4}")).toThrow(TypeError);
expect(() => check(new Map([["a", 2]]), "map{2,3}")).toThrow(TypeError);
expect(() => check(new Map([["a", 2], ["b", 3], ["c", 4], ["d", 5]]), "map{2,3}")).toThrow(TypeError);
expect(() => check(new Set([1]), "set{2,3}")).toThrow(TypeError);
expect(() => check(new Set([1, 2, 3, 4]), "set{2,3}")).toThrow(TypeError);
expect(() => check(122, "number{123,125}")).toThrow(TypeError);
expect(() => check(126, "number{123,125}")).toThrow(TypeError);
});
test("Correct error message", () => {
expect(() => check("abcdefgh", "str{3,6}")).toThrow(/Must be string with size between 3 and 6/);
expect(() => check(1, "int{2,12}")).toThrow(/Must be integer with size between 2 and 12/);
});
});
test("Other values (boolean, symbol) are not valid", () => {
expect(() => check(true, "boolean{1,1}")).toThrow(TypeError);
});
test("Not valid without at least minimum or maximum", () => {
expect(() => check(126, "number{}")).toThrow(BlorkError);
expect(() => check(126, "number{,}")).toThrow(BlorkError);
expect(() => check(126, "number{a,}")).toThrow(BlorkError);
expect(() => check(126, "number{,b}")).toThrow(BlorkError);
});
});
describe("Array types", () => {

@@ -107,3 +242,3 @@ test("Array types pass correctly", () => {

});
test("Array types have correct error message", () => {
test("Correct error message", () => {
expect(() => check(true, "str[]")).toThrow(/Must be plain array containing string/);

@@ -128,2 +263,5 @@ expect(() => check([], "str[]+")).toThrow(/Must be non-empty plain array containing string/);

});
test("Correct error message", () => {
expect(() => check(true, "[num, str]")).toThrow(/Must be plain array tuple containing finite number, string/);
});
});

@@ -146,3 +284,3 @@ describe("Object types", () => {

});
test("Object types have correct error message", () => {
test("Correct error message", () => {
expect(() => check(true, "{int}")).toThrow(/Must be plain object containing integer/);

@@ -184,3 +322,3 @@ expect(() => check({ "ABC": true }, "{ upper: int }")).toThrow(/Must be plain object with UPPERCASE string keys containing integer/);

});
test("AND and OR combined types have correct error message", () => {
test("Correct error message", () => {
expect(() => check(1, "string & string | string")).toThrow(/Must be string and \(string or string\)/);

@@ -206,3 +344,3 @@ expect(() => check(1, "string | string & string")).toThrow(/Must be \(string or string\) and string/);

});
test('Grouped types have correct error message', () => {
test('Correct error message', () => {
expect(() => check(true, "(str | num)")).toThrow(/Must be string or finite number/);

@@ -209,0 +347,0 @@ expect(() => check(true, "(str & upper) | (num & int)")).toThrow(/Must be \(string and UPPERCASE string\) or \(finite number and integer\)/);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc