spread-call.js (4196B)
1 load(libdir + "asserts.js"); 2 load(libdir + "eqArrayHelper.js"); 3 load(libdir + "iteration.js"); 4 5 let makeCall = farg => Function("f", "arg", "return f(" + farg + ");"); 6 let makeFunCall = farg => Function("f", "arg", "return f.call(null, " + farg + ");"); 7 let makeNew = farg => Function("f", "arg", "return new f(" + farg + ").value;"); 8 9 function checkCommon(f, makeFn) { 10 assertEqArray(makeFn("...[1, 2, 3]")(f), [1, 2, 3]); 11 assertEqArray(makeFn("1, ...[2], 3")(f), [1, 2, 3]); 12 assertEqArray(makeFn("1, ...[2], ...[3]")(f), [1, 2, 3]); 13 assertEqArray(makeFn("1, ...[2, 3]")(f), [1, 2, 3]); 14 assertEqArray(makeFn("1, ...[], 2, 3")(f), [1, 2, 3]); 15 16 // other iterable objects 17 assertEqArray(makeFn("...arg")(f, new Int32Array([1, 2, 3])), [1, 2, 3]); 18 assertEqArray(makeFn("...arg")(f, "abc"), ["a", "b", "c"]); 19 assertEqArray(makeFn("...arg")(f, [1, 2, 3][Symbol.iterator]()), [1, 2, 3]); 20 assertEqArray(makeFn("...arg")(f, new Set([1, 2, 3])), [1, 2, 3]); 21 assertEqArray(makeFn("...arg")(f, new Map([["a", "A"], ["b", "B"], ["c", "C"]])).map(([k, v]) => k + v), ["aA", "bB", "cC"]); 22 let itr = {}; 23 itr[Symbol.iterator] = function() { 24 return { 25 i: 1, 26 next: function() { 27 if (this.i < 4) 28 return { value: this.i++, done: false }; 29 else 30 return { value: undefined, done: true }; 31 } 32 }; 33 }; 34 assertEqArray(makeFn("...arg")(f, itr), [1, 2, 3]); 35 function* gen() { 36 for (let i = 1; i < 4; i ++) 37 yield i; 38 } 39 assertEqArray(makeFn("...arg")(f, gen()), [1, 2, 3]); 40 41 assertEqArray(makeFn("...arg=[1, 2, 3]")(f), [1, 2, 3]); 42 43 // 12.2.4.1.2 Runtime Semantics: ArrayAccumulation 44 // If Type(spreadObj) is not Object, then throw a TypeError exception. 45 assertThrowsInstanceOf(makeFn("1, ...null, 2, 3"), TypeError); 46 assertThrowsInstanceOf(makeFn("1, ...undefined, 2, 3"), TypeError); 47 } 48 49 function checkNormal(f, makeFn) { 50 checkCommon(f, makeFn); 51 52 assertEqArray(makeFn("...[]")(f), [undefined, undefined, undefined]); 53 assertEqArray(makeFn("...[1]")(f), [1, undefined, undefined]); 54 assertEqArray(makeFn("...[1, 2]")(f), [1, 2, undefined]); 55 assertEqArray(makeFn("...[1, 2, 3, 4]")(f), [1, 2, 3]); 56 57 assertEqArray(makeFn("...[undefined]")(f), [undefined, undefined, undefined]); 58 } 59 60 checkNormal(function(a, b, c) { return [a, b, c]; }, makeCall); 61 checkNormal(function(a, b, c) { return [a, b, c]; }, makeFunCall); 62 checkNormal((a, b, c) => [a, b, c], makeCall); 63 checkNormal((a, b, c) => [a, b, c], makeFunCall); 64 function normalClass(a, b, c) { 65 this.value = [a, b, c]; 66 assertEq(Object.getPrototypeOf(this), normalClass.prototype); 67 } 68 checkNormal(normalClass, makeNew); 69 70 function checkDefault(f, makeFn) { 71 checkCommon(f, makeFn); 72 73 assertEqArray(makeFn("...[]")(f), [-1, -2, -3]); 74 assertEqArray(makeFn("...[1]")(f), [1, -2, -3]); 75 assertEqArray(makeFn("...[1, 2]")(f), [1, 2, -3]); 76 assertEqArray(makeFn("...[1, 2, 3, 4]")(f), [1, 2, 3]); 77 78 assertEqArray(makeFn("...[undefined]")(f), [-1, -2, -3]); 79 } 80 81 checkDefault(function(a = -1, b = -2, c = -3) { return [a, b, c]; }, makeCall); 82 checkDefault(function(a = -1, b = -2, c = -3) { return [a, b, c]; }, makeFunCall); 83 checkDefault((a = -1, b = -2, c = -3) => [a, b, c], makeCall); 84 checkDefault((a = -1, b = -2, c = -3) => [a, b, c], makeFunCall); 85 function defaultClass(a = -1, b = -2, c = -3) { 86 this.value = [a, b, c]; 87 assertEq(Object.getPrototypeOf(this), defaultClass.prototype); 88 } 89 checkDefault(defaultClass, makeNew); 90 91 function checkRest(f, makeFn) { 92 checkCommon(f, makeFn); 93 94 assertEqArray(makeFn("...[]")(f), []); 95 assertEqArray(makeFn("1, ...[2, 3, 4], 5")(f), [1, 2, 3, 4, 5]); 96 assertEqArray(makeFn("1, ...[], 2")(f), [1, 2]); 97 assertEqArray(makeFn("1, ...[2, 3], 4, ...[5, 6]")(f), [1, 2, 3, 4, 5, 6]); 98 99 assertEqArray(makeFn("...[undefined]")(f), [undefined]); 100 } 101 102 checkRest(function(...x) { return x; }, makeCall); 103 checkRest(function(...x) { return x; }, makeFunCall); 104 checkRest((...x) => x, makeCall); 105 checkRest((...x) => x, makeFunCall); 106 function restClass(...x) { 107 this.value = x; 108 assertEq(Object.getPrototypeOf(this), restClass.prototype); 109 } 110 checkRest(restClass, makeNew);