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.
144 lines
4.0 KiB
JavaScript
144 lines
4.0 KiB
JavaScript
6 years ago
|
"use strict";
|
||
|
|
||
|
const expect = require("chai").expect;
|
||
|
|
||
|
const dm = require("../src");
|
||
|
|
||
|
/* FIXME: Slot rule testing */
|
||
|
/* FIXME: Function guard signature matching */
|
||
|
|
||
|
let GitSource = dm.createTrait("GitSource", {
|
||
|
stringify: dm.function([], dm.string())
|
||
|
});
|
||
|
|
||
|
let GithubSource, CrytoGitSource, ExternalGitSource, sourceOne, sourceTwo, randomGitSource;
|
||
|
|
||
|
describe("traits", () => {
|
||
|
it("should allow valid trait implementations", () => {
|
||
|
GithubSource = dm.createType("GithubSource", {
|
||
|
username: dm.string(),
|
||
|
repository: dm.string()
|
||
|
}).implements(GitSource, {
|
||
|
stringify: dm.guard([], dm.string(), function () {
|
||
|
return `https://github.com/${this.username}/${this.repository}.git`;
|
||
|
})
|
||
|
});
|
||
|
|
||
|
CrytoGitSource = dm.createType("CrytoGitSource", {
|
||
|
username: dm.string(),
|
||
|
repository: dm.string()
|
||
|
}).implements(GitSource, {
|
||
|
stringify: dm.guard([], dm.string(), function () {
|
||
|
return `http://git.cryto.net/${this.username}/${this.repository}.git`;
|
||
|
})
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it("should produce working trait functionality", () => {
|
||
|
sourceOne = GithubSource({
|
||
|
username: "joepie91",
|
||
|
repository: "node-bhttp"
|
||
|
});
|
||
|
|
||
|
expect(sourceOne.stringify()).to.equal("https://github.com/joepie91/node-bhttp.git");
|
||
|
|
||
|
sourceTwo = CrytoGitSource({
|
||
|
username: "joepie91",
|
||
|
repository: "node-bhttp"
|
||
|
});
|
||
|
|
||
|
expect(sourceTwo.stringify()).to.equal("http://git.cryto.net/joepie91/node-bhttp.git");
|
||
|
});
|
||
|
|
||
|
let guardedFunc = dm.guard([GitSource], dm.nothing(), function (source) {
|
||
|
expect(source.stringify()).to.be.a("string");
|
||
|
});
|
||
|
|
||
|
it("should allow an instance of any type with the correct trait to be passed into a trait-guarded function", () => {
|
||
|
guardedFunc(sourceOne);
|
||
|
guardedFunc(sourceTwo);
|
||
|
});
|
||
|
|
||
|
it("should reject an instance of a type that does not have the correct trait", () => {
|
||
|
let SomeType = dm.createType("SomeType", {
|
||
|
value: dm.string()
|
||
|
});
|
||
|
|
||
|
let instance = SomeType({
|
||
|
value: "foo"
|
||
|
});
|
||
|
|
||
|
expect(() => {
|
||
|
guardedFunc(instance);
|
||
|
}).to.throw("Expected object of a type with the GitSource trait, got an instance of SomeType instead");
|
||
|
});
|
||
|
|
||
|
it(" ... even if that type has an otherwise compatible-looking method", () => {
|
||
|
let SomeOtherType = dm.createType("SomeOtherType", {
|
||
|
value: dm.string(),
|
||
|
stringify: dm.function([], dm.string())
|
||
|
});
|
||
|
|
||
|
let instance = SomeOtherType({
|
||
|
value: "foo",
|
||
|
stringify: dm.guard([], dm.string(), function () {
|
||
|
return "this is not a URL at all";
|
||
|
})
|
||
|
});
|
||
|
|
||
|
expect(() => {
|
||
|
guardedFunc(instance);
|
||
|
}).to.throw("Expected object of a type with the GitSource trait, got an instance of SomeOtherType instead");
|
||
|
});
|
||
|
|
||
|
it("should reject a trait implementation that does not meet the trait definition", () => {
|
||
|
expect(() => {
|
||
|
let InvalidType = dm.createType("InvalidType", {
|
||
|
value: dm.string()
|
||
|
}).implements(GitSource, {
|
||
|
stringify: "this is not a function"
|
||
|
});
|
||
|
}).to.throw("Expected a guarded function () → string, got a string instead");
|
||
|
});
|
||
|
|
||
|
it("should reject an empty trait implementation when the trait definition does not allow that", () => {
|
||
|
expect(() => {
|
||
|
let InvalidType = dm.createType("InvalidType", {
|
||
|
value: dm.string()
|
||
|
}).implements(GitSource, {
|
||
|
|
||
|
});
|
||
|
}).to.throw("Value is required for property 'stringify'");
|
||
|
});
|
||
|
|
||
|
it("should allow for specifying slot rules", () => {
|
||
|
ExternalGitSource = dm.createType("ExternalGitSource", {
|
||
|
sourceName: dm.string()
|
||
|
}).implements(GitSource, {
|
||
|
stringify: dm.slot()
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it("should allow specifying a value for that slot", () => {
|
||
|
randomGitSource = ExternalGitSource({
|
||
|
sourceName: "randomGit",
|
||
|
stringify: dm.guard([], dm.string(), function () {
|
||
|
return "https://randomgit.example.com/repo.git"
|
||
|
})
|
||
|
});
|
||
|
});
|
||
|
|
||
|
it("should have produced a working slot value", () => {
|
||
|
expect(randomGitSource.stringify()).to.equal("https://randomgit.example.com/repo.git");
|
||
|
});
|
||
|
|
||
|
it("should reject an invalid slot value in the instance", () => {
|
||
|
expect(() => {
|
||
|
ExternalGitSource({
|
||
|
sourceName: "randomGit",
|
||
|
stringify: "foo"
|
||
|
});
|
||
|
}).to.throw("Expected a guarded function () → string, got a string instead");
|
||
|
});
|
||
|
});
|