Index: test/mjsunit/harmony/array-copywithin.js |
diff --git a/test/mjsunit/harmony/array-copywithin.js b/test/mjsunit/harmony/array-copywithin.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..c3a0c14663bf29113d463577d565157ef0cdb415 |
--- /dev/null |
+++ b/test/mjsunit/harmony/array-copywithin.js |
@@ -0,0 +1,338 @@ |
+// Copyright 2014 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-arrays |
+ |
+(function copyWithinArity() { |
+ assertEquals(Array.prototype.copyWithin.length, 2); |
+})(); |
+ |
+ |
+(function copyWithinTargetAndStart() { |
+ // works with two arguemnts |
+ assertArrayEquals([4, 5, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, 3)); |
+ assertArrayEquals([1, 4, 5, 4, 5], [1, 2, 3, 4, 5].copyWithin(1, 3)); |
+ assertArrayEquals([1, 3, 4, 5, 5], [1, 2, 3, 4, 5].copyWithin(1, 2)); |
+ assertArrayEquals([1, 2, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(2, 2)); |
+})(); |
+ |
+ |
+(function copyWithinTargetStartAndEnd() { |
+ // works with three arguments |
+ assertArrayEquals([1, 2, 3, 4, 5].copyWithin(0, 3, 4), [4, 2, 3, 4, 5]); |
+ assertArrayEquals([1, 2, 3, 4, 5].copyWithin(1, 3, 4), [1, 4, 3, 4, 5]); |
+ assertArrayEquals([1, 2, 3, 4, 5].copyWithin(1, 2, 4), [1, 3, 4, 4, 5]); |
+})(); |
+ |
+ |
+(function copyWithinNegativeRelativeOffsets() { |
+ // works with negative arguments |
+ assertArrayEquals([4, 5, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, -2)); |
+ assertArrayEquals([4, 2, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, -2, -1)); |
+ assertArrayEquals([1, 3, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(-4, -3, -2)); |
+ assertArrayEquals([1, 3, 4, 4, 5], [1, 2, 3, 4, 5].copyWithin(-4, -3, -1)); |
+ assertArrayEquals([1, 3, 4, 5, 5], [1, 2, 3, 4, 5].copyWithin(-4, -3)); |
+ // test with arguments equal to -this.length |
+ assertArrayEquals([1, 2, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(-5, 0)); |
+})(); |
+ |
+ |
+(function copyWithinArrayLikeValues() { |
+ // works with array-like values |
+ var args = (function () { return arguments; }(1, 2, 3)); |
+ Array.prototype.copyWithin.call(args, -2, 0); |
+ assertArrayEquals([1, 1, 2], Array.prototype.slice.call(args)); |
+ |
+ // [[Class]] does not change |
+ assertArrayEquals("[object Arguments]", Object.prototype.toString.call(args)); |
+})(); |
+ |
+ |
+(function copyWithinNullThis() { |
+ // throws on null/undefined values |
+ assertThrows(function() { |
+ return Array.prototype.copyWithin.call(null, 0, 3); |
+ }, TypeError); |
+})(); |
+ |
+ |
+(function copyWithinUndefinedThis() { |
+ assertThrows(function() { |
+ return Array.prototype.copyWithin.call(undefined, 0, 3); |
+ }, TypeError); |
+})(); |
+ |
+ |
+// TODO(caitp): indexed properties of String are read-only and setting them |
+// should throw in strict mode. See bug v8:4042 |
+// (function copyWithinStringThis() { |
+// // test with this value as string |
+// assertThrows(function() { |
+// return Array.prototype.copyWithin.call("hello world", 0, 3); |
+// }, TypeError); |
+// })(); |
+ |
+ |
+(function copyWithinNumberThis() { |
+ // test with this value as number |
+ assertEquals(34, Array.prototype.copyWithin.call(34, 0, 3).valueOf()); |
+})(); |
+ |
+ |
+(function copyWithinSymbolThis() { |
+ // test with this value as number |
+ var sym = Symbol("test"); |
+ assertEquals(sym, Array.prototype.copyWithin.call(sym, 0, 3).valueOf()); |
+})(); |
+ |
+ |
+(function copyyWithinTypedArray() { |
+ // test with this value as TypedArray |
+ var buffer = new ArrayBuffer(16); |
+ var int32View = new Int32Array(buffer); |
+ for (var i=0; i<int32View.length; i++) { |
+ int32View[i] = i*2; |
+ } |
+ assertArrayEquals(new Int32Array([2, 4, 6, 6]), |
+ Array.prototype.copyWithin.call(int32View, 0, 1)); |
+})(); |
+ |
+ |
+(function copyWithinSloppyArguments() { |
+ // if arguments object is sloppy, copyWithin must move the arguments around |
+ function f(a, b, c, d, e) { |
+ [].copyWithin.call(arguments, 1, 3); |
+ return [a, b, c, d, e]; |
+ } |
+ assertArrayEquals([1, 4, 5, 4, 5], f(1, 2, 3, 4, 5)); |
+})(); |
+ |
+ |
+(function copyWithinStartLessThanTarget() { |
+ // test with target > start on 2 arguments |
+ assertArrayEquals([1, 2, 3, 1, 2], [1, 2, 3, 4, 5].copyWithin(3, 0)); |
+ |
+ // test with target > start on 3 arguments |
+ assertArrayEquals([1, 2, 3, 1, 2], [1, 2, 3, 4, 5].copyWithin(3, 0, 4)); |
+})(); |
+ |
+ |
+(function copyWithinArrayWithHoles() { |
+ // test on array with holes |
+ var arr = new Array(6); |
+ for (var i = 0; i < arr.length; i += 2) { |
+ arr[i] = i; |
+ } |
+ assertArrayEquals([, 4, , , 4, , ], arr.copyWithin(0, 3)); |
+})(); |
+ |
+ |
+(function copyWithinArrayLikeWithHoles() { |
+ // test on array-like object with holes |
+ assertArrayEquals({ |
+ length: 6, |
+ 1: 4, |
+ 4: 4 |
+ }, Array.prototype.copyWithin.call({ |
+ length: 6, |
+ 0: 0, |
+ 2: 2, |
+ 4: 4 |
+ }, 0, 3)); |
+})(); |
+ |
+ |
+(function copyWithinNonIntegerRelativeOffsets() { |
+ // test on fractional arguments |
+ assertArrayEquals([4, 5, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0.2, 3.9)); |
+})(); |
+ |
+ |
+(function copyWithinNegativeZeroTarget() { |
+ // test with -0 |
+ assertArrayEquals([4, 5, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(-0, 3)); |
+})(); |
+ |
+ |
+(function copyWithinTargetOutsideStart() { |
+ // test with arguments more than this.length |
+ assertArrayEquals([1, 2, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, 7)); |
+ |
+ // test with arguments less than -this.length |
+ assertArrayEquals([1, 2, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(-7, 0)); |
+})(); |
+ |
+ |
+(function copyWithinEmptyArray() { |
+ // test on empty array |
+ assertArrayEquals([], [].copyWithin(0, 3)); |
+})(); |
+ |
+ |
+(function copyWithinTargetCutOff() { |
+ // test with target range being shorter than end - start |
+ assertArrayEquals([1, 2, 2, 3, 4], [1, 2, 3, 4, 5].copyWithin(2, 1, 4)); |
+})(); |
+ |
+ |
+(function copyWithinOverlappingRanges() { |
+ // test overlapping ranges |
+ var arr = [1, 2, 3, 4, 5]; |
+ arr.copyWithin(2, 1, 4); |
+ assertArrayEquals([1, 2, 2, 2, 3], arr.copyWithin(2, 1, 4)); |
+})(); |
+ |
+ |
+(function copyWithinStrictDelete() { |
+ // check that [[Delete]] is strict (non-extensible via freeze) |
+ assertThrows(function() { |
+ return Object.freeze([1, , 3, , 4, 5]).copyWithin(2, 1, 4); |
+ }, TypeError); |
+ |
+ // check that [[Delete]] is strict (non-extensible via seal) |
+ assertThrows(function() { |
+ return Object.seal([1, , 3, , 4, 5]).copyWithin(2, 1, 4); |
+ }, TypeError); |
+ |
+ // check that [[Delete]] is strict (non-extensible via preventExtensions) |
+ assertThrows(function() { |
+ return Object.preventExtensions([1, , 3, , 4, 5]).copyWithin(2, 1, 4); |
+ }, TypeError); |
+})(); |
+ |
+ |
+(function copyWithinStrictSet() { |
+ // check that [[Set]] is strict (non-extensible via freeze) |
+ assertThrows(function() { |
+ return Object.freeze([1, 2, 3, 4, 5]).copyWithin(0, 3); |
+ }, TypeError); |
+ |
+ // check that [[Set]] is strict (non-extensible via seal) |
+ assertThrows(function() { |
+ return Object.seal([, 2, 3, 4, 5]).copyWithin(0, 3); |
+ }, TypeError); |
+ |
+ // check that [[Set]] is strict (non-extensible via preventExtensions) |
+ assertThrows(function() { |
+ return Object.preventExtensions([ , 2, 3, 4, 5]).copyWithin(0, 3); |
+ }, TypeError); |
+})(); |
+ |
+ |
+(function copyWithinSetterThrows() { |
+ function Boom() {} |
+ // test if we throw in between |
+ var arr = Object.defineProperty([1, 2, 3, 4, 5], 1, { |
+ set: function () { |
+ throw new Boom(); |
+ } |
+ }); |
+ |
+ assertThrows(function() { |
+ return arr.copyWithin(1, 3); |
+ }, Boom); |
+ |
+ assertArrayEquals([1, , 3, 4, 5], arr); |
+})(); |
+ |
+ |
+(function copyWithinDefaultEnd() { |
+ // undefined as third argument |
+ assertArrayEquals( |
+ [4, 5, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, 3, undefined)); |
+})(); |
+ |
+ |
+(function copyWithinGetLengthOnce() { |
+ // test that this.length is called only once |
+ var count = 0; |
+ var arr = Object.defineProperty({ 0: 1, 1: 2, 2: 3, 3: 4, 4: 5 }, "length", { |
+ get: function () { |
+ count++; |
+ return 5; |
+ } |
+ }); |
+ Array.prototype.copyWithin.call(arr, 1, 3); |
+ assertEquals(1, count); |
+ |
+ Array.prototype.copyWithin.call(arr, 1, 3, 4); |
+ assertEquals(2, count); |
+})(); |
+ |
+ |
+(function copyWithinLargeArray() { |
+ var large = 10000; |
+ |
+ // test on a large array |
+ var arr = new Array(large); |
+ assertArrayEquals(arr, arr.copyWithin(45, 9000)); |
+ |
+ var expected = new Array(large); |
+ // test on floating point numbers |
+ for (var i = 0; i < large; i++) { |
+ arr[i] = Math.random(); |
+ expected[i] = arr[i]; |
+ if (i >= 9000) { |
+ expected[(i - 9000) + 45] = arr[i]; |
+ } |
+ } |
+ assertArrayEquals(expected, arr.copyWithin(45, 9000)); |
+ |
+ // test on array of objects |
+ for (var i = 0; i < large; i++) { |
+ arr[i] = { num: Math.random() }; |
+ } + 45 |
+ arr.copyWithin(45, 9000); |
+ |
+ // test copied by reference |
+ for (var i = 9000; i < large; ++i) { |
+ assertSame(arr[(i - 9000) + 45], arr[i]); |
+ } |
+ |
+ // test array length remains same |
+ assertEquals(large, arr.length); |
+})(); |
+ |
+ |
+(function copyWithinSuperLargeLength() { |
+ // 2^53 - 1 is the maximum value returned from ToLength() |
+ var large = Math.pow(2, 53) - 1; |
+ var object = { length: large }; |
+ |
+ // Initialize last 10 entries |
+ for (var i = 1; i <= 10; ++i) { |
+ object[(large - 11) + i] = { num: i }; |
+ } |
+ |
+ Array.prototype.copyWithin.call(object, 1, large - 10); |
+ |
+ // Test copied values |
+ for (var i = 1; i <= 10; ++i) { |
+ var old_ref = object[(large - 11) + i]; |
+ var new_ref = object[i]; |
+ assertSame(old_ref, new_ref); |
+ assertSame(new_ref.num, i); |
+ } |
+ |
+ // Assert length has not changed |
+ assertEquals(large, object.length); |
+})(); |
+ |
+ |
+(function copyWithinNullEnd() { |
+ // test null on third argument is converted to +0 |
+ assertArrayEquals([1, 2, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, 3, null)); |
+})(); |
+ |
+ |
+(function copyWithinElementsInObjectsPrototype() { |
+ // tamper the global Object prototype and test this works |
+ Object.prototype[2] = 1; |
+ assertArrayEquals([4, 5, 3, 4, 5], [1, 2, 3, 4, 5].copyWithin(0, 3)); |
+ delete Object.prototype[2]; |
+ |
+ Object.prototype[3] = "FAKE"; |
+ assertArrayEquals(["FAKE", 5, 3, "FAKE", 5], [1, 2, 3, , 5].copyWithin(0, 3)); |
+ delete Object.prototype[3]; |
+})(); |