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.

275 lines
8.0 KiB
JavaScript

"use strict";
const expect = require("chai").expect;
const dm = require("../src");
const getValueType = require("../src/util/get-value-type");
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();
});
});
});
});