v8/test/mjsunit/harmony/array-to-reversed.js
Shu-yu Guo 3c4c25dbd4 [change-array-by-copy] Implement Array.prototype.toSpliced
Drive-by: add unscopable test for Array.prototype.toReversed.

Bug: v8:12764
Change-Id: I9d7dd8d4eae6d23811382b6795c2c6ff7f76be72
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3717552
Reviewed-by: Marja Hölttä <marja@chromium.org>
Commit-Queue: Shu-yu Guo <syg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81364}
2022-06-24 22:05:39 +00:00

109 lines
3.2 KiB
JavaScript

// 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(0, Array.prototype.toReversed.length);
assertEquals("toReversed", Array.prototype.toReversed.name);
(function TestSmiPacked() {
let a = [1,2,3,4];
let r = a.toReversed();
assertEquals([1,2,3,4], a);
assertEquals([4,3,2,1], r);
assertFalse(a === r);
})();
(function TestDoublePacked() {
let a = [1.1,2.2,3.3,4.4];
let r = a.toReversed();
assertEquals([1.1,2.2,3.3,4.4], a);
assertEquals([4.4,3.3,2.2,1.1], r);
assertFalse(a === r);
})();
(function TestPacked() {
let a = [true,false,1,42.42];
let r = a.toReversed();
assertEquals([true,false,1,42.42], a);
assertEquals([42.42,1,false,true], r);
assertFalse(a === r);
})();
(function TestGeneric() {
let a = { length: 4,
get "0"() { return "hello"; },
get "1"() { return "cursed"; },
get "2"() { return "java"; },
get "3"() { return "script" } };
let r = Array.prototype.toReversed.call(a);
assertEquals("hello", a[0]);
assertEquals(["script","java","cursed","hello"], r);
assertFalse(a === r);
assertTrue(Array.isArray(r));
assertEquals(Array, r.constructor);
})();
(function TestReadOrder() {
let order = [];
let a = { length: 4,
get "0"() { order.push("4th"); return "4th"; },
get "1"() { order.push("3rd"); return "3rd"; },
get "2"() { order.push("2nd"); return "2nd"; },
get "3"() { order.push("1st"); return "1st"; } };
let r = Array.prototype.toReversed.call(a);
assertEquals(["1st","2nd","3rd","4th"], r);
assertEquals(["1st","2nd","3rd","4th"], order);
})();
(function TestTooBig() {
let a = { length: Math.pow(2, 32) };
assertThrows(() => Array.prototype.toReversed.call(a), RangeError);
})();
(function TestNoSpecies() {
class MyArray extends Array {
static get [Symbol.species]() { return MyArray; }
}
assertEquals(Array, (new MyArray()).toReversed().constructor);
})();
// All tests after this have an invalidated elements-on-prototype protector.
(function TestNoHoles() {
let a = [,,,,];
Array.prototype[3] = "on proto";
let r = a.toReversed();
assertEquals(["on proto",undefined,undefined,undefined], r);
for (let i = 0; i < a.length; i++) {
assertFalse(a.hasOwnProperty(i));
assertTrue(r.hasOwnProperty(i));
}
})();
(function TestMidIterationShenanigans() {
let a = { length: 4,
"0": 1,
get "1"() { a.length = 1; return 2; },
"2": 3,
"3": 4,
__proto__: Array.prototype };
// The length is cached before iteration, so mid-iteration resizing does not
// affect the copied array length.
let r = a.toReversed();
assertEquals(1, a.length);
assertEquals([4,3,2,1], r);
// Values can be changed mid-iteration.
a = { length: 4,
"0": 1,
get "1"() { a[0] = "poof"; return 2; },
"2": 3,
"3": 4,
__proto__: Array.prototype };
r = a.toReversed();
assertEquals([4,3,2,"poof"], r);
})();
assertEquals(Array.prototype[Symbol.unscopables].toReversed, true);