|
|
|
"use strict";
|
|
|
|
|
|
|
|
const expect = require("chai").expect;
|
|
|
|
|
|
|
|
const dm = require("../src");
|
|
|
|
|
|
|
|
describe("function guards", () => {
|
|
|
|
it("should accept a correctly-behaving function", () => {
|
|
|
|
let guardedFunction = dm.guard([dm.string(), dm.number()], dm.boolean(), function (str, num) {
|
|
|
|
expect(str).to.equal("hello world");
|
|
|
|
expect(num).to.equal(42);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
guardedFunction("hello world", 42);
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw on an invalid return value type", () => {
|
|
|
|
let guardedFunction = dm.guard([dm.string(), dm.number()], dm.boolean(), function (str, num) {
|
|
|
|
return "not a boolean";
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(() => {
|
|
|
|
guardedFunction("hello world", 42);
|
|
|
|
}).to.throw("Expected a boolean, got a string instead");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw on an invalid argument type", () => {
|
|
|
|
let guardedFunction = dm.guard([dm.string(), dm.number()], dm.boolean(), function (str, num) {
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(() => {
|
|
|
|
guardedFunction(false, 42);
|
|
|
|
}).to.throw("Expected a string, got a boolean instead");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should throw on a missing argument", () => {
|
|
|
|
let guardedFunction = dm.guard([dm.string(), dm.number()], dm.boolean(), function (str, num) {
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
expect(() => {
|
|
|
|
guardedFunction("hello world");
|
|
|
|
}).to.throw("Value is required for property '<unknown>'");
|
|
|
|
});
|
|
|
|
|
|
|
|
it(" ... but not when that argument is optional", () => {
|
|
|
|
let guardedFunction = dm.guard([dm.string(), dm.number().optional()], dm.boolean(), function (str, num) {
|
|
|
|
expect(str).to.equal("hello world");
|
|
|
|
expect(num).to.equal(null);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
guardedFunction("hello world");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should correctly handle defaults", () => {
|
|
|
|
let guardedFunction = dm.guard([dm.string(), dm.number().default(42)], dm.boolean(), function (str, num) {
|
|
|
|
expect(str).to.equal("hello world");
|
|
|
|
expect(num).to.equal(42);
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
guardedFunction("hello world");
|
|
|
|
});
|
|
|
|
|
|
|
|
let SomeType = dm.createType("SomeType", {
|
|
|
|
value: dm.string()
|
|
|
|
});
|
|
|
|
|
|
|
|
let guardedTypeFunction = dm.guard([SomeType], dm.nothing(), function (instance) {
|
|
|
|
expect(instance.value).to.equal("foo");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should allow correct instances for a type rule", () => {
|
|
|
|
guardedTypeFunction(SomeType({
|
|
|
|
value: "foo"
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should reject other values for that rule", () => {
|
|
|
|
expect(() => {
|
|
|
|
guardedTypeFunction("hello world");
|
|
|
|
}).to.throw("Expected an instance of SomeType, got a string instead");
|
|
|
|
});
|
|
|
|
|
|
|
|
let SomeTraitType = dm.createType("SomeTraitType", {
|
|
|
|
value: dm.string()
|
|
|
|
});
|
|
|
|
|
|
|
|
let SomeTrait = dm.createTrait("SomeTrait", {
|
|
|
|
traitValue: dm.string()
|
|
|
|
});
|
|
|
|
|
|
|
|
SomeTraitType.implements(SomeTrait, {
|
|
|
|
traitValue: "SomeTraitType"
|
|
|
|
});
|
|
|
|
|
|
|
|
let guardedTraitFunction = dm.guard([SomeTrait], dm.nothing(), function (instance) {
|
|
|
|
expect(instance.value).to.equal("foo");
|
|
|
|
expect(instance.traitValue).to.equal("SomeTraitType");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should allow correct instances for a trait rule", () => {
|
|
|
|
guardedTraitFunction(SomeTraitType({
|
|
|
|
value: "foo"
|
|
|
|
}));
|
|
|
|
});
|
|
|
|
|
|
|
|
it ("should reject instances that do not have the trait", () => {
|
|
|
|
expect(() => {
|
|
|
|
guardedTraitFunction(SomeType({
|
|
|
|
value: "foo"
|
|
|
|
}));
|
|
|
|
}).to.throw("Expected object of a type with the SomeTrait trait, got an instance of SomeType instead");
|
|
|
|
});
|
|
|
|
|
|
|
|
it("should reject other values for that rule", () => {
|
|
|
|
expect(() => {
|
|
|
|
guardedTraitFunction("hello world");
|
|
|
|
}).to.throw("Expected object of a type with the SomeTrait trait, got a string instead");
|
|
|
|
});
|
|
|
|
});
|