summaryrefslogtreecommitdiff
path: root/deps/v8/test/mjsunit/harmony/array-to-sorted.js
blob: d32523a7fa08a63155a0a22ce16f4df39adbb2b8 (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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --harmony-change-array-by-copy

assertEquals(1, Array.prototype.toSorted.length);
assertEquals("toSorted", Array.prototype.toSorted.name);

function TerribleCopy(input, fillHoles) {
  let copy;
  if (Array.isArray(input)) {
    copy = new Array(input.length);
  } else {
    copy = { length: input.length };
  }
  for (let i = 0; i < input.length; ++i) {
    if (i in input) {
      copy[i] = input[i];
    } else if (fillHoles) {
      copy[i] = undefined;
    }
  }
  return copy;
}

function AssertToSortedAndSortSameResult(input, ...args) {
  const orig = TerribleCopy(input, false);
  const s = Array.prototype.toSorted.apply(input, args);
  const copy = TerribleCopy(input, true);
  Array.prototype.sort.apply(copy, args);

  // The in-place sorted version should be pairwise equal to the toSorted,
  // modulo being an actual Array if the input is generic, and holes should
  // be filled with undefined.
  if (Array.isArray(input)) {
    assertEquals(copy, s);
  } else {
    assertEquals(copy.length, s.length);
    for (let i = 0; i < copy.length; i++) {
      assertTrue(i in copy);
      assertTrue(i in s);
      assertEquals(copy[i], s[i]);
    }
  }

  // The original input should be unchanged.
  assertEquals(orig, input);

  // The result of toSorted() is a copy.
  assertFalse(s === input);
}

function TestToSortedBasicBehaviorHelper(input) {
  // No custom comparator.
  AssertToSortedAndSortSameResult(input);
  // Custom comparator.
  AssertToSortedAndSortSameResult(input, (x, y) => {
    if (x < y) return -1;
    if (x > y) return 1;
    return 0;
  });
}

// Smi packed
TestToSortedBasicBehaviorHelper([1,3,2,4]);

// Double packed
TestToSortedBasicBehaviorHelper([1.1,3.3,2.2,4.4]);

// Packed
TestToSortedBasicBehaviorHelper([true,false,1,42.42,null,"foo"]);

// Smi holey
TestToSortedBasicBehaviorHelper([1,,3,,2,,4,,]);

// Double holey
TestToSortedBasicBehaviorHelper([1.1,,3.3,,2.2,,4.4,,]);

// Holey
TestToSortedBasicBehaviorHelper([true,,false,,1,,42.42,,null,,"foo",,]);

// Generic
TestToSortedBasicBehaviorHelper({ length: 4,
                                  get "0"() { return "hello"; },
                                  get "1"() { return "cursed"; },
                                  get "2"() { return "java"; },
                                  get "3"() { return "script" } });

(function TestSnapshotAtBeginning() {
  const a = [1,3,4,2];
  // Use a cursed comparator that mutates the original array. toSorted, like
  // sort, takes a snapshot at the beginning.
  const s = a.toSorted((x, y) => {
    a.pop();
    if (x < y) return -1;
    if (x > y) return 1;
    return 0;
  });
  assertEquals([1,2,3,4], s);
  assertEquals(0, a.length);
})();

(function TestBig() {
  const a = [];
  a[50001] = 42.42;
  a.toSorted();
})();

(function TestTooBig() {
  const a = { length: Math.pow(2, 32) };
  assertThrows(() => Array.prototype.toSorted.call(a), RangeError);
})();

(function TestNoSpecies() {
  class MyArray extends Array {
    static get [Symbol.species]() { return MyArray; }
  }
  assertEquals(Array, (new MyArray()).toSorted().constructor);
})();

// All tests after this have an invalidated elements-on-prototype protector.
(function TestNoHoles() {
  const a = [,,,,];
  Array.prototype[3] = "on proto";
  const s = a.toSorted();
  assertEquals(["on proto",undefined,undefined,undefined], s);
  assertEquals(a.length, s.length)
  for (let i = 0; i < a.length; i++) {
    assertFalse(a.hasOwnProperty(i));
    assertTrue(s.hasOwnProperty(i));
  }
})();

assertEquals(Array.prototype[Symbol.unscopables].toSorted, true);