merge.test.js (4519B)
1 var assert = require('assert'); 2 var typed = require('../typed-function'); 3 4 describe('merge', function () { 5 it('should merge two typed-functions', function () { 6 var typed1 = typed({'boolean': function (value) { return 'boolean:' + value; }}); 7 var typed2 = typed({'number': function (value) { return 'number:' + value; }}); 8 9 var typed3 = typed(typed1, typed2); 10 11 assert.deepEqual(Object.keys(typed3.signatures).sort(), ['boolean', 'number']); 12 13 assert.strictEqual(typed3(true), 'boolean:true'); 14 assert.strictEqual(typed3(2), 'number:2'); 15 assert.throws(function () {typed3('foo')}, /TypeError: Unexpected type of argument in function unnamed \(expected: number or boolean, actual: string, index: 0\)/); 16 }); 17 18 it('should merge three typed-functions', function () { 19 var typed1 = typed({'boolean': function (value) { return 'boolean:' + value; }}); 20 var typed2 = typed({'number': function (value) { return 'number:' + value; }}); 21 var typed3 = typed({'string': function (value) { return 'string:' + value; }}); 22 23 var typed4 = typed(typed1, typed2, typed3); 24 25 assert.deepEqual(Object.keys(typed4.signatures).sort(), ['boolean', 'number', 'string']); 26 27 assert.strictEqual(typed4(true), 'boolean:true'); 28 assert.strictEqual(typed4(2), 'number:2'); 29 assert.strictEqual(typed4('foo'), 'string:foo'); 30 assert.throws(function () {typed4(new Date())}, /TypeError: Unexpected type of argument in function unnamed \(expected: number or string or boolean, actual: Date, index: 0\)/); 31 }); 32 33 it('should merge two typed-functions with a custom name', function () { 34 var typed1 = typed('typed1', {'boolean': function (value) { return 'boolean:' + value; }}); 35 var typed2 = typed('typed2', {'number': function (value) { return 'number:' + value; }}); 36 37 var typed3 = typed('typed3', typed1, typed2); 38 39 assert.equal(typed3.name, 'typed3'); 40 }); 41 42 it('should not copy conversions as exact signatures', function () { 43 var typed2 = typed.create(); 44 typed2.conversions = [ 45 {from: 'string', to: 'number', convert: function (x) {return parseFloat(x)}} 46 ]; 47 48 var fn2 = typed2({'number': function (value) { return value }}); 49 50 assert.strictEqual(fn2(2), 2); 51 assert.strictEqual(fn2('123'), 123); 52 53 var fn1 = typed({ 'Date': function (value) {return value} }); 54 var fn3 = typed(fn1, fn2); // create via typed which has no conversions 55 56 var date = new Date() 57 assert.strictEqual(fn3(2), 2); 58 assert.strictEqual(fn3(date), date); 59 assert.throws(function () {fn3('123') }, /TypeError: Unexpected type of argument in function unnamed \(expected: number or Date, actual: string, index: 0\)/); 60 }); 61 62 it('should allow merging duplicate signatures when pointing to the same function', function () { 63 var typed1 = typed({'boolean': function (value) { return 'boolean:' + value; }}); 64 65 var merged = typed(typed1, typed1); 66 67 assert.deepEqual(Object.keys(merged.signatures).sort(), ['boolean']); 68 }); 69 70 it('should throw an error in case of conflicting signatures when merging', function () { 71 var typed1 = typed({'boolean': function (value) { return 'boolean:' + value; }}); 72 var typed2 = typed({'boolean': function (value) { return 'boolean:' + value; }}); 73 74 assert.throws(function () { 75 typed(typed1, typed2) 76 }, /Error: Signature "boolean" is defined twice/); 77 }); 78 79 it('should throw an error in case of conflicting names when merging', function () { 80 var typed1 = typed('fn1', {'boolean': function () {}}); 81 var typed2 = typed('fn2', {'string': function () {}}); 82 var typed3 = typed({'number': function () {}}); 83 84 assert.throws(function () { 85 typed(typed1, typed2) 86 }, /Error: Function names do not match \(expected: fn1, actual: fn2\)/); 87 88 var typed4 = typed(typed2, typed3); 89 assert.equal(typed4.name, 'fn2'); 90 }); 91 92 it('should allow recursive across merged signatures', function () { 93 var fn1 = typed({ 94 '...number': function (values) { 95 var sum = 0; 96 for (var i = 0; i < values.length; i++) { 97 sum += values[i]; 98 } 99 return sum; 100 } 101 }); 102 103 var fn2 = typed({ 104 '...string': function (values) { 105 var newValues = []; 106 for (var i = 0; i < values.length; i++) { 107 newValues[i] = parseInt(values[i], 10); 108 } 109 return this.apply(null, newValues); 110 } 111 }); 112 113 var fn3 = typed(fn1, fn2); 114 115 assert.equal(fn3('1', '2', '3'), '6'); 116 assert.equal(fn3(1, 2, 3), 6); 117 }) 118 });