"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"); }); it("should correctly describe a guarded Set", () => { let guardedSet = createGuardedSet(new Set(), dm.boolean(), null, {}); expect(getValueType(guardedSet)).to.equal("a Set"); }); }); 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"); }); it("should correctly describe a mapOf rule", () => { let rule = dm.mapOf(dm.string(), dm.boolean()); expect(getValueType(rule)).to.equal("a Map"); }); /* 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"); }); }); 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(); }); }); }); });