406b5587 |
import * as uut from './genfuns';
import * as e from './genfuns';
|
94944213 |
|
406b5587 |
describe('matches_specializer', () => {
|
94944213 |
test('works in expected cases', () => {
|
406b5587 |
function AThing() { }
const an_instance = new AThing();
|
94944213 |
|
406b5587 |
expect(uut.matches_specializer(an_instance, AThing)).toBeTruthy();
expect(uut.matches_specializer(an_instance, String)).toBeFalsy();
expect(uut.matches_specializer(an_instance, Object)).toBeTruthy();
|
94944213 |
|
406b5587 |
expect(uut.matches_specializer([], Array)).toBeTruthy();
expect(uut.matches_specializer([], Object)).toBeTruthy();
expect(uut.matches_specializer([], Number)).toBeFalsy();
|
94944213 |
function Foo() {}
Foo.prototype = Object.create(null);
const inst = new Foo();
|
406b5587 |
expect(uut.matches_specializer(inst, Foo)).toBeTruthy();
expect(uut.matches_specializer(inst, Object)).toBeFalsy();
expect(uut.matches_specializer({a:1}, uut.Shape('a'))).toBeTruthy();
expect(uut.matches_specializer({a:1, b:2}, uut.Shape('a'))).toBeTruthy();
expect(uut.matches_specializer({b:2}, uut.Shape('a'))).toBeFalsy();
expect(uut.matches_specializer({a:1, b:2, c:3}, uut.Shape('a', 'b', 'c'))).toBeTruthy();
expect(uut.matches_specializer({a:1, b:2, c:3, d:4}, uut.Shape('a', 'b', 'c'))).toBeTruthy();
expect(uut.matches_specializer({a:1, c:3}, uut.Shape('a', 'b', 'c'))).toBeFalsy();
expect(uut.matches_specializer({c:3}, uut.Shape('a', 'b', 'c'))).toBeFalsy();
expect(uut.matches_specializer({d:3}, uut.Shape('a', 'b', 'c'))).toBeFalsy();
|
94944213 |
});
|
406b5587 |
test('null behavior', () => {
expect(uut.matches_specializer(null, null)).toBeTruthy();
expect(uut.matches_specializer(null, Number)).toBeFalsy();
expect(uut.matches_specializer(null, String)).toBeFalsy();
expect(uut.matches_specializer(null, Object)).toBeFalsy();
});
|
94944213 |
|
406b5587 |
test('undefined (the value) behavior', () => {
expect(uut.matches_specializer(undefined, undefined)).toBeTruthy();
expect(uut.matches_specializer(undefined, Number)).toBeFalsy();
expect(uut.matches_specializer(undefined, String)).toBeFalsy();
expect(uut.matches_specializer(undefined, Object)).toBeFalsy();
});
|
94944213 |
|
406b5587 |
test('works for numbers', () => {
expect(uut.matches_specializer(new Number(1), Number)).toBeTruthy();
expect(uut.matches_specializer(new Number(1), Object)).toBeTruthy();
expect(uut.matches_specializer(new Number(1), String)).toBeFalsy();
|
94944213 |
|
406b5587 |
expect(uut.matches_specializer(1, Number)).toBeTruthy();
expect(uut.matches_specializer(1, Object)).toBeTruthy();
expect(uut.matches_specializer(1, String)).toBeFalsy();
|
94944213 |
});
|
406b5587 |
test('handles strings', () => {
expect(uut.matches_specializer(new String("foobar"), String)).toBeTruthy();
expect(uut.matches_specializer(new String("foobar"), Object)).toBeTruthy();
expect(uut.matches_specializer("1", String)).toBeTruthy();
expect(uut.matches_specializer("1", Object)).toBeTruthy();
expect(uut.matches_specializer("1", Number)).toBeFalsy();
})
|
94944213 |
});
describe('defgeneric', () => {
test('methods get called appropriately', () => {
expect(
uut.defgeneric("testing1", "a", "b")
.primary([Object, Object], (_, __) => 1)
.fn(1,2)
).toEqual(1);
|
406b5587 |
expect(() => {
uut.defgeneric("foobar", "a")
.primary([String], function (a) {})
.fn({})
}).toThrow(e.NoApplicableMethodError);
|
94944213 |
expect(
uut.defgeneric("testing1", "a", "b")
.primary([Number, Number], (_, __) => 1)
.fn(1,2)
).toEqual(1);
expect(
uut.defgeneric("testing1", "a", "b")
.primary([Number, Number], (_, __) => 2)
.primary([String, String], (_, __) => 1)
.fn("1","2")
).toEqual(1);
let firstCounts = 0;
expect(
uut.defgeneric("testing1", "a", "b")
.primary([Number, Number], (_, __) => firstCounts += 1)
.primary([String, String], (_, __) => firstCounts += 1)
.fn("1","2")
).toEqual(1);
expect(firstCounts).toEqual(1);
let secondCounts = 0;
expect(
uut.defgeneric("testing1", "a", "b")
.primary([Object, Object], (_, __) => secondCounts += 1)
.primary([String, String], (_, __) => secondCounts += 1)
.fn("1","2")
).toEqual(1);
expect(secondCounts).toEqual(1);
let thirdCounts = 0;
expect(
uut.defgeneric("testing1", "a", "b")
.before([Object, Object], (_, __) => thirdCounts += 1)
.primary([String, String], (_, __) => 'hi')
.after([Object, String], (_, __) => thirdCounts += 1)
.fn("1","2")
).toEqual('hi');
expect(thirdCounts).toEqual(2);
|
406b5587 |
expect(
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
return 1
})
.primary([String], function (a) {
return 2
})
.fn("foobar"))
.toEqual(2);
});
test('next-method-p works', () => {
expect.assertions(3);
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
expect(this.next_method_p).toBe(false);
})
.fn({});
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
expect(this.next_method_p).toBe(false);
})
.primary([String], function (a) {
expect(this.next_method_p).toBe(true);
})
.fn("foobar");
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
expect(this.next_method_p).toBe(false);
})
.primary([String], function (a) {
expect(this.next_method_p).toBe(true);
})
.fn(1);
});
test('call-next-method works', () => {
expect(() => {
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
this.call_next_method();
})
.fn({});
}).toThrow(e.NoNextMethodError);
expect(() => {
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
this.call_next_method();
})
.primary([String], function (a) {
return 1;
})
.fn({});
});
expect(
uut.defgeneric("foobar", "a")
.primary([Object], function (a) {
return 1;
})
.primary([String], function (a) {
return this.call_next_method();
})
.fn("foobar")
).toEqual(1);
expect(
uut.defgeneric("foobar", "a", "b")
.primary ([String, String], function (a,b) {
return `1${this.call_next_method()}`;
})
.primary ([Object, String], function (a,b) {
return `3${this.call_next_method()}`;
})
.primary ([String, Object], function (a,b) {
return `2${this.call_next_method()}`;
})
.primary ([Object, Object], function (a,b) {
return `4`;
}).fn("a", "b")
).toEqual("1234");
});
});
describe('custom specializers', () => {
test('Shape works', () => {
expect(uut.defgeneric("foobar", "a")
.primary([uut.Shape('a', 'b')], ({a,b}) => a+b)
.primary([Object], _ => null)
.fn({a:1,b:2}))
.toEqual(3);
expect(uut.defgeneric("foobar", "a")
.primary([uut.Shape('a', 'b')], ({a,b}) => a+b)
.primary([Object], _ => null)
.fn({a:1,b:2,c:3}))
.toEqual(3);
expect(uut.defgeneric("foobar", "a")
.primary([uut.Shape('a', 'b')], ({a,b}) => a+b)
.primary([Object], _ => null)
.fn({a:1}))
.toEqual(null);
});
test('Shape, prototype precedence', () => {
expect(uut.defgeneric("foobar4", "a")
.primary([uut.Shape('a')], ({a}) => a)
.primary([uut.Shape('a', 'b')], ({a,b}) => {return a+b})
.primary([Object], _ => null).fn({a:1,b:3}))
.toEqual(4);
expect(uut.defgeneric("foobar", "a")
.primary([uut.Shape('a', 'b')], ({a,b}) => a+b)
.primary([uut.Shape('b')], ({b}) => b)
.primary([Object], _ => null)
.fn({a:1,b:2}))
.toEqual(3);
const Foo = function () {}
Foo.prototype = {a: true, b: null};
expect(uut.defgeneric("foobar", "a")
.primary([uut.Shape('a')], function ({a}) { return 'a'; })
.primary([uut.Shape('a', 'b', 'c')], function ({a,b,c}) { return `c${this.call_next_method()}`; })
.primary([uut.Shape('a', 'b')], function ({a,b}) { return `b${this.call_next_method()}`; })
.primary([Object], _ => null)
.fn(Object.assign(new Foo(), {c: 3})))
.toEqual('cba');
});
});
|
94944213 |
|
406b5587 |
describe("Shape", () => {
test('super_of', () => {
expect(uut.Shape().super_of(uut.Shape("a", "b", "c"))).toBeTruthy();
expect(uut.Shape('a').super_of(uut.Shape('a', 'b'))).toBeTruthy();
expect(uut.Shape("a", "b").super_of(uut.Shape("a", "b", "c"))).toBeTruthy();
expect(uut.Shape("a", "b").super_of(uut.Shape("a", "b"))).toBeFalsy();
expect(uut.Shape("a", "b").super_of(uut.Shape("a"))).toBeFalsy();
|
94944213 |
});
});
|