summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/Tuple/prototype/flat/flat.js
blob: 93748f9c36825f3ee693156a247ca8b07c815aba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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);