diff options
Diffstat (limited to '')
8 files changed, 314 insertions, 0 deletions
diff --git a/js/src/tests/non262/Tuple/prototype/flat/empty-tuple-elements.js b/js/src/tests/non262/Tuple/prototype/flat/empty-tuple-elements.js new file mode 100644 index 0000000000..e8acef7b43 --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flat/empty-tuple-elements.js @@ -0,0 +1,8 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +var t = #[]; +assertEq(#[].flat(), #[]); +assertEq(#[#[],#[]].flat(), #[]); +assertEq(#[#[], #[1]].flat(), #[1]); +assertEq(#[#[], #[1, t]].flat(), #[1, t]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/Tuple/prototype/flat/flat.js b/js/src/tests/non262/Tuple/prototype/flat/flat.js new file mode 100644 index 0000000000..93748f9c36 --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flat/flat.js @@ -0,0 +1,96 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +/* +8.2.3.16 Tuple.prototype.flat ( [ depth ] ) +When the flat method is called with zero or one arguments, the following steps are taken: + +1. Let T be ? thisTupleValue(this value). +2. Let list be T.[[Sequence]]. +3. Let depthNum be 1. +4. If depth is not undefined, then +a. Set depthNum to ? ToInteger(depth). +5. Let flat be a new empty List. +6. Perform ? FlattenIntoTuple(flat, list, depthNum). +7. Return a new Tuple value whose [[Sequence]] is flat. + +8.2.3.16.1 FlattenIntoTuple ( target, source, depth [ , mapperFunction, thisArg ] ) +The abstract operation FlattenIntoTuple takes arguments target, source, and depth and optional arguments mapperFunction and thisArg. It performs the following steps when called: + +1. Assert: target is a List. +2. Assert: source is a List. +3. Assert: ! IsInteger(depth) is true, or depth is either +∞ or -∞. +4. Assert: If mapperFunction is present, then ! IsCallable(mapperFunction) is true, thisArg is present, and depth is 1. +5. Let sourceIndex be 0. +6. For each element of source, +a. If mapperFunction is present, then +i. Set element to ? Call(mapperFunction, thisArg, « element, sourceIndex, source »). +ii. If Type(element) is Object, throw a TypeError exception. +b. If depth > 0 and Type(element) is Tuple, then +i. Perform ? FlattenIntoTuple(target, element, depth - 1). +c. Else, +i. Let len be the length of target. +ii. If len ≥ 253 - 1, throw a TypeError exception. +iii. Append element to target. +d. Set sourceIndex to sourceIndex + 1. + +*/ +/* Step 1 */ +/* flat() should throw on a non-Tuple */ +let method = Tuple.prototype.flat; +assertEq(method.call(#[1,#[2],3]), #[1,2,3]); +assertEq(method.call(Object(#[1,#[2],3])), #[1,2,3]); +assertThrowsInstanceOf(() => method.call("monkeys"), TypeError, + "value of TupleObject must be a Tuple"); +assertThrowsInstanceOf(() => method.call(null), TypeError, + "value of TupleObject must be a Tuple"); +assertThrowsInstanceOf(() => method.call(), TypeError, + "value of TupleObject must be a Tuple"); + + +let tup = #[1,2,#[3,#[4,5],6],#[5,6],7]; +let tup2 = #[1,2,#[3,#[4,#["a", "b"], 5],6],#[5,#[6,#[7,8,#[9,10]]]],7]; + +/* Step 3 -- depth is converted to Integer */ +assertEq(tup.flat("monkeys"), tup.flat(0)); +assertEq(tup.flat({}), tup.flat(0)); +assertEq(tup.flat(+0), tup.flat(0)); +assertEq(tup.flat(-0), tup.flat(0)); +assertEq(tup.flat('2'), tup.flat(2)); +assertEq(tup.flat(true), tup.flat(1)); +assertEq(tup.flat(false), tup.flat(0)); +assertEq(tup.flat(null), tup.flat(0)); +assertEq(tup.flat(NaN), tup.flat(0)); +assertEq(tup.flat([1,2,3]), tup.flat(0)); +assertThrowsInstanceOf(() => tup.flat(Symbol("x")), TypeError, + "can't convert symbol to number"); +assertThrowsInstanceOf(() => tup.flat(Object.create(null)), TypeError, + "can't convert Object to number"); +assertThrowsInstanceOf(() => tup.flat(#[1]), TypeError, + "can't convert Tuple to number"); + + +/* Step 3 -- if depth is undefined, depthNum is set to 1 */ +assertEq(tup.flat(undefined), tup.flat(1)); +assertEq(tup.flat(), tup.flat(1)); + +/* Step 7 */ +assertEq(#[].flat(), #[]); +assertEq(#[1].flat(), #[1]); +assertEq(#[#[1,2],#[3,4]].flat(), #[1,2,3,4]); +assertEq(tup.flat(0), tup); +assertEq(tup.flat(1), #[1,2,3,#[4,5],6,5,6,7]); +assertEq(tup.flat(2), #[1,2,3,4,5,6,5,6,7]); +assertEq(tup.flat(3), tup.flat(2)); +assertEq(tup2.flat(0), tup2); +assertEq(tup2.flat(1), #[1,2,3,#[4,#["a", "b"], 5],6,5,#[6,#[7,8,#[9,10]]],7]); +assertEq(tup2.flat(2), #[1,2,3,4,#["a", "b"],5,6,5,6,#[7, 8, #[9, 10]],7]); +assertEq(tup2.flat(3), #[1,2,3,4,"a","b",5,6,5,6, 7, 8, #[9, 10], 7]); +assertEq(tup2.flat(4), #[1,2,3,4,"a","b",5,6,5,6, 7, 8, 9, 10, 7]); + +/* FlattenIntoTuple steps: */ +/* Step 3: depth can be Infinity or -Infinity */ +assertEq(tup2.flat(Infinity), tup2.flat(4)); +assertEq(tup2.flat(-Infinity), tup2.flat(0)); + +/* Step 6.c.ii. -- throw if len would be > n^253 - 1 -- not sure how to test this */ + +reportCompare(0, 0); diff --git a/js/src/tests/non262/Tuple/prototype/flat/indexed-setters.js b/js/src/tests/non262/Tuple/prototype/flat/indexed-setters.js new file mode 100644 index 0000000000..26b77e03fd --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flat/indexed-setters.js @@ -0,0 +1,16 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) + +// If an indexed Array setter is overridden, TupleSplice shouldn't use it +// when constructing the intermediate array + +var z = 5; +print("1111"); +Object.defineProperty(Array.prototype, '0', { set: function(y) { z = 42; }}); +print("2222"); +let newT = #[#[1],#[2,3]].flat(); +print("3333"); +assertEq(z, 5); +print("4444"); + +reportCompare(0, 0); + diff --git a/js/src/tests/non262/Tuple/prototype/flat/length.js b/js/src/tests/non262/Tuple/prototype/flat/length.js new file mode 100644 index 0000000000..8bbbea0ae9 --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flat/length.js @@ -0,0 +1,27 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +var desc = Object.getOwnPropertyDescriptor(Tuple.prototype.flat, "length"); +assertEq(desc.value, 0); +assertEq(desc.writable, false); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + + +desc = Object.getOwnPropertyDescriptor(Tuple.prototype.flat, "name"); +assertEq(desc.value, "flat"); +assertEq(desc.writable, false); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + +desc = Object.getOwnPropertyDescriptor(Tuple.prototype, "flat"); +assertEq(desc.writable, true); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + +assertEq(isConstructor(Tuple.prototype.flat), false); + +assertThrowsInstanceOf(() => { + let t = #[1]; + new t.flat(); +}, TypeError, '`let t = #[1]; new t.flat()` throws TypeError'); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/Tuple/prototype/flat/undefined-elements.js b/js/src/tests/non262/Tuple/prototype/flat/undefined-elements.js new file mode 100644 index 0000000000..4a705167f5 --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flat/undefined-elements.js @@ -0,0 +1,10 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +var t = #[void 0]; + +assertEq(#[1, null, void 0].flat(), #[1, null, undefined]); +assertEq(#[1, #[null, void 0]].flat(), #[1, null, undefined]); +assertEq(#[#[null, void 0], #[null, void 0]].flat(), #[null, undefined, null, undefined]); +assertEq(#[1, #[null, t]].flat(1), #[1, null, t]); +assertEq(#[1, #[null, t]].flat(2), #[1, null, undefined]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/Tuple/prototype/flatMap/depth-always-one.js b/js/src/tests/non262/Tuple/prototype/flatMap/depth-always-one.js new file mode 100644 index 0000000000..2f3aed6e32 --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flatMap/depth-always-one.js @@ -0,0 +1,16 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +assertEq(#[1, 2].flatMap(function(e) { + return #[e, e * 2]; +}), #[1, 2, 2, 4]); + +var result = #[1, 2, 3].flatMap(function(ele) { + return #[ + #[ele * 2] + ]; +}); +assertEq(result.length, 3); +assertEq(result[0], #[2]); +assertEq(result[1] ,#[4]); +assertEq(result[2], #[6]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/Tuple/prototype/flatMap/flatMap.js b/js/src/tests/non262/Tuple/prototype/flatMap/flatMap.js new file mode 100644 index 0000000000..0fde7014a8 --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flatMap/flatMap.js @@ -0,0 +1,114 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +/* +8.2.3.17 Tuple.prototype.flatMap ( mapperFunction [ , thisArg ] ) +When the flatMap method is called with one or two arguments, the following steps are taken: + +1. Let T be ? thisTupleValue(this value). +2. Let list be T.[[Sequence]]. +3. If ! IsCallable(mapperFunction) is false, throw a TypeError exception. +4. Let flat be a new empty List. +5. Perform ? FlattenIntoTuple(flat, list, 1, mapperFunction, thisArg). +6. Return a new Tuple value whose [[Sequence]] is flat. + +8.2.3.16.1 FlattenIntoTuple ( target, source, depth [ , mapperFunction, thisArg ] ) +The abstract operation FlattenIntoTuple takes arguments target, source, and depth and optional arguments mapperFunction and thisArg. It performs the following steps when called: + +1. Assert: target is a List. +2. Assert: source is a List. +3. Assert: ! IsInteger(depth) is true, or depth is either +∞ or -∞. +4. Assert: If mapperFunction is present, then ! IsCallable(mapperFunction) is true, thisArg is present, and depth is 1. +5. Let sourceIndex be 0. +6. For each element of source, +a. If mapperFunction is present, then +i. Set element to ? Call(mapperFunction, thisArg, « element, sourceIndex, source »). +ii. If Type(element) is Object, throw a TypeError exception. +b. If depth > 0 and Type(element) is Tuple, then +i. Perform ? FlattenIntoTuple(target, element, depth - 1). +c. Else, +i. Let len be the length of target. +ii. If len ≥ 253 - 1, throw a TypeError exception. +iii. Append element to target. +d. Set sourceIndex to sourceIndex + 1. + */ + +/* Step 1 */ +/* flatMap() should throw on a non-Tuple */ +let method = Tuple.prototype.flatMap; +let id = x => x; +assertEq(method.call(#[1,#[2],3], id), #[1,2,3]); +assertEq(method.call(Object(#[1,#[2],3]), id), #[1,2,3]); +assertThrowsInstanceOf(() => method.call("monkeys", id), TypeError, + "value of TupleObject must be a Tuple"); +assertThrowsInstanceOf(() => method.call(null, id), TypeError, + "value of TupleObject must be a Tuple"); +assertThrowsInstanceOf(() => method.call(id), TypeError, + "value of TupleObject must be a Tuple"); + + +let tup = #[1,2,#[3,#[4,5],6],#[5,6],7]; +let tup2 = #[1, #[2], 3]; + +/* Step 4 */ +/* callbackfn not callable -- should throw */ +assertThrowsInstanceOf(() => tup.flatMap(), TypeError, + "missing function argument to Tuple.prototype.flatMap"); +assertThrowsInstanceOf(() => tup.flatMap(undefined), TypeError, + "missing function argument to Tuple.prototype.flatMap"); +assertThrowsInstanceOf(() => tup.flatMap("monkeys"), TypeError, + "bad function argument to Tuple.prototype.flatMap"); + + +/* callbackfn with 1 argument -- should be allowed */ +var f2 = function(x) { + if (typeof(x) === "number") { + return(x * x); + } else { + return 0; + } +}; +assertEq(tup2.flatMap(f2), #[1, 0, 9]); + +/* callbackfn with 2 arguments -- should be allowed */ +f2 = function(x, i) { + if (typeof(x) === "number") { + return(x + i); + } else { + return(i); + } +}; +assertEq(tup2.flatMap(f2), #[1, 1, 5]); + +/* callbackfn with > 3 arguments -- subsequent ones will be undefined */ +var f3 = (a, b, c, d, e) => e === undefined; +assertEq(tup2.flatMap(f3), #[true, true, true]); + +/* callbackfn should be able to use index and tuple */ +var f4 = function (x, i, tup) { + if (typeof(x) === "number") { + return(tup.indexOf(x+1) * i * x); + } else { + return(tup.indexOf(x) * i); + } +} +assertEq(tup2.flatMap(f4), #[-0, 1, -6]); + +/* explicit thisArg */ +f1 = function (x, i, tup) { + if (typeof(x) == "number") { + return(this.elements.indexOf(x) * x); + } else { + return(this.elements.indexOf(x)); + } +} +assertEq(#[1,2,#[3,4],#[5]].flatMap(f1, { elements: [2, 4] }), #[-1, 0, -1, -1]); + +/* FlattenIntoTuple steps */ +/* Step 6.a.ii. */ +var badF = x => new Object(x); +assertThrowsInstanceOf(() => tup.flatMap(badF), TypeError, + "Tuple cannot contain Object"); +/* Step 6.b.i. */ +var f = x => #[x, x]; +assertEq(#[1,#[2,3],4].flatMap(f), #[1,1,#[2,3],#[2,3],4,4]); + +reportCompare(0, 0); diff --git a/js/src/tests/non262/Tuple/prototype/flatMap/length.js b/js/src/tests/non262/Tuple/prototype/flatMap/length.js new file mode 100644 index 0000000000..4e6f5eb0ab --- /dev/null +++ b/js/src/tests/non262/Tuple/prototype/flatMap/length.js @@ -0,0 +1,27 @@ +// |reftest| skip-if(!this.hasOwnProperty("Tuple")) +var desc = Object.getOwnPropertyDescriptor(Tuple.prototype.flatMap, "length"); +assertEq(desc.value, 1); +assertEq(desc.writable, false); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + + +desc = Object.getOwnPropertyDescriptor(Tuple.prototype.flatMap, "name"); +assertEq(desc.value, "flatMap"); +assertEq(desc.writable, false); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + +desc = Object.getOwnPropertyDescriptor(Tuple.prototype, "flatMap"); +assertEq(desc.writable, true); +assertEq(desc.enumerable, false); +assertEq(desc.configurable, true); + +assertEq(isConstructor(Tuple.prototype.flatMap), false); + +assertThrowsInstanceOf(() => { + let t = #[1]; + new t.flatMap(); +}, TypeError, '`let t = #[1]; new t.flatMap()` throws TypeError'); + +reportCompare(0, 0); |