spread-call-length.js (1786B)
1 load(libdir + 'iteration.js'); 2 3 let makeCall = farg => Function("f", "arg", "return f(" + farg + ");"); 4 let makeFunCall = farg => Function("f", "arg", "return f.call(null, " + farg + ");"); 5 let makeNew = farg => Function("f", "arg", "return new f(" + farg + ").length;"); 6 7 function checkLength(f, makeFn) { 8 assertEq(makeFn("...[1, 2, 3]")(f), 3); 9 assertEq(makeFn("1, ...[2], 3")(f), 3); 10 assertEq(makeFn("1, ...[2], ...[3]")(f), 3); 11 assertEq(makeFn("1, ...[2, 3]")(f), 3); 12 assertEq(makeFn("1, ...[], 2, 3")(f), 3); 13 14 assertEq(makeFn("...[1]")(f), 1); 15 assertEq(makeFn("...[1, 2]")(f), 2); 16 assertEq(makeFn("...[1, 2, 3, 4]")(f), 4); 17 assertEq(makeFn("1, ...[2, 3, 4], 5")(f), 5); 18 19 assertEq(makeFn("...[undefined]")(f), 1); 20 21 // other iterable objects 22 assertEq(makeFn("...arg")(f, new Int32Array([1, 2, 3])), 3); 23 assertEq(makeFn("...arg")(f, "abc"), 3); 24 assertEq(makeFn("...arg")(f, [1, 2, 3][Symbol.iterator]()), 3); 25 assertEq(makeFn("...arg")(f, new Set([1, 2, 3])), 3); 26 assertEq(makeFn("...arg")(f, new Map([["a", "A"], ["b", "B"], ["c", "C"]])), 3); 27 let itr = {}; 28 itr[Symbol.iterator] = function() { 29 return { 30 i: 1, 31 next: function() { 32 if (this.i < 4) 33 return { value: this.i++, done: false }; 34 else 35 return { value: undefined, done: true }; 36 } 37 }; 38 } 39 assertEq(makeFn("...arg")(f, itr), 3); 40 function* gen() { 41 for (let i = 1; i < 4; i ++) 42 yield i; 43 } 44 assertEq(makeFn("...arg")(f, gen()), 3); 45 } 46 47 checkLength(function(x) { return arguments.length; }, makeCall); 48 checkLength(function(x) { return arguments.length; }, makeFunCall); 49 function lengthClass(x) { 50 this.length = arguments.length; 51 } 52 checkLength(lengthClass, makeNew);