Comparing version 4.1.0 to 4.2.0
// @flow | ||
const FormattedError = require("./FormattedError"); | ||
const ValueError = require("./ValueError"); | ||
const BlorkError = require("./BlorkError"); | ||
@@ -19,22 +19,22 @@ const format = require("./format"); | ||
* @param {string} prefix A prefix for the error message. | ||
* @param {Error} defaultError The error to throw if the checker fails (used if the checker doesn't have a custom Error). | ||
* @param {Error} error The error to throw if the checker fails (used if the checker doesn't have a custom Error). | ||
* @return {void} | ||
*/ | ||
function run(checker, value, prefix, defaultError) { | ||
function runChecker(checker, value, prefix, error) { | ||
// Check the value. If we fail, throw. | ||
if (!checker(value)) { | ||
// Make standardised message using checker.desc | ||
const message = `Must be ${checker.desc}`; | ||
if (!checker(value)) | ||
// Throw either checker.error or error with standardised message. | ||
throwError(checker.error || error, `Must be ${checker.desc}`, value, prefix); | ||
} | ||
// Which error to use (either checker.error or defaultError). | ||
const whichError = checker.error || defaultError; | ||
// Treat FormattedError errors differently. | ||
if (whichError.prototype instanceof FormattedError) | ||
// If it's a FormattedError, pass in the correct arguments and throw it. | ||
throw new whichError(message, value, prefix); | ||
else | ||
// Otherwise preformat the error and throw it. | ||
throw new whichError(format(message, value, prefix)); | ||
} | ||
// Throw an error. | ||
// Pass in arguments differently if it's a ValueError. | ||
function throwError(error, message, value, prefix) { | ||
// Treat ValueError errors differently. | ||
if (error.prototype instanceof ValueError) | ||
// If it's a ValueError, pass in the correct arguments and throw it. | ||
throw new error(message, value, prefix); | ||
else | ||
// Otherwise preformat the error and throw it. | ||
throw new error(format(message, value, prefix)); | ||
} | ||
@@ -53,3 +53,3 @@ | ||
// Default error message to use. | ||
this._error = TypeError; | ||
this._error = ValueError; | ||
@@ -79,3 +79,3 @@ // Clone the input of checkers to this._checkers. | ||
// Check args. | ||
run(this._checkers.string, prefix, "arguments[2]", BlorkError); | ||
runChecker(this._checkers.string, prefix, "arguments[2]", BlorkError); | ||
@@ -86,3 +86,3 @@ // Reset loop protection. | ||
// Check the value against the type. | ||
this._check(value, type, prefix, this._error, this); | ||
this._check(value, type, prefix); | ||
} | ||
@@ -101,4 +101,4 @@ | ||
// Check args. | ||
run(this._checkers.args, argsobj, "arguments[0]", BlorkError); | ||
run(this._checkers.array, types, "arguments[1]", BlorkError); | ||
runChecker(this._checkers.args, argsobj, "arguments[0]", BlorkError); | ||
runChecker(this._checkers.array, types, "arguments[1]", BlorkError); | ||
@@ -112,7 +112,7 @@ // Reset loop protection. | ||
// Recurse into each type. | ||
for (let i = 0; i < l; i++) this._check(argsobj[i], types[i], `arguments[${i}]`, this._error, this); | ||
for (let i = 0; i < l; i++) this._check(argsobj[i], types[i], `arguments[${i}]`); | ||
// No excess arguments. | ||
if (argsobj.length > l) | ||
throw new this._error(format(`Too many arguments (expected ${l})`, argsobj.length, "arguments")); | ||
throwError(this._error, `Too many arguments (expected ${l})`, argsobj.length, "arguments"); | ||
} | ||
@@ -134,6 +134,6 @@ | ||
// Check args. | ||
run(this._checkers["lower+"], name, "arguments[0]", BlorkError); | ||
run(this._checkers.function, checker, "arguments[1]", BlorkError); | ||
run(this._checkers.string, desc, "arguments[2]", BlorkError); | ||
if (err) run(this._checkers.function, err, "arguments[3]", BlorkError); | ||
runChecker(this._checkers["lower+"], name, "arguments[0]", BlorkError); | ||
runChecker(this._checkers.function, checker, "arguments[1]", BlorkError); | ||
runChecker(this._checkers.string, desc, "arguments[2]", BlorkError); | ||
if (err) runChecker(this._checkers.function, err, "arguments[3]", BlorkError); | ||
@@ -156,3 +156,3 @@ // Don't double up. | ||
// Check args. | ||
run(this._checkers.function, error, "arguments[0]", BlorkError, this); | ||
runChecker(this._checkers.function, error, "arguments[0]", BlorkError, this); | ||
@@ -278,14 +278,14 @@ // Save err. | ||
// Found. | ||
if (typeof type === "string") run(this._find(type), value, name, this._error); | ||
else if (type === true) run(this._checkers.true, value, name, this._error); | ||
else if (type === false) run(this._checkers.false, value, name, this._error); | ||
else if (type === null) run(this._checkers.null, value, name, this._error); | ||
else if (type === undefined) run(this._checkers.undefined, value, name, this._error); | ||
else if (type === Boolean) run(this._checkers.boolean, value, name, this._error); | ||
else if (type === Number) run(this._checkers.number, value, name, this._error); | ||
else if (type === String) run(this._checkers.string, value, name, this._error); | ||
if (typeof type === "string") runChecker(this._find(type), value, name, this._error); | ||
else if (type === true) runChecker(this._checkers.true, value, name, this._error); | ||
else if (type === false) runChecker(this._checkers.false, value, name, this._error); | ||
else if (type === null) runChecker(this._checkers.null, value, name, this._error); | ||
else if (type === undefined) runChecker(this._checkers.undefined, value, name, this._error); | ||
else if (type === Boolean) runChecker(this._checkers.boolean, value, name, this._error); | ||
else if (type === Number) runChecker(this._checkers.number, value, name, this._error); | ||
else if (type === String) runChecker(this._checkers.string, value, name, this._error); | ||
else if (type instanceof Function) { | ||
// Functions do an instanceof check. | ||
if (!(value instanceof type)) | ||
throw new this._error(format(`Must be instance of ${type.name || "anonymous class"}`, value, name)); | ||
throwError(this._error, `Must be instance of ${type.name || "anonymous class"}`, value, name); | ||
} else if (type instanceof Array) { | ||
@@ -317,3 +317,3 @@ // Pass to checkArray. | ||
// Value itself must be an array (check using the array checker). | ||
run(this._checkers.array, value, name, this._error); | ||
runChecker(this._checkers.array, value, name, this._error); | ||
@@ -345,3 +345,3 @@ // Prevent infinite loops. | ||
// No excess items in a tuple. | ||
if (value.length > length) throw new this._err(format(`${length} items`, value.length, prefix)); | ||
if (value.length > length) throwError(this._error, `Must have ${length} items`, value.length, prefix); | ||
} | ||
@@ -368,3 +368,3 @@ | ||
// Value itself must be an object (check using the object checker). | ||
run(this._checkers.object, value, name, this._error); | ||
runChecker(this._checkers.object, value, name, this._error); | ||
@@ -371,0 +371,0 @@ // Prevent infinite loops. |
@@ -1,2 +0,2 @@ | ||
const FormattedError = require("./FormattedError"); | ||
const ValueError = require("./ValueError"); | ||
@@ -6,7 +6,7 @@ /** | ||
* | ||
* Blork normally throws TypeError (or a custom error) when the value you're checking is invalid. | ||
* Blork normally throws ValueError when the value you're checking is invalid. | ||
* But! A BlorkError is thrown when you're using Blork wrong. | ||
* - The type you're checking against (not the value you're checking) is invalid or doesn't exist. | ||
*/ | ||
class BlorkError extends FormattedError {} | ||
class BlorkError extends ValueError {} | ||
BlorkError.name = "BlorkError"; | ||
@@ -13,0 +13,0 @@ BlorkError.message = "Incorrect Blork configuration"; |
@@ -1,2 +0,2 @@ | ||
const FormattedError = require("./FormattedError"); | ||
const ValueError = require("./ValueError"); | ||
const BlorkError = require("./BlorkError"); | ||
@@ -21,2 +21,2 @@ const blork = require("./blork"); | ||
exports.BlorkError = BlorkError; | ||
exports.FormattedError = FormattedError; | ||
exports.ValueError = ValueError; |
{ | ||
"name": "blork", | ||
"description": "Blork! Mini runtime type checking in Javascript", | ||
"version": "4.1.0", | ||
"version": "4.2.0", | ||
"license": "0BSD", | ||
@@ -6,0 +6,0 @@ "author": "Dave Houlbrooke <dave@shax.com>", |
@@ -44,6 +44,6 @@ # Blork! Mini runtime type checking in Javascript | ||
// Call with invalid args. | ||
myFunc(123); // Throws TypeError "arguments[0]: Must be string (received 123)" | ||
myFunc("abc", "abc"); // Throws TypeError "arguments[1]: Must be number (received "abc")" | ||
myFunc(); // Throws TypeError "arguments[0]: Must be string (received undefined)" | ||
myFunc("abc", 123, true); // Throws TypeError "arguments: Too many arguments (expected 2) (received 3)" | ||
myFunc(123); // Throws ValueError "arguments[0]: Must be string (received 123)" | ||
myFunc("abc", "abc"); // Throws ValueError "arguments[1]: Must be number (received "abc")" | ||
myFunc(); // Throws ValueError "arguments[0]: Must be string (received undefined)" | ||
myFunc("abc", 123, true); // Throws ValueError "arguments: Too many arguments (expected 2) (received 3)" | ||
``` | ||
@@ -69,8 +69,8 @@ | ||
// Checks that fail. | ||
check("Sally", "number"); // Throws TypeError "Must be number (received "Sally")" | ||
check("Sally", Boolean); // Throws TypeError "Must be true or false (received "Sally")" | ||
check("Sally", "number"); // Throws ValueError "Must be number (received "Sally")" | ||
check("Sally", Boolean); // Throws ValueError "Must be true or false (received "Sally")" | ||
// Checks that fail (with a prefix/name set). | ||
check("Sally", "num", "name"); // Throws TypeError "name: Must be number (received "Sally")" | ||
check(true, "str", "status"); // Throws TypeError "status: Must be string (received true)" | ||
check("Sally", "num", "name"); // Throws ValueError "name: Must be number (received "Sally")" | ||
check(true, "str", "status"); // Throws ValueError "status: Must be string (received true)" | ||
``` | ||
@@ -97,3 +97,3 @@ | ||
// This check fails because it"s not optional. | ||
check(undefined, "number"); // Throws TypeError "Must be number (received undefined)" | ||
check(undefined, "number"); // Throws ValueError "Must be number (received undefined)" | ||
@@ -104,3 +104,3 @@ // This check passes because it"s optional. | ||
// Null does not count as optional. | ||
check(null, "number?"); // Throws TypeError "Must be number (received null)" | ||
check(null, "number?"); // Throws ValueError "Must be number (received null)" | ||
``` | ||
@@ -126,3 +126,3 @@ | ||
check([1029, "Sonia"], ["number", "string"]); // No error. | ||
check([1029, "Sonia", true], ["number", "string"]); // Throws TypeError: "Array: Too many array items (expected 2) (received 3)" | ||
check([1029, "Sonia", true], ["number", "string"]); // Throws ValueError: "Array: Too many array items (expected 2) (received 3)" | ||
``` | ||
@@ -146,3 +146,3 @@ | ||
// Deeply nested check (fails). | ||
// Will throw TypeError "Array[1][status][2]: Must be number (received "not_a_number")" | ||
// Will throw ValueError "Array[1][status][2]: Must be number (received "not_a_number")" | ||
check( | ||
@@ -189,3 +189,3 @@ [ | ||
// Fails. | ||
check("A dog sits on the chair", "catty"); // Throws TypeError "Must be string containing "cat" (received "A dog sits on the chair")" | ||
check("A dog sits on the chair", "catty"); // Throws ValueError "Must be string containing "cat" (received "A dog sits on the chair")" | ||
@@ -196,3 +196,3 @@ // Combine a custom checkers with a built-in checker using `&` syntax. | ||
check("A CAT SAT ON THE MAT", "upper+ & catty"); // No error. | ||
check("A DOG SAT ON THE MAT", "upper+ & catty"); // Throws TypeError "Must be non-empty uppercase string and string containing 'cat'" | ||
check("A DOG SAT ON THE MAT", "upper+ & catty"); // Throws ValueError "Must be non-empty uppercase string and string containing 'cat'" | ||
``` | ||
@@ -217,3 +217,3 @@ | ||
// Fails. | ||
myFunc("A dog sits over there"); // Throws TypeError "arguments[1]: Must be string containing "cat" (received "A dog sits over there")" | ||
myFunc("A dog sits over there"); // Throws ValueError "arguments[1]: Must be string containing "cat" (received "A dog sits over there")" | ||
``` | ||
@@ -251,3 +251,3 @@ | ||
// Set a new custom error on the new instance. | ||
throws(class CustomError extends TypeError); | ||
throws(class CustomError extends ValueError); | ||
@@ -321,5 +321,5 @@ // Add a custom checker on the new instance. | ||
// Fail. | ||
check(123, "str"); // Throws TypeError "Must be string (received 123)" | ||
check({}, "object+"); // Throws TypeError "Must be object with one or more properties (received Object(0))" | ||
check([], "array+"); // Throws TypeError "Must be array with one or more items (received Array(0))" | ||
check(123, "str"); // Throws ValueError "Must be string (received 123)" | ||
check({}, "object+"); // Throws ValueError "Must be object with one or more properties (received Object(0))" | ||
check([], "array+"); // Throws ValueError "Must be array with one or more items (received Array(0))" | ||
``` | ||
@@ -339,4 +339,4 @@ | ||
// Fail. | ||
check(123, "str?"); // Throws TypeError "Must be string (received 123)" | ||
check(null, "str?"); // Throws TypeError "Must be string (received null)" | ||
check(123, "str?"); // Throws ValueError "Must be string (received 123)" | ||
check(null, "str?"); // Throws ValueError "Must be string (received null)" | ||
``` | ||
@@ -356,4 +356,4 @@ | ||
// Fail. | ||
check(null, "str|num"); // Throws TypeError "Must be string or number (received null)" | ||
check(null, "str|num|bool|func|obj"); // Throws TypeError "Must be string or number or boolean or function or object (received null)" | ||
check(null, "str|num"); // Throws ValueError "Must be string or number (received null)" | ||
check(null, "str|num|bool|func|obj"); // Throws ValueError "Must be string or number or boolean or function or object (received null)" | ||
``` | ||
@@ -371,4 +371,4 @@ | ||
// Fail. | ||
check("THIS CAT IS CRAZY", "lower & catty"); // Throws TypeError "Must be lowercase string and catty" | ||
check("THIS DOG IS CRAZY", "string & catty"); // Throws TypeError "Must be string and catty" | ||
check("THIS CAT IS CRAZY", "lower & catty"); // Throws ValueError "Must be lowercase string and catty" | ||
check("THIS DOG IS CRAZY", "string & catty"); // Throws ValueError "Must be string and catty" | ||
``` | ||
@@ -412,8 +412,8 @@ | ||
// Fail. | ||
check("abc", Boolean); // Throws TypeError "Must be true or false (received "abc")" | ||
check("abc", String); // Throws TypeError "Must be string (received "abc")" | ||
check("abc", String, "myVar"); // Throws TypeError "myVar: Must be string (received "abc")" | ||
check(new MyClass, OtherClass); // Throws TypeError "Must ben instance of OtherClass (received MyClass)" | ||
check({ name: 123 }, { name: String }); // Throws TypeError "name: Must be string (received 123)" | ||
check({ name: 123 }, { name: String }, "myObj"); // Throws TypeError "myObj[name]: Must be string (received 123)" | ||
check("abc", Boolean); // Throws ValueError "Must be true or false (received "abc")" | ||
check("abc", String); // Throws ValueError "Must be string (received "abc")" | ||
check("abc", String, "myVar"); // Throws ValueError "myVar: Must be string (received "abc")" | ||
check(new MyClass, OtherClass); // Throws ValueError "Must ben instance of OtherClass (received MyClass)" | ||
check({ name: 123 }, { name: String }); // Throws ValueError "name: Must be string (received 123)" | ||
check({ name: 123 }, { name: String }, "myObj"); // Throws ValueError "myObj[name]: Must be string (received 123)" | ||
``` | ||
@@ -434,4 +434,4 @@ | ||
// Fail. | ||
check({ age: "apple" }, { age: "num" }); // Throws TypeError "age: Must be number (received "apple")" | ||
check({ size: { height: 10, width: "abc" } }, { size: { height: "num", width: "num" } }); // Throws TypeError "size[width]: Must be number (received "abc")" | ||
check({ age: "apple" }, { age: "num" }); // Throws ValueError "age: Must be number (received "apple")" | ||
check({ size: { height: 10, width: "abc" } }, { size: { height: "num", width: "num" } }); // Throws ValueError "size[width]: Must be number (received "abc")" | ||
``` | ||
@@ -451,3 +451,3 @@ | ||
// Fail. | ||
check({ a: 1, b: 2, c: "abc" }, { [ANY]: "num" }); // Throws TypeError "c: Must be number (received "abc")" | ||
check({ a: 1, b: 2, c: "abc" }, { [ANY]: "num" }); // Throws ValueError "c: Must be number (received "abc")" | ||
``` | ||
@@ -462,3 +462,3 @@ | ||
// Fail. | ||
check({ name: "Jess", another: 28 }, { name: "str", [ANY]: "undefined" }); // Throws TypeError "another: Must be undefined (received 28)" | ||
check({ name: "Jess", another: 28 }, { name: "str", [ANY]: "undefined" }); // Throws ValueError "another: Must be undefined (received 28)" | ||
``` | ||
@@ -477,4 +477,4 @@ | ||
// Fail. | ||
check(["abc", "abc", 123], ["str"]); // Throws TypeError "Array[2]: Must be number (received 123)" | ||
check(["abc", "abc", 123], ["number"]); // Throws TypeError "Array[0]: Must be string (received "abc")" | ||
check(["abc", "abc", 123], ["str"]); // Throws ValueError "Array[2]: Must be number (received 123)" | ||
check(["abc", "abc", 123], ["number"]); // Throws ValueError "Array[0]: Must be string (received "abc")" | ||
``` | ||
@@ -492,5 +492,5 @@ | ||
// Fail. | ||
check([123], ["num", "str"]); // Throws TypeError "Array[1]: Must be string (received undefined)" | ||
check([123, 123], ["num", "str"]); // Throws TypeError "Array[1]: Must be string (received 123)" | ||
check([123, "abc", true], ["num", "str"]); // Throws TypeError "Array: Too many items (expected 2 but received 3)" | ||
check([123], ["num", "str"]); // Throws ValueError "Array[1]: Must be string (received undefined)" | ||
check([123, 123], ["num", "str"]); // Throws ValueError "Array[1]: Must be string (received 123)" | ||
check([123, "abc", true], ["num", "str"]); // Throws ValueError "Array: Too many items (expected 2 but received 3)" | ||
``` | ||
@@ -508,2 +508,5 @@ | ||
- 4.2.0 | ||
- Rename `FormattedError` to `ValueError` (more descriptive and reusable name). | ||
- Make `ValueError` the default error thrown by Blork (not ValueError) | ||
- 4.1.0 | ||
@@ -510,0 +513,0 @@ - Allow custom error to be set for custom checkers via `add()` |
@@ -1,2 +0,2 @@ | ||
const FormattedError = require("../lib/FormattedError"); | ||
const ValueError = require("../lib/ValueError"); | ||
const BlorkError = require("../lib/BlorkError"); | ||
@@ -43,5 +43,5 @@ const { check, add } = require("../lib/exports"); | ||
}); | ||
test("Add and run a custom checker (with custom FormattedError)", () => { | ||
test("Add and run a custom checker (with custom ValueError)", () => { | ||
// Create a custom error. | ||
class IsNullError extends FormattedError {} | ||
class IsNullError extends ValueError {} | ||
@@ -48,0 +48,0 @@ // Define a checker called '013e93'. |
@@ -1,2 +0,2 @@ | ||
const FormattedError = require("../lib/FormattedError"); | ||
const ValueError = require("../lib/ValueError"); | ||
const BlorkError = require("../lib/BlorkError"); | ||
@@ -18,12 +18,12 @@ const { check, throws } = require("../lib/exports"); | ||
}); | ||
test("Set a custom error object (that extends FormattedError) and check it throws", () => { | ||
test("Set a custom error object (that extends ValueError) and check it throws", () => { | ||
// Define a custom error. | ||
class MyFormattedError extends FormattedError {} | ||
class MyValueError extends ValueError {} | ||
// Set it as the custom error. | ||
expect(throws(MyFormattedError)).toBeUndefined(); | ||
expect(throws(MyValueError)).toBeUndefined(); | ||
// Fail a check and make sure it throws the custom error (not TypeError). | ||
expect(() => check(false, "true", "myValue")).toThrow(MyFormattedError); | ||
expect(() => check(false, "true", "myValue")).toThrow(FormattedError); | ||
expect(() => check(false, "true", "myValue")).toThrow(MyValueError); | ||
expect(() => check(false, "true", "myValue")).toThrow(ValueError); | ||
expect(() => check(false, "true", "myValue")).toThrow(/myValue: Must be true \(received false\)/); | ||
@@ -30,0 +30,0 @@ }); |
95942
1543
501