summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/Tuple/prototype/flat
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--js/src/tests/non262/Tuple/prototype/flat/empty-tuple-elements.js8
-rw-r--r--js/src/tests/non262/Tuple/prototype/flat/flat.js96
-rw-r--r--js/src/tests/non262/Tuple/prototype/flat/indexed-setters.js16
-rw-r--r--js/src/tests/non262/Tuple/prototype/flat/length.js27
-rw-r--r--js/src/tests/non262/Tuple/prototype/flat/undefined-elements.js10
-rw-r--r--js/src/tests/non262/Tuple/prototype/flatMap/depth-always-one.js16
-rw-r--r--js/src/tests/non262/Tuple/prototype/flatMap/flatMap.js114
-rw-r--r--js/src/tests/non262/Tuple/prototype/flatMap/length.js27
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);