summaryrefslogtreecommitdiffstats
path: root/js/src/tests/non262/Array/toSpliced-dense.js
blob: 1108f1b5f8ada8fc8e3e6b689290e3845b4d1d2e (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
// |reftest| shell-option(--enable-change-array-by-copy) skip-if(!Array.prototype.toSpliced)

const startIndices = [
  -10, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 10,
];

const deleteCounts = [
  0, 1, 2, 3, 4, 5, 10,
];

const insertCounts = [
  0, 1, 2, 3, 4, 5, 10,
];

const itemsList = insertCounts.map(count => {
  return new Array(count).fill(0);
});

const arrays = [
  // Dense no holes.
  [],
  [1],
  [1,2],
  [1,2,3],
  [1,2,3,4],
  [1,2,3,4,5,6,7,8],

  // Dense trailing holes.
  [,],
  [1,,],
  [1,2,,],
  [1,2,3,,],
  [1,2,3,4,,],
  [1,2,3,4,5,6,7,8,,],

  // Dense leading holes.
  [,],
  [,1],
  [,1,2],
  [,1,2,3],
  [,1,2,3,4],
  [,1,2,3,4,5,6,7,8],

  // Dense with holes.
  [1,,3],
  [1,2,,4],
  [1,,3,,5,6,,8],
];

const objects = arrays.map(array => {
  let obj = {
    length: array.length,
  };
  for (let i = 0; i < array.length; ++i) {
    if (i in array) {
      obj[i] = array[i];
    }
  }
  return obj;
});

const objectsWithLargerDenseInitializedLength = arrays.map(array => {
  let obj = {
    length: array.length,
  };
  for (let i = 0; i < array.length; ++i) {
    if (i in array) {
      obj[i] = array[i];
    }
  }

  // Add some extra dense elements after |length|.
  for (let i = 0; i < 5; ++i) {
    obj[array.length + i] = "extra";
  }

  return obj;
});

const thisValues = [
  ...arrays,
  ...objects,
  ...objectsWithLargerDenseInitializedLength,
];

for (let thisValue of thisValues) {
  for (let startIndex of startIndices) {
    for (let deleteCount of deleteCounts) {
      for (let items of itemsList) {
        let res = Array.prototype.toSpliced.call(thisValue, startIndex, deleteCount, ...items);

        // Array.prototype.toSpliced(), steps 3-6.
        let actualStart;
        if (startIndex < 0) {
          actualStart = Math.max(thisValue.length + startIndex, 0);
        } else {
          actualStart = Math.min(startIndex, thisValue.length);
        }

        // Array.prototype.toSpliced(), step 10.
        let actualDeleteCount = Math.min(Math.max(0, deleteCount), thisValue.length - actualStart);

        let newLength = thisValue.length + items.length - actualDeleteCount;
        assertEq(res.length, newLength);

        for (let i = 0; i < actualStart; ++i) {
          assertEq(Object.hasOwn(res, i), true);
          assertEq(res[i], thisValue[i]);
        }

        for (let i = 0; i < items.length; ++i) {
          assertEq(Object.hasOwn(res, actualStart + i), true);
          assertEq(res[actualStart + i], items[i]);
        }

        for (let i = 0; i < newLength - actualStart - items.length; ++i) {
          assertEq(Object.hasOwn(res, actualStart + items.length + i), true);
          assertEq(res[actualStart + items.length + i],
                   thisValue[actualStart + actualDeleteCount + i]);
        }
      }
    }
  }
}

if (typeof reportCompare === "function")
  reportCompare(0, 0);