You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
276 lines
8.1 KiB
JavaScript
276 lines
8.1 KiB
JavaScript
6 years ago
|
"use strict";
|
||
|
|
||
|
const expect = require("chai").expect;
|
||
|
|
||
|
const dm = require("../src");
|
||
|
const getValueType = require("../src/util/get-value-type");
|
||
|
const generateValidator = require("../src/generate-validator");
|
||
|
const createGuardedMap = require("../src/guarded-collections/map");
|
||
|
const createGuardedSet = require("../src/guarded-collections/set");
|
||
|
|
||
|
describe("value descriptions", () => {
|
||
|
describe("values", () => {
|
||
|
describe("simple types", () => {
|
||
|
it("should correctly describe a string", () => {
|
||
|
expect(getValueType("some string")).to.equal("a string");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a number", () => {
|
||
|
expect(getValueType(42)).to.equal("a number");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a boolean", () => {
|
||
|
expect(getValueType(true)).to.equal("a boolean");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe null", () => {
|
||
|
expect(getValueType(null)).to.equal("null");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe undefined", () => {
|
||
|
expect(getValueType(undefined)).to.equal("undefined");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe positive Infinity", () => {
|
||
|
expect(getValueType(Infinity)).to.equal("Infinity");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe negative Infinity", () => {
|
||
|
expect(getValueType(-Infinity)).to.equal("negative Infinity");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe NaN", () => {
|
||
|
expect(getValueType(NaN)).to.equal("NaN");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a RegExp", () => {
|
||
|
expect(getValueType(new RegExp())).to.equal("a regular expression");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a regular expression literal", () => {
|
||
|
expect(getValueType(/foo/)).to.equal("a regular expression");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("function types", () => {
|
||
|
it("should correctly describe a named function", () => {
|
||
|
function namedFunction() {
|
||
|
// nothing
|
||
|
}
|
||
|
|
||
|
expect(getValueType(namedFunction)).to.equal("a function[namedFunction]");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe an anonymous function", () => {
|
||
|
expect(getValueType(function(){})).to.equal("a function");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe an arrow function", () => {
|
||
|
expect(getValueType(() => {})).to.equal("a function");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a function created through a Function object", () => {
|
||
|
expect(getValueType(new Function())).to.equal("a function");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a named constructor function", () => {
|
||
|
function SomeConstructor() {
|
||
|
// nothing
|
||
|
}
|
||
|
|
||
|
SomeConstructor.prototype.someProp = 42;
|
||
|
|
||
|
expect(getValueType(SomeConstructor)).to.equal("a constructor[SomeConstructor]");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe an anonymous constructor function", () => {
|
||
|
/* NOTE: We're doing some weird IIFE wrapping here to defeat the function name inference introduced in ES6; otherwise we can't test anonymous constructors. */
|
||
|
(function (SomeConstructor) {
|
||
|
SomeConstructor.prototype.someProp = 42;
|
||
|
expect(getValueType(SomeConstructor)).to.equal("a constructor");
|
||
|
})(function(){});
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a guarded named function", () => {
|
||
|
let func = dm.guard(
|
||
|
[dm.string(), dm.boolean()],
|
||
|
dm.nothing(),
|
||
|
function someNamedFunction(stringArg, booleanArg) {
|
||
|
// nothing
|
||
|
}
|
||
|
);
|
||
|
|
||
|
expect(getValueType(func)).to.equal("a guarded function[someNamedFunction] (string, boolean) → nothing")
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a guarded anonymous function", () => {
|
||
|
let func = dm.guard(
|
||
|
[dm.string(), dm.boolean()],
|
||
|
dm.nothing(),
|
||
|
function (stringArg, booleanArg) {
|
||
|
// nothing
|
||
|
}
|
||
|
);
|
||
|
|
||
|
expect(getValueType(func)).to.equal("a guarded function (string, boolean) → nothing")
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("collection types", () => {
|
||
|
it("should correctly describe an array", () => {
|
||
|
expect(getValueType([])).to.equal("an array");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe an object literal", () => {
|
||
|
expect(getValueType({})).to.equal("an object");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a Map", () => {
|
||
|
expect(getValueType(new Map())).to.equal("a Map");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a Set", () => {
|
||
|
expect(getValueType(new Set())).to.equal("a Set");
|
||
|
});
|
||
|
|
||
|
/* TODO: Guarded array */
|
||
|
|
||
|
it("should correctly describe a guarded Map", () => {
|
||
|
let guardedMap = createGuardedMap(new Map(), dm.boolean(), dm.string(), {});
|
||
|
expect(getValueType(guardedMap)).to.equal("a Map<string → boolean>");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a guarded Set", () => {
|
||
|
let guardedSet = createGuardedSet(new Set(), dm.boolean(), null, {});
|
||
|
expect(getValueType(guardedSet)).to.equal("a Set<boolean>");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("instance types", () => {
|
||
|
describe("standard types", () => {
|
||
|
it("should correctly describe a Date", () => {
|
||
|
expect(getValueType(new Date())).to.equal("an instance of Date");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe an Error", () => {
|
||
|
expect(getValueType(new Error())).to.equal("an instance of Error");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("custom types", () => {
|
||
|
it("should correctly describe a type", () => {
|
||
|
let CustomType = dm.createType("CustomType", {
|
||
|
value: dm.string()
|
||
|
});
|
||
|
|
||
|
expect(getValueType(CustomType({
|
||
|
value: "foo"
|
||
|
}))).to.equal("an instance of CustomType");
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("rules", () => {
|
||
|
describe("simple types", () => {
|
||
|
it("should correctly describe a boolean rule", () => {
|
||
|
expect(getValueType(dm.boolean())).to.equal("a boolean");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a string rule", () => {
|
||
|
expect(getValueType(dm.string())).to.equal("a string");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a number rule", () => {
|
||
|
expect(getValueType(dm.number())).to.equal("a number");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a null rule", () => {
|
||
|
expect(getValueType(dm.null())).to.equal("null");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a undefined rule", () => {
|
||
|
expect(getValueType(dm.undefined())).to.equal("undefined");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a nothing rule", () => {
|
||
|
expect(getValueType(dm.nothing())).to.equal("nothing");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe an instanceOf rule", () => {
|
||
|
expect(getValueType(dm.instanceOf(Date))).to.equal("an instance of Date");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("collection types", () => {
|
||
|
it("should correctly describe a setOf rule", () => {
|
||
|
let rule = dm.setOf(dm.boolean());
|
||
|
expect(getValueType(rule)).to.equal("a Set<boolean>");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a mapOf rule", () => {
|
||
|
let rule = dm.mapOf(dm.string(), dm.boolean());
|
||
|
expect(getValueType(rule)).to.equal("a Map<string → boolean>");
|
||
|
});
|
||
|
|
||
|
/* TODO: Guarded arrays */
|
||
|
});
|
||
|
|
||
|
describe("custom types", () => {
|
||
|
it("should correctly describe a type", () => {
|
||
|
let CustomType = dm.createType("CustomType", {
|
||
|
value: dm.string()
|
||
|
});
|
||
|
|
||
|
expect(getValueType(CustomType)).to.equal("an instance of CustomType");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a trait", () => {
|
||
|
let CustomTrait = dm.createTrait("CustomTrait", {
|
||
|
value: dm.string()
|
||
|
});
|
||
|
|
||
|
expect(getValueType(CustomTrait)).to.equal("an instance of a type with the CustomTrait trait");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("modifiers", () => {
|
||
|
it("should correctly describe an either rule", () => {
|
||
|
let rule = dm.either(
|
||
|
dm.string(),
|
||
|
dm.boolean()
|
||
|
);
|
||
|
|
||
|
expect(getValueType(rule)).to.equal("Either<string | boolean>");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("special rules", () => {
|
||
|
it("should correctly describe a self rule", () => {
|
||
|
expect(getValueType(dm.self())).to.equal("(self)");
|
||
|
});
|
||
|
|
||
|
it("should correctly describe a slot rule", () => {
|
||
|
expect(getValueType(dm.slot())).to.equal("(slot)");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("guards", () => {
|
||
|
it("should correctly describe a guarded function rule", () => {
|
||
|
expect(getValueType(dm.function(
|
||
|
[dm.string(), dm.boolean()],
|
||
|
dm.nothing(),
|
||
|
))).to.equal("a guarded function (string, boolean) → nothing");
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe("error conditions", () => {
|
||
|
it("should throw an error when encountering an unrecognized rule", () => {
|
||
|
expect(() => {
|
||
|
getValueType({_isTypeRule: true, _butNotReally: false});
|
||
|
}).to.throw();
|
||
|
});
|
||
|
});
|
||
|
});
|
||
|
});
|