Skip to content

Commit

Permalink
fix(modifiers): return false if sub-checkers aren't found (causing Bl…
Browse files Browse the repository at this point in the history
…orkError)
  • Loading branch information
dhoulb committed Nov 5, 2018
1 parent 43c1f37 commit d9bea70
Show file tree
Hide file tree
Showing 13 changed files with 112 additions and 20 deletions.
54 changes: 47 additions & 7 deletions lib/modifiers/modifiers.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ module.exports = [
// Get normal checker.
const valueChecker = find(matches[2]);

// Checkers must exist.
if (!valueChecker) return;

// Create a checker.
const checker = v => valueChecker(v);

Expand All @@ -43,6 +46,9 @@ module.exports = [
// Get normal checker.
const valueChecker = find(type);

// Checkers must exist.
if (!valueChecker) return;

// Create a checker.
const checker = v => valueChecker(v);

Expand All @@ -61,8 +67,11 @@ module.exports = [
split: "&",
callback: function andModifier(types, find) {
// Convert matches to types.
const length = types.length;
const checkers = types.map(find);
const length = checkers.length;

// Checkers must exist.
if (checkers.indexOf(undefined) >= 0) return;

// Check each checker.
const checker = v => {
Expand Down Expand Up @@ -91,8 +100,11 @@ module.exports = [
split: "|",
callback: function orModifier(types, find) {
// Convert matches to types.
const length = types.length;
const checkers = types.map(find);
const length = checkers.length;

// Checkers must exist.
if (checkers.indexOf(undefined) >= 0) return;

// Check each checker.
const checker = v => {
Expand Down Expand Up @@ -160,6 +172,9 @@ module.exports = [
// Find the real checker.
const valueChecker = find(type);

// Checkers must exist.
if (!valueChecker) return;

// Create a checker.
const checker = v => valueChecker(v);

Expand All @@ -180,19 +195,22 @@ module.exports = [
callback: function arrayModifier(type, find) {
// Get normal checker.
const isArray = find("array");
const itemChecker = find(type);
const valueChecker = find(type);

// Checkers must exist.
if (!valueChecker) return;

// Create array type checker.
const checker = v => {
// Must be an array.
if (!isArray(v)) return false;

// Check every item in the array matches type.
return v.every(w => itemChecker(w));
return v.every(w => valueChecker(w));
};

// Checker settings.
checker.desc = `plain array containing ${wrapCombined(itemChecker)}`;
checker.desc = `plain array containing ${wrapCombined(valueChecker)}`;
checker.modified = true;

// Return it.
Expand All @@ -214,6 +232,9 @@ module.exports = [
const checkers = types.map(find);
const length = checkers.length;

// Checkers must exist.
if (checkers.indexOf(undefined) >= 0) return;

// Create array type checker.
const checker = v => {
// Must be an array.
Expand Down Expand Up @@ -254,6 +275,7 @@ module.exports = [
const namedKeys = [];
const namedCheckers = {};
const anyCheckers = [];
let checkersExist = true;

// Loop through to create list of named and any checkers.
types.forEach(t => {
Expand All @@ -265,7 +287,8 @@ module.exports = [
// Key checker.
const k = find(kv[0]);
const v = find(kv[1]);
if (k.string) {
if (!k || !v) checkersExist = false;
else if (k.string) {
// Named checker.
namedKeys.push(k.string);
namedCheckers[k.string] = v;
Expand All @@ -275,12 +298,17 @@ module.exports = [
}
} else {
// Value only checker.
anyCheckers.push([undefined, find(t)]);
const v = find(t);
if (!v) checkersExist = false;
anyCheckers.push([undefined, v]);
}
});
const namedLength = namedKeys.length;
const anyLength = anyCheckers.length;

// Checkers must exist.
if (!checkersExist) return;

// Create array type checker.
const checker = v => {
// Must be an array.
Expand Down Expand Up @@ -340,6 +368,9 @@ module.exports = [
// Get normal checker.
const valueChecker = find(type);

// Checkers must exist.
if (!valueChecker) return;

// Create an optional checker for this inverted type.
// Returns 0 if undefined, or passes through to the normal checker.
const checker = v => !valueChecker(v);
Expand All @@ -361,6 +392,9 @@ module.exports = [
// Get normal checker.
const valueChecker = find(type);

// Checkers must exist.
if (!valueChecker) return;

// Create an optional checker for this optional type.
// Returns 0 if undefined, or passes through to the normal checker.
const checker = v => (v === undefined ? true : valueChecker(v));
Expand All @@ -384,6 +418,9 @@ module.exports = [
const emptyChecker = find("empty");
const valueChecker = find(type);

// Checkers must exist.
if (!valueChecker) return;

// 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.
const checker = v => {
Expand Down Expand Up @@ -433,6 +470,9 @@ module.exports = [
// Get normal checker.
const valueChecker = find(matches[1]);

// Checkers must exist.
if (!valueChecker) return;

// Vars.
const min = matches[2] ? parseInt(matches[2], 10) : matches[3] ? parseInt(matches[3], 10) : null;
const max = matches[2]
Expand Down
8 changes: 6 additions & 2 deletions test/modifiers/modifiers-and.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Combined types", () => {
describe("AND types", () => {
test("AND combined types pass correctly", () => {
expect(check(1, "number & integer")).toBe(undefined);
expect(check(1, "num & +int")).toBe(undefined);
Expand All @@ -25,4 +25,8 @@ describe("Combined types", () => {
expect(() => check(1, "string | string & string")).toThrow("Must be (string or string) and string");
expect(() => check(1, "{ string } | null")).toThrow("Must be (plain object like { string: string }) or null");
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "notexist & notexist")).toThrow(BlorkError);
expect(() => check(1, "notexist & notexist")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-array.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Array types", () => {
test("Array types pass correctly", () => {
Expand All @@ -23,4 +23,8 @@ describe("Array types", () => {
"Must be plain array containing ((non-empty string) or (non-empty plain array))"
);
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "notexist[]")).toThrow(BlorkError);
expect(() => check(1, "notexist[]")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-grouped.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Grouped types", () => {
test("Grouped types pass correctly", () => {
Expand Down Expand Up @@ -35,4 +35,8 @@ describe("Grouped types", () => {
expect(check(123, "(num | (string))")).toBe(undefined);
expect(check("abc", "(num | (string) | num)")).toBe(undefined);
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "((notexist))")).toThrow(BlorkError);
expect(() => check(1, "((notexist))")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-inverted.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Inverted types", () => {
test("Inverted types pass correctly", () => {
Expand All @@ -20,4 +20,8 @@ describe("Inverted types", () => {
expect(() => check("abc", "!str+")).toThrow("Must be anything except non-empty string");
expect(() => check(123, "!(int | str)")).toThrow("Must be anything except (integer or string)");
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "!notexist")).toThrow(BlorkError);
expect(() => check(1, "!notexist")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-nonEmpty.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Non-empty types", () => {
test("Non-empty types pass correctly", () => {
Expand Down Expand Up @@ -33,4 +33,8 @@ describe("Non-empty types", () => {
expect(() => check(true, "str+")).toThrow("Must be non-empty string");
expect(() => check([], "arr+")).toThrow("Must be non-empty plain array");
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "notexist+")).toThrow(BlorkError);
expect(() => check(1, "notexist+")).toThrow("Checker not found");
});
});
10 changes: 9 additions & 1 deletion test/modifiers/modifiers-object.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Object types", () => {
describe("Any checkers", () => {
Expand Down Expand Up @@ -64,4 +64,12 @@ describe("Object types", () => {
);
});
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "{ string: notexist }")).toThrow(BlorkError);
expect(() => check(1, "{ string: notexist }")).toThrow("Checker not found");
expect(() => check(1, "{ notexist: number }")).toThrow(BlorkError);
expect(() => check(1, "{ notexist: number }")).toThrow("Checker not found");
expect(() => check(1, "{ notexist }")).toThrow(BlorkError);
expect(() => check(1, "{ notexist }")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-optional.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Optional types", () => {
test("Optional types pass correctly", () => {
Expand All @@ -20,4 +20,8 @@ describe("Optional types", () => {
expect(() => check([true], "string?[]")).toThrow("Must be plain array containing (string or empty)");
expect(() => check([true], "(str | int)?")).toThrow("Must be (string or integer) or empty");
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "notexist?")).toThrow(BlorkError);
expect(() => check(1, "notexist?")).toThrow("Checker not found");
});
});
8 changes: 6 additions & 2 deletions test/modifiers/modifiers-or.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Combined types", () => {
describe("OR types", () => {
test("OR combined types pass correctly", () => {
expect(check(1, "number|string")).toBe(undefined);
expect(check("a", "number|string")).toBe(undefined);
Expand All @@ -12,4 +12,8 @@ describe("Combined types", () => {
expect(() => check(Symbol(), "number|string")).toThrow(TypeError);
expect(() => check(Symbol(), "number|string")).toThrow(/Must be finite number or string/);
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "notexist | notexist")).toThrow(BlorkError);
expect(() => check(1, "notexist | notexist")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-prefix.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Prefix types", () => {
test("Prefix types pass correctly", () => {
Expand Down Expand Up @@ -27,4 +27,8 @@ describe("Prefix types", () => {
);
expect(() => check({ real: 123 }, "age: { 'real': 124 }")).toThrow("age: Must be plain object");
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "prefix: notexist")).toThrow(BlorkError);
expect(() => check(1, "prefix: notexist")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-return.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Return types", () => {
test("Return types pass correctly", () => {
Expand All @@ -16,4 +16,8 @@ describe("Return types", () => {
test("Return type has highest precedence", () => {
expect(() => check(123, "return str+ | boolean")).toThrow("Must return (non-empty string) or boolean");
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "return notexist")).toThrow(BlorkError);
expect(() => check(1, "return notexist")).toThrow("Checker not found");
});
});
4 changes: 4 additions & 0 deletions test/modifiers/modifiers-size.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,4 +130,8 @@ describe("Size types", () => {
expect(() => check(126, "number{a,}")).toThrow(BlorkError);
expect(() => check(126, "number{,b}")).toThrow(BlorkError);
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "notexist{0,}")).toThrow(BlorkError);
expect(() => check(1, "notexist{0,}")).toThrow("Checker not found");
});
});
6 changes: 5 additions & 1 deletion test/modifiers/modifiers-tuple.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const { check } = require("../../lib/exports");
const { check, BlorkError } = require("../../lib/exports");

describe("Tuple types", () => {
test("Tuple types pass correctly", () => {
Expand All @@ -15,4 +15,8 @@ describe("Tuple types", () => {
test("Correct error message", () => {
expect(() => check(true, "[num, str]")).toThrow(/Must be plain array tuple like \[finite number, string\]/);
});
test("Unknown checkers throw BlorkError", () => {
expect(() => check(1, "[notexist]")).toThrow(BlorkError);
expect(() => check(1, "[notexist]")).toThrow("Checker not found");
});
});

0 comments on commit d9bea70

Please sign in to comment.