@onlabsorg/swan-js
Version:
A simple yet powerful expression language written in JavaScript
1,366 lines (1,049 loc) • 75.9 kB
JavaScript
const expect = require("./expect");
const {
Term,
Tuple,
Item,
Bool,
Numb,
Func,
Undefined,
Mapping,
Sequence,
Text,
List,
Namespace,
wrap, unwrap
} = require('../lib/types');
describe("types", () => {
describe("Bool", () => {
describe(".items()", () => {
it("should yield the item itself", () => {
const item = new Bool(true);
expect(item.items()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.items())).to.deep.equal([item]);
});
});
describe(".values()", () => {
it("should yield the item value", () => {
const item = new Bool(true);
expect(item.values()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.values())).to.deep.equal([true]);
});
});
describe("[Symbol.iterator]()", () => {
it("should yield the item value", () => {
const item = new Bool(true);
expect(Array.from(item)).to.deep.equal([true]);
});
});
describe(".iterPairs(other)", () => {
it("should yield corresponding pairs of the two terms", () => {
const item1 = new Bool(true);
const item2 = new Bool(false);
expect(item1.iterPairs(item2)[Symbol.iterator]).to.be.a("function");
const pairs = Array.from(item1.iterPairs(item2));
expect(pairs.length).to.equal(1);
expect(pairs[0][0]).to.be.Bool(true);
expect(pairs[0][1]).to.be.Bool(false);
});
});
describe(".imapSync(fn)", () => {
it("should synchronously apply fn to the item and return the wrapped output", () => {
const item = new Bool(true);
const fn = item => [item.unwrap()];
expect(item.imapSync(fn)).to.be.List([true]);
});
});
describe(".vmapSync(fn)", () => {
it("should synchronously apply fn to the item value and return the wrapped output", () => {
const item = new Bool(true);
const fn = value => [value];
expect(item.vmapSync(fn)).to.be.List([true]);
});
});
describe(".imapAsync(fn)", () => {
it("should asynchronously apply fn to the item and return the wrapped output", async () => {
const item = new Bool(true);
const fn = async item => [item.unwrap()];
expect(await item.imapAsync(fn)).to.be.List([true]);
});
});
describe(".vmapAsync(fn)", () => {
it("should asynchronously apply fn to the item value and return the wrapped output", async () => {
const item = new Bool(true);
const fn = async value => [value];
expect(await item.vmapAsync(fn)).to.be.List([true]);
});
});
describe(".toBoolean()", () => {
it("should return the term value", () => {
expect((new Bool(true)).toBoolean()).to.be.true;
expect((new Bool(false)).toBoolean()).to.be.false;
});
});
describe(".toString()", () => {
it("should return 'TRUE' if the value is true", () => {
expect((new Bool(true)).toString()).to.equal("TRUE")
});
it("should return 'FALSE' if the value is true", () => {
expect((new Bool(false)).toString()).to.equal("FALSE")
});
});
describe(".typeName", () => {
it("should return the item class name", () => {
expect(new Bool(true).typeName).to.equal("Bool");
});
});
describe(".isNothing()", () => {
it("should return false", () => {
expect(new Bool(true).isNothing()).to.be.false;
});
});
describe(".normalize()", () => {
it("should return the item as it is", () => {
const item = new Bool(true);
expect(item.normalize()).to.equal(item);
});
});
describe(".unwrap()", () => {
it("should return the item value", () => {
expect(new Bool(true).unwrap() ).to.equal(true);
expect(new Bool(false).unwrap()).to.equal(false);
});
});
describe(".sum(other)", () => {
it("should return the logical OR", () => {
const TRUE = new Bool(true);
const FALSE = new Bool(false);
expect(TRUE.sum(TRUE) ).to.be.Bool(true);
expect(TRUE.sum(FALSE) ).to.be.Bool(true);
expect(FALSE.sum(TRUE) ).to.be.Bool(true);
expect(FALSE.sum(FALSE)).to.be.Bool(false);
});
});
describe(".negate()", () => {
it("should not be defined", () => {
const item = new Bool(true);
expect(item.negate).to.be.undefined;
});
});
describe(".isNull()", () => {
it("should return true if the item is FALSE", () => {
expect(new Bool(true).isNull()).to.be.false;
expect(new Bool(false).isNull()).to.be.true;
});
});
describe("Bool.null", () => {
it("should return FALSE", () => {
expect(Bool.null).to.be.Bool(false);
});
});
describe(".mul(other)", () => {
it("should return the logical AND", () => {
const TRUE = new Bool(true);
const FALSE = new Bool(false);
expect(TRUE.mul(TRUE) ).to.be.Bool(true);
expect(TRUE.mul(FALSE) ).to.be.Bool(false);
expect(FALSE.mul(TRUE) ).to.be.Bool(false);
expect(FALSE.mul(FALSE)).to.be.Bool(false);
});
});
describe(".invert()", () => {
it("should not be defined", () => {
const item = new Bool(true);
expect(item.invert).to.be.undefined;
});
});
describe(".isUnit()", () => {
it("should return true if the item is TRUE", () => {
expect(new Bool(true).isUnit()).to.be.true;
expect(new Bool(false).isUnit()).to.be.false;
});
});
describe("Bool.unit", () => {
it("should return TRUE", () => {
expect(Bool.unit).to.be.Bool(true);
});
});
describe(".pow(other)", () => {
it("should not be defined", () => {
const item = new Bool(true);
expect(item.pow).to.be.undefined;
});
});
describe(".compare(other)", () => {
it("should return 0 if the items are both TRUE or both FALSE", () => {
const TRUE = new Bool(true);
const FALSE = new Bool(false);
expect(TRUE.compare(TRUE)).to.equal(0);
expect(FALSE.compare(FALSE)).to.equal(0);
});
it("should consider FALSE less than TRUE", () => {
const TRUE = new Bool(true);
const FALSE = new Bool(false);
expect(TRUE.compare(FALSE)).to.equal(+1);
expect(FALSE.compare(TRUE)).to.equal(-1);
});
});
});
describe("Numb", () => {
describe(".items()", () => {
it("should yield the item itself", () => {
const item = new Numb(10);
expect(item.items()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.items())).to.deep.equal([item]);
});
});
describe(".values()", () => {
it("should yield the item value", () => {
const item = new Numb(10);
expect(item.values()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.values())).to.deep.equal([10]);
});
});
describe("[Symbol.iterator]()", () => {
it("should yield the item value", () => {
const item = new Numb(10);
expect(Array.from(item)).to.deep.equal([10]);
});
});
describe(".iterPairs(other)", () => {
it("should yield corresponding pairs of the two terms", () => {
const item1 = new Numb(10);
const item2 = new Numb(20);
expect(item1.iterPairs(item2)[Symbol.iterator]).to.be.a("function");
const pairs = Array.from(item1.iterPairs(item2));
expect(pairs.length).to.equal(1);
expect(pairs[0][0]).to.be.Numb(10);
expect(pairs[0][1]).to.be.Numb(20);
});
});
describe(".imapSync(fn)", () => {
it("should synchronously apply fn to the item and return the wrapped output", () => {
const item = new Numb(10);
const fn = item => [item.unwrap()];
expect(item.imapSync(fn)).to.be.List([10]);
});
});
describe(".vmapSync(fn)", () => {
it("should synchronously apply fn to the item value and return the wrapped output", () => {
const item = new Numb(10);
const fn = value => [value];
expect(item.vmapSync(fn)).to.be.List([10]);
});
});
describe(".imapAsync(fn)", () => {
it("should asynchronously apply fn to the item and return the wrapped output", async () => {
const item = new Numb(10);
const fn = async item => [item.unwrap()];
expect(await item.imapAsync(fn)).to.be.List([10]);
});
});
describe(".vmapAsync(fn)", () => {
it("should asynchronously apply fn to the item value and return the wrapped output", async () => {
const item = new Numb(10);
const fn = async value => [value];
expect(await item.vmapAsync(fn)).to.be.List([10]);
});
});
describe(".toBoolean()", () => {
it("should return true if the number is not null", () => {
expect((new Numb(9)).toBoolean()).to.be.true;
expect((new Numb(0)).toBoolean()).to.be.false;
});
});
describe(".toString()", () => {
it("should return the stringified value", () => {
expect((new Numb(-1.23)).toString()).to.equal("-1.23");
});
});
describe(".typeName", () => {
it("should return the item class name", () => {
expect(new Numb(10).typeName).to.equal("Numb");
});
});
describe(".isNothing()", () => {
it("should return false", () => {
expect(new Numb(10).isNothing()).to.be.false;
expect(new Numb( 0).isNothing()).to.be.false;
});
});
describe(".normalize()", () => {
it("should return the item as it is", () => {
const item = new Numb(10);
expect(item.normalize()).to.equal(item);
});
});
describe(".unwrap()", () => {
it("should return the item value", () => {
expect(new Numb(10).unwrap()).to.equal(10);
expect(new Numb( 0).unwrap()).to.equal( 0);
});
});
describe(".sum(other)", () => {
it("should return the sum of the two numbers", () => {
const item1 = new Numb(10);
const item2 = new Numb(20);
expect(item1.sum(item2)).to.be.Numb(30);
});
});
describe(".negate()", () => {
it("should return the negation of the item", () => {
const item = new Numb(10);
expect(item.negate()).to.be.Numb(-10);
});
});
describe(".isNull()", () => {
it("should return true if the item is 0", () => {
expect(new Numb(10).isNull()).to.be.false;
expect(new Numb( 0).isNull()).to.be.true;
});
});
describe("Numb.null", () => {
it("should return 0", () => {
expect(Numb.null).to.be.Numb(0);
});
});
describe(".mul(other)", () => {
it("should return the product of the two numbers", () => {
const item1 = new Numb(10);
const item2 = new Numb(20);
expect(item1.mul(item2)).to.be.Numb(200);
});
});
describe(".invert()", () => {
it("should return the reciprocal of the Numb item", () => {
const item = new Numb(10);
expect(item.invert()).to.be.Numb(0.1);
});
});
describe(".isUnit()", () => {
it("should return true if the item is 1", () => {
expect(new Numb(1).isUnit()).to.be.true;
expect(new Numb(0).isUnit()).to.be.false;
});
});
describe("Numb.unit", () => {
it("should return 1", () => {
expect(Numb.unit).to.be.Numb(1);
});
});
describe(".pow(other)", () => {
it("should return the exponentiation of the two numbers", () => {
const item1 = new Numb(10);
const item2 = new Numb(3);
expect(item1.pow(item2)).to.be.Numb(1000);
});
});
describe(".compare(other)", () => {
it("should compare the two numbers according to the real numbers order rules", () => {
const item1 = new Numb(10);
const item2 = new Numb(20);
expect(item1.compare(item1)).to.equal(0);
expect(item2.compare(item2)).to.equal(0);
expect(item1.compare(item2)).to.equal(-1);
expect(item2.compare(item1)).to.equal(+1);
});
});
});
describe("Text", () => {
describe(".items()", () => {
it("should yield the item itself", () => {
const item = new Text("abc");
expect(item.items()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.items())).to.deep.equal([item]);
});
});
describe(".values()", () => {
it("should yield the item value", () => {
const item = new Text("abc");
expect(item.values()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.values())).to.deep.equal(["abc"]);
});
});
describe("[Symbol.iterator]()", () => {
it("should yield the item value", () => {
const item = new Text("abc");
expect(Array.from(item)).to.deep.equal(["abc"]);
});
});
describe(".iterPairs(other)", () => {
it("should yield corresponding pairs of the two terms", () => {
const item1 = new Text("abc");
const item2 = new Text("def");
expect(item1.iterPairs(item2)[Symbol.iterator]).to.be.a("function");
const pairs = Array.from(item1.iterPairs(item2));
expect(pairs.length).to.equal(1);
expect(pairs[0][0]).to.be.Text("abc");
expect(pairs[0][1]).to.be.Text("def");
});
});
describe(".imapSync(fn)", () => {
it("should synchronously apply fn to the item and return the wrapped output", () => {
const item = new Text("abc");
const fn = item => [item.unwrap()];
expect(item.imapSync(fn)).to.be.List(["abc"]);
});
});
describe(".vmapSync(fn)", () => {
it("should synchronously apply fn to the item value and return the wrapped output", () => {
const item = new Text("abc");
const fn = value => [value];
expect(item.vmapSync(fn)).to.be.List(["abc"]);
});
});
describe(".imapAsync(fn)", () => {
it("should asynchronously apply fn to the item and return the wrapped output", async () => {
const item = new Text("abc");
const fn = async item => [item.unwrap()];
expect(await item.imapAsync(fn)).to.be.List(["abc"]);
});
});
describe(".vmapAsync(fn)", () => {
it("should asynchronously apply fn to the item value and return the wrapped output", async () => {
const item = new Text("abc");
const fn = async value => [value];
expect(await item.vmapAsync(fn)).to.be.List(["abc"]);
});
});
describe(".toBoolean()", () => {
it("should return true if the string value is not empty", () => {
expect((new Text("abc")).toBoolean()).to.be.true;
expect((new Text("")).toBoolean()).to.be.false;
});
});
describe(".toString()", () => {
it("should return the text value as it is", () => {
expect((new Text("abc")).toString()).to.equal("abc");
});
});
describe(".typeName", () => {
it("should return the item class name", () => {
expect(new Text("abc").typeName).to.equal("Text");
});
});
describe(".isNothing()", () => {
it("should return false", () => {
expect(new Text("abc").isNothing()).to.be.false;
expect(new Text("" ).isNothing()).to.be.false;
});
});
describe(".normalize()", () => {
it("should return the item as it is", () => {
const item = new Text("abc");
expect(item.normalize()).to.equal(item);
});
});
describe(".unwrap()", () => {
it("should return the item value", () => {
expect(new Text("abc").unwrap()).to.equal("abc");
expect(new Text("" ).unwrap()).to.equal("");
});
});
describe(".sum(other)", () => {
it("should concatenate the two strings", () => {
const item1 = new Text("abc");
const item2 = new Text("def");
expect(item1.sum(item2)).to.be.Text("abcdef");
});
});
describe(".negate()", () => {
it("should not be defined", () => {
const item = new Text("abc");
expect(item.negate).to.be.undefined;
});
});
describe(".isNull()", () => {
it("should return true if the string is empty", () => {
expect(new Text("abc").isNull()).to.be.false;
expect(new Text("" ).isNull()).to.be.true;
});
});
describe("Text.null", () => {
it("should return an empty Text item", () => {
expect(Text.null).to.be.Text("");
});
});
describe(".mul(other)", () => {
it("should not be defined", () => {
const item = new Text("abc");
expect(item.mul).to.be.undefined;
});
});
describe(".invert()", () => {
it("should not be defined", () => {
const item = new Text("abc");
expect(item.invert).to.be.undefined;
});
});
describe(".isUnit()", () => {
it("should not be defined", () => {
const item = new Text("abc");
expect(item.isUnit).to.be.undefined;
});
});
describe("Text.unit", () => {
it("should not be defined", () => {
expect(Text.unit).to.be.undefined;
});
});
describe(".pow(other)", () => {
it("should not be defined", () => {
const item = new Text("abc");
expect(item.pow).to.be.undefined;
});
});
describe(".compare(other)", () => {
it("should compare the two strings alphabetically", () => {
const item1 = new Text("abc");
const item2 = new Text("def");
expect(item1.compare(item1)).to.equal(0);
expect(item2.compare(item2)).to.equal(0);
expect(item1.compare(item2)).to.equal(-1);
expect(item2.compare(item1)).to.equal(+1);
expect(new Text("aaa").compare(new Text("aa"))).to.equal(+1);
});
});
describe(".domain", () => {
it("should return the array of integers between 0 and the string length minus one", () => {
expect(new Text("abc").domain).to.deep.equal([0,1,2]);
expect(new Text("" ).domain).to.deep.equal([]);
});
});
describe(".vget(i)", () => {
it("should return i-th character of the string", () => {
expect(new Text("abc").vget(1)).to.equal('b')
});
it("should return undefined if i is not in the Text domain", () => {
const item = new Text("abc");
expect(item.vget(-1)).to.be.undefined;
expect(item.vget(10)).to.be.undefined;
expect(item.vget('xx')).to.be.undefined;
});
});
describe(".size", () => {
it("should contain the number of characters of the string", () => {
expect(new Text("abc").size).to.equal(3);
expect(new Text("").size).to.equal(0);
});
});
describe(".image", () => {
it("should return the tuple of characters of the string", () => {
const item = new Text("abc");
expect(item.image).to.deep.equal(['a','b','c']);
});
});
describe(".apply(...X)", () => {
it("should return the tuple of Text characters mapped to the arguments", () => {
const item = new Text("abcdef");
expect(item.apply(1,3,5)).to.be.Tuple(['b','d','f']);
});
it("should normalize the returned tuple", () => {
const item = new Text("abcdef");
expect(item.apply(1)).to.be.Text('b');
});
it("should return Undefined Mapping if the index is not in the Text item domain", () => {
const item = new Text("abcdef");
expect(item.apply(-1)).to.be.Undefined('Mapping', arg0 => {
expect(arg0).to.equal(-1);
});
const tuple = item.apply(1, -1, 3);
expect(tuple).to.be.instanceof(Tuple);
expect(Array.from(tuple)[0]).to.equal('b');
expect(Array.from(tuple)[1]).to.be.Undefined('Mapping', arg0 => {
expect(arg0).to.equal(-1);
});
expect(Array.from(tuple)[2]).to.equal('d');
});
})
});
describe("List", () => {
describe(".items()", () => {
it("should yield the item itself", () => {
const item = new List([10,20,30]);
expect(item.items()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.items())).to.deep.equal([item]);
});
});
describe(".values()", () => {
it("should yield the item value", () => {
const item = new List([10,20,30]);
expect(item.values()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.values())).to.deep.equal([[10,20,30]]);
});
});
describe("[Symbol.iterator]()", () => {
it("should yield the item value", () => {
const item = new List([10,20,30]);
expect(Array.from(item)).to.deep.equal([[10,20,30]]);
});
});
describe(".iterPairs(other)", () => {
it("should yield corresponding pairs of the two terms", () => {
const item1 = new List([10,20,30]);
const item2 = new List([40,50,60]);
expect(item1.iterPairs(item2)[Symbol.iterator]).to.be.a("function");
const pairs = Array.from(item1.iterPairs(item2));
expect(pairs.length).to.equal(1);
expect(pairs[0][0]).to.be.List([10,20,30]);
expect(pairs[0][1]).to.be.List([40,50,60]);
});
});
describe(".imapSync(fn)", () => {
it("should synchronously apply fn to the item and return the wrapped output", () => {
const item = new List([10,20,30]);
const fn = item => [item.unwrap()];
expect(item.imapSync(fn)).to.be.List([[10,20,30]]);
});
});
describe(".vmapSync(fn)", () => {
it("should synchronously apply fn to the item value and return the wrapped output", () => {
const item = new List([10,20,30]);
const fn = value => [value];
expect(item.vmapSync(fn)).to.be.List([[10,20,30]]);
});
});
describe(".imapAsync(fn)", () => {
it("should asynchronously apply fn to the item and return the wrapped output", async () => {
const item = new List([10,20,30]);
const fn = async item => [item.unwrap()];
expect(await item.imapAsync(fn)).to.be.List([[10,20,30]]);
});
});
describe(".vmapAsync(fn)", () => {
it("should asynchronously apply fn to the item value and return the wrapped output", async () => {
const item = new List([10,20,30]);
const fn = async value => [value];
expect(await item.vmapAsync(fn)).to.be.List([[10,20,30]]);
});
});
describe(".toBoolean()", () => {
it("should return true if the array value is not empty", () => {
expect((new List([10,20,30])).toBoolean()).to.be.true;
expect((new List([ ])).toBoolean()).to.be.false;
});
});
describe(".toString()", () => {
it("should return '[[List of n items]]'", () => {
expect(new List([10,20,30]).toString()).to.equal("[[List of 3 items]]");
expect(new List([10 ]).toString()).to.equal("[[List of 1 item]]");
expect(new List([ ]).toString()).to.equal("[[List of 0 items]]");
});
});
describe(".typeName", () => {
it("should return the item class name", () => {
expect(new List([10,20,30]).typeName).to.equal("List");
});
});
describe(".isNothing()", () => {
it("should return false", () => {
expect(new List([10,20,30]).isNothing()).to.be.false;
expect(new List([ ]).isNothing()).to.be.false;
});
});
describe(".normalize()", () => {
it("should return the item as it is", () => {
const item = new List([10,20,30]);
expect(item.normalize()).to.equal(item);
});
});
describe(".unwrap()", () => {
it("should return the item value", () => {
expect(new List([10,20,30]).unwrap()).to.deep.equal([10,20,30]);
expect(new List([ ]).unwrap()).to.deep.equal([]);
});
});
describe(".sum(other)", () => {
it("should concatenate the two lists", () => {
const item1 = new List([10,20,30]);
const item2 = new List([40,50,60]);
expect(item1.sum(item2)).to.be.List([10,20,30,40,50,60]);
});
});
describe(".negate()", () => {
it("should not be defined", () => {
const item = new List([10,20,30]);
expect(item.negate).to.be.undefined;
});
});
describe(".isNull()", () => {
it("should return true if the list is empty", () => {
expect(new List([10,20,30]).isNull()).to.be.false;
expect(new List([ ]).isNull()).to.be.true;
});
});
describe("List.null", () => {
it("should return an empty Text item", () => {
expect(List.null).to.be.List([]);
});
});
describe(".mul(other)", () => {
it("should not be defined", () => {
const item = new List([10,20,30]);
expect(item.mul).to.be.undefined;
});
});
describe(".invert()", () => {
it("should not be defined", () => {
const item = new List([10,20,30]);
expect(item.invert).to.be.undefined;
});
});
describe(".isUnit()", () => {
it("should not be defined", () => {
const item = new List([10,20,30]);
expect(item.isUnit).to.be.undefined;
});
});
describe("List.unit", () => {
it("should not be defined", () => {
expect(List.unit).to.be.undefined;
});
});
describe(".pow(other)", () => {
it("should not be defined", () => {
const item = new List([10,20,30]);
expect(item.pow).to.be.undefined;
});
});
describe(".compare(other)", () => {
it("should compare the two lists lexicographically", () => {
const item1 = new List([10,20,30]);
const item2 = new List([40,50,60]);
expect(item1.compare(item1)).to.equal(0);
expect(item2.compare(item2)).to.equal(0);
expect(item1.compare(item2)).to.equal(-1);
expect(item2.compare(item1)).to.equal(+1);
expect(new List([10,10,10]).compare(new List([10,10]))).to.equal(+1);
});
});
describe(".domain", () => {
it("should return the array of integers between 0 and the list length minus one", () => {
expect(new List([10,20,30]).domain).to.deep.equal([0,1,2]);
expect(new List([ ]).domain).to.deep.equal([]);
});
});
describe(".vget(i)", () => {
it("should return i-th value of the list", () => {
expect(new List([10,20,30]).vget(1)).to.equal(20)
});
it("should return undefined if i is not in the List domain", () => {
const item = new List([10,20,30]);
expect(item.vget(-1)).to.be.undefined;
expect(item.vget(10)).to.be.undefined;
expect(item.vget('xx')).to.be.undefined;
});
});
describe(".size", () => {
it("should contain the number of items of the list", () => {
expect(new List([10,20,30]).size).to.equal(3);
expect(new List([ ]).size).to.equal(0);
});
});
describe(".image", () => {
it("should return the tuple of characters of the string", () => {
const item = new List([10,20,30]);
expect(item.image).to.be.deep.equal([10,20,30]);
});
});
describe(".apply(...X)", () => {
it("should return the tuple of List items mapped to the arguments", () => {
const item = new List([10,20,30,40,50,60]);
expect(item.apply(1,3,5)).to.be.Tuple([20,40,60]);
});
it("should normalize the returned tuple", () => {
const item = new List([10,20,30,40,50,60]);
expect(item.apply(1)).to.be.Numb(20);
});
it("should return Undefined Mapping if the index is not in the List item domain", () => {
const item = new List([10,20,30,40,50,60]);
expect(item.apply(-1)).to.be.Undefined('Mapping', arg0 => {
expect(arg0).to.equal(-1);
});
const tuple = item.apply(1, -1, 3);
expect(tuple).to.be.instanceof(Tuple);
expect(Array.from(tuple)[0]).to.equal(20);
expect(Array.from(tuple)[1]).to.be.Undefined('Mapping', arg0 => {
expect(arg0).to.equal(-1);
});
expect(Array.from(tuple)[2]).to.equal(40);
});
})
});
describe("Namespace", () => {
describe(".items()", () => {
it("should yield the item itself", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.items()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.items())).to.deep.equal([item]);
});
});
describe(".values()", () => {
it("should yield the item value", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.values()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.values())).to.deep.equal([{k1:1, k2:2, k3:3}]);
});
});
describe("[Symbol.iterator]()", () => {
it("should yield the item value", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(Array.from(item)).to.deep.equal([{k1:1, k2:2, k3:3}]);
});
});
describe(".iterPairs(other)", () => {
it("should yield corresponding pairs of the two terms", () => {
const item1 = new Namespace({k1:1, k2:2, k3:3});
const item2 = new Namespace({k4:4, k5:5, k6:6});
expect(item1.iterPairs(item2)[Symbol.iterator]).to.be.a("function");
const pairs = Array.from(item1.iterPairs(item2));
expect(pairs.length).to.equal(1);
expect(pairs[0][0]).to.be.Namespace({k1:1, k2:2, k3:3});
expect(pairs[0][1]).to.be.Namespace({k4:4, k5:5, k6:6});
});
});
describe(".imapSync(fn)", () => {
it("should synchronously apply fn to the item and return the wrapped output", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
const fn = item => [item.unwrap()];
expect(item.imapSync(fn)).to.be.List([{k1:1, k2:2, k3:3}]);
});
});
describe(".vmapSync(fn)", () => {
it("should synchronously apply fn to the item value and return the wrapped output", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
const fn = value => [value];
expect(item.vmapSync(fn)).to.be.List([{k1:1, k2:2, k3:3}]);
});
});
describe(".imapAsync(fn)", () => {
it("should asynchronously apply fn to the item and return the wrapped output", async () => {
const item = new Namespace({k1:1, k2:2, k3:3});
const fn = async item => [item.unwrap()];
expect(await item.imapAsync(fn)).to.be.List([{k1:1, k2:2, k3:3}]);
});
});
describe(".vmapAsync(fn)", () => {
it("should asynchronously apply fn to the item value and return the wrapped output", async () => {
const item = new Namespace({k1:1, k2:2, k3:3});
const fn = async value => [value];
expect(await item.vmapAsync(fn)).to.be.List([{k1:1, k2:2, k3:3}]);
});
});
describe(".toBoolean()", () => {
it("should return true if the namespace value is not empty", () => {
expect((new Namespace({a:1})).toBoolean()).to.be.true;
expect((new Namespace({})).toBoolean()).to.be.false;
});
it("should consider empty a namespace containing only non-valid identifiers", () => {
expect((new Namespace({$key:1})).toBoolean()).to.be.false;
});
});
describe(".toString()", () => {
it("should retun '[[Namespace of n items]]'", () => {
expect((new Namespace({key1:1, key2:2, key3:3, $key4:4})).toString()).to.equal("[[Namespace of 3 items]]");
expect((new Namespace({key1:1 })).toString()).to.equal("[[Namespace of 1 item]]");
expect((new Namespace({ })).toString()).to.equal("[[Namespace of 0 items]]");
});
});
describe(".typeName", () => {
it("should return the item class name", () => {
expect(new Namespace({k1:1, k2:2, k3:3}).typeName).to.equal("Namespace");
});
});
describe(".isNothing()", () => {
it("should return false", () => {
expect(new Namespace({k1:1, k2:2, k3:3}).isNothing()).to.be.false;
expect(new Namespace({ }).isNothing()).to.be.false;
});
});
describe(".normalize()", () => {
it("should return the item as it is", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.normalize()).to.equal(item);
});
});
describe(".unwrap()", () => {
it("should return the item value", () => {
expect(new Namespace({k1:1, k2:2, k3:3}).unwrap()).to.deep.equal({k1:1, k2:2, k3:3});
expect(new Namespace({ }).unwrap()).to.deep.equal({});
});
});
describe(".sum(other)", () => {
it("should concatenate the two lists", () => {
const item1 = new Namespace({k1:1, k2:2, k3:3});
const item2 = new Namespace({k3:4, k4:5, k5:6});
expect(item1.sum(item2)).to.be.Namespace({k1:1, k2:2, k3:4, k4:5, k5:6});
});
});
describe(".negate()", () => {
it("should not be defined", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.negate).to.be.undefined;
});
});
describe(".isNull()", () => {
it("should return true if the list is empty", () => {
expect(new Namespace({k1:1, k2:2, k3:3}).isNull()).to.be.false;
expect(new Namespace({ }).isNull()).to.be.true;
});
});
describe("Namespace.null", () => {
it("should return an empty Text item", () => {
expect(Namespace.null).to.be.Namespace({});
});
});
describe(".mul(other)", () => {
it("should not be defined", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.mul).to.be.undefined;
});
});
describe(".invert()", () => {
it("should not be defined", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.invert).to.be.undefined;
});
});
describe(".isUnit()", () => {
it("should not be defined", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.isUnit).to.be.undefined;
});
});
describe("Namespace.unit", () => {
it("should not be defined", () => {
expect(Namespace.unit).to.be.undefined;
});
});
describe(".pow(other)", () => {
it("should not be defined", () => {
const item = new Namespace({k1:1, k2:2, k3:3});
expect(item.pow).to.be.undefined;
});
});
describe(".compare(other)", () => {
it("should return equal if two namespace have the same identifiers and equal values", () => {
const item1 = new Namespace({k1:1, k2:2, k3:3});
const item2 = new Namespace({k4:4, k5:5, k6:6});
expect(item1.compare(item1)).to.equal(0);
expect(item2.compare(item2)).to.equal(0);
expect(item1.compare(item2)).to.be.NaN;
expect(item2.compare(item1)).to.be.NaN;
expect(new Namespace({k1:1, k2:2, $k3:3}).compare(new Namespace({k1:1, k2:2}))).to.equal(0);
});
});
describe(".domain", () => {
it("should return the array of the namespace identifiers", () => {
expect(new Namespace({k1:1, k2:2, k3:3}).domain).to.deep.equal(['k1','k2','k3']);
expect(new Namespace({ }).domain).to.deep.equal([]);
});
});
describe(".vget(key)", () => {
it("should return the value mapped to the given identifier", () => {
expect(new Namespace({k1:1, k2:2, k3:3}).vget('k2')).to.equal(2)
});
it("should return undefined if key is not in the Namespace domain", () => {
const item = new Namespace({k1:1, k2:2, k3:3, $k4:4});
expect(item.vget(10)).to.be.undefined;
expect(item.vget('xx')).to.be.undefined;
expect(item.vget('$k4')).to.be.undefined;
});
});
describe(".size", () => {
it("should contain the number of names in the namespace", () => {
expect(new Namespace({x:10,y:20,z:30}).size).to.equal(3);
expect(new Namespace({}).size).to.equal(0);
});
it("should ignore non-valid identifiers", () => {
expect(new Namespace({x:10,y:20,$z:30}).size).to.equal(2);
});
});
describe(".image", () => {
it("should return the array of values of the namespace", () => {
const item = new Namespace({k1:1, k2:2, k3:3, $k4:4});
expect(item.image).to.be.deep.equal([1,2,3]);
});
});
describe(".apply(...X)", () => {
it("should return the tuple of values mapped to the arguments", () => {
const item = new Namespace({k1:1, k2:2, k3:3, k4:4, k5:5, k6:6});
expect(item.apply('k2','k4','k6')).to.be.Tuple([2,4,6]);
});
it("should normalize the returned tuple", () => {
const item = new Namespace({k1:1, k2:2, k3:3, k4:4, k5:5, k6:6});
expect(item.apply('k2')).to.be.Numb(2);
});
it("should return Undefined Mapping if the key is not in the Namespace domain", () => {
const item = new Namespace({k1:1, k2:2, k3:3, k4:4, k5:5, k6:6});
expect(item.apply(-1)).to.be.Undefined('Mapping', arg0 => {
expect(arg0).to.equal(-1);
});
const tuple = item.apply('k2', -1, 'k4');
expect(tuple).to.be.instanceof(Tuple);
expect(Array.from(tuple)[0]).to.equal(2);
expect(Array.from(tuple)[1]).to.be.Undefined('Mapping', arg0 => {
expect(arg0).to.equal(-1);
});
expect(Array.from(tuple)[2]).to.equal(4);
});
it("should call the __apply__ item if it is a function", async () => {
const item = new Namespace({__apply__: (x, y) => x + y});
expect(await item.apply(10, 100)).to.be.Numb(110);
});
})
});
describe("Func", () => {
describe(".items()", () => {
it("should yield the item itself", () => {
const item = new Func(x=>x);
expect(item.items()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.items())).to.deep.equal([item]);
});
});
describe(".values()", () => {
it("should yield the item value", () => {
const item = new Func(x=>x);
expect(item.values()[Symbol.iterator]).to.be.a("function");
expect(Array.from(item.values())).to.deep.equal([item.unwrap()]);
});
});
describe("[Symbol.iterator]()", () => {
it("should yield the item value", () => {
const item = new Func(x=>x);
expect(Array.from(item)).to.deep.equal([item.unwrap()]);
});
});
describe(".iterPairs(other)", () => {
it("should yield corresponding pairs of the two terms", () => {
const item1 = new Func(x=>x);
const item2 = new Func(x=>x);
expect(item1.iterPairs(item2)[Symbol.iterator]).to.be.a("function");
const pairs = Array.from(item1.iterPairs(item2));
expect(pairs.length).to.equal(1);
expect(pairs[0][0]).to.equal(item1);
expect(pairs[0][1]).to.equal(item2);
});
});
describe(".imapSync(fn)", () => {
it("should synchronously apply fn to the item and return the wrapped output", () => {
const item = new Func(x=>x);
const fn = item => [item.unwrap()];
expect(item.imapSync(fn)).to.be.List([item.unwrap()]);
});
});
describe(".vmapSync(fn)", () => {
it("should synchronously apply fn to the item value and return the wrapped output", () => {
const item = new Func(x=>x);
const fn = value => [value];
expect(item.vmapSync(fn)).to.be.List([item.unwrap()]);
});
});
describe(".imapAsync(fn)", () => {
it("should asynchronously apply fn to the item and return the wrapped output", async () => {
const item = new Func(x=>x);
const fn = async item => [item.unwrap()];
expect(await item.imapAsync(fn)).to.be.List([item.unwrap()]);
});
});
describe(".vmapAsync(fn)", () => {