summaryrefslogtreecommitdiffstats
path: root/js/src/tests/test262/built-ins/Array/prototype/concat
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /js/src/tests/test262/built-ins/Array/prototype/concat
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'js/src/tests/test262/built-ins/Array/prototype/concat')
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-b-iii-3-b-1.js28
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-c-i-1.js30
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js26
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js26
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js24
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js32
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js35
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js31
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js36
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js21
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js52
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js27
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js16
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js31
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js24
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js28
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js27
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js56
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js45
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js38
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js26
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js43
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js41
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js25
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js34
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js28
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T1.js28
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T2.js30
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T3.js24
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T4.js24
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T1.js30
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T2.js22
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T1.js34
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js37
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js37
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-exceeding-integer-limit.js42
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-near-integer-limit.js39
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/browser.js0
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/call-with-boolean.js20
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-non-object.js44
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-poisoned.js28
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-non-array.js40
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-array.js48
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-non-array.js49
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-proxy.js45
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-revoked-proxy.js40
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-abrupt.js34
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js40
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible-spreadable.js45
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible.js43
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-null.js38
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-poisoned.js33
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-undef.js40
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property-spreadable.js47
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property.js45
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property-spreadable.js49
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property.js49
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/create-species.js48
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-err.js40
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-order.js75
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-is-array-proxy-revoked.js52
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy-revoked.js45
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy.js53
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-falsey.js57
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-truthy.js55
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-undefined.js43
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/length.js34
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/name.js32
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/not-a-constructor.js35
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/prop-desc.js23
-rw-r--r--js/src/tests/test262/built-ins/Array/prototype/concat/shell.js0
71 files changed, 2546 insertions, 0 deletions
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-b-iii-3-b-1.js b/js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-b-iii-3-b-1.js
new file mode 100644
index 0000000000..213a63acc5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-b-iii-3-b-1.js
@@ -0,0 +1,28 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Array.prototype.concat will concat an Array when index property
+ (read-only) exists in Array.prototype (Step 5.b.iii.3.b)
+includes: [propertyHelper.js]
+---*/
+
+Object.defineProperty(Array.prototype, "0", {
+ value: 100,
+ writable: false,
+ configurable: true
+});
+
+var oldArr = [101];
+var newArr = Array.prototype.concat.call(oldArr);
+
+verifyProperty(newArr, "0", {
+ value: 101,
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-c-i-1.js b/js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-c-i-1.js
new file mode 100644
index 0000000000..104ca1114d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/15.4.4.4-5-c-i-1.js
@@ -0,0 +1,30 @@
+// Copyright (c) 2012 Ecma International. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Array.prototype.concat will concat an Array when index property
+ (read-only) exists in Array.prototype (Step 5.c.i)
+includes: [propertyHelper.js]
+---*/
+
+Object.defineProperty(Array.prototype, "0", {
+ value: 100,
+ writable: false,
+ configurable: true
+});
+
+var newArrayFromConcat = Array.prototype.concat.call(101);
+
+assert(
+ newArrayFromConcat[0] instanceof Number,
+ 'The result of evaluating (newArrayFromConcat[0] instanceof Number) is expected to be true'
+);
+verifyProperty(newArrayFromConcat, "0", {
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js
new file mode 100644
index 0000000000..64a1fce627
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-to-string-throws.js
@@ -0,0 +1,26 @@
+// Copyright (c) 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.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like length to string throws
+features: [Symbol.isConcatSpreadable]
+---*/
+var objWithPoisonedLengthToString = {
+ "length": {
+ toString: function() {
+ throw new Test262Error();
+ },
+ valueOf: null
+ },
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+objWithPoisonedLengthToString[Symbol.isConcatSpreadable] = true;
+assert.throws(Test262Error, function() {
+ [].concat(objWithPoisonedLengthToString);
+}, '[].concat(objWithPoisonedLengthToString) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js
new file mode 100644
index 0000000000..2ef6eacd26
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-length-value-of-throws.js
@@ -0,0 +1,26 @@
+// Copyright (c) 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.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like length valueOf throws
+features: [Symbol.isConcatSpreadable]
+---*/
+var objWithPoisonedLengthValueOf = {
+ "length": {
+ valueOf: function() {
+ throw new Test262Error();
+ },
+ toString: null
+ },
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+objWithPoisonedLengthValueOf[Symbol.isConcatSpreadable] = true;
+assert.throws(Test262Error, function() {
+ [].concat(objWithPoisonedLengthValueOf);
+}, '[].concat(objWithPoisonedLengthValueOf) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js
new file mode 100644
index 0000000000..91cbc74883
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-negative-length.js
@@ -0,0 +1,24 @@
+// Copyright (c) 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.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like negative length
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var obj = {
+ "length": -4294967294,
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+assert.compareArray([].concat(obj), [], '[].concat({"length": -4294967294, "1": "A", "3": "B", "5": "C"}) must return []');
+obj.length = -4294967294;
+assert.compareArray([].concat(obj), [], '[].concat({"length": -4294967294, "1": "A", "3": "B", "5": "C"}) must return []');
+obj.length = "-4294967294";
+assert.compareArray([].concat(obj), [], '[].concat({"length": -4294967294, "1": "A", "3": "B", "5": "C"}) must return []');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js
new file mode 100644
index 0000000000..d03a424288
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-primitive-non-number-length.js
@@ -0,0 +1,32 @@
+// Copyright (c) 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.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like primitive non number length
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var obj = {
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+obj.length = {
+ toString: function() {
+ return "SIX";
+ },
+ valueOf: null
+};
+assert.compareArray([].concat(obj), [], '[].concat({"1": "A", "3": "B", "5": "C"}) must return []');
+obj.length = {
+ toString: null,
+ valueOf: function() {
+ return "SIX";
+ }
+};
+assert.compareArray([].concat(obj), [], '[].concat({"1": "A", "3": "B", "5": "C"}) must return []');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js
new file mode 100644
index 0000000000..1aa0191efd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-string-length.js
@@ -0,0 +1,35 @@
+// Copyright (c) 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.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like string length
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var obj = {
+ "length": "6",
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+var obj2 = {
+ length: 3,
+ "0": "0",
+ "1": "1",
+ "2": "2"
+};
+var arr = ["X", "Y", "Z"];
+
+var expected = [
+ void 0, "A", void 0, "B", void 0, "C",
+ obj2,
+ "X", "Y", "Z"
+];
+var actual = Array.prototype.concat.call(obj, obj2, arr);
+
+assert.compareArray(actual, expected, 'The value of actual is expected to equal the value of expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js
new file mode 100644
index 0000000000..8aef650339
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like-to-length-throws.js
@@ -0,0 +1,31 @@
+// Copyright (c) 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.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like to length throws
+features: [Symbol.isConcatSpreadable]
+---*/
+var spreadableWithBrokenLength = {
+ "length": {
+ valueOf: null,
+ toString: null
+ },
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+spreadableWithBrokenLength[Symbol.isConcatSpreadable] = true;
+var obj2 = {
+ length: 3,
+ "0": "0",
+ "1": "1",
+ "2": "2"
+};
+var arr = ["X", "Y", "Z"];
+assert.throws(TypeError, function() {
+ Array.prototype.concat.call(spreadableWithBrokenLength, obj2, arr);
+}, 'Array.prototype.concat.call(spreadableWithBrokenLength, obj2, arr) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js
new file mode 100644
index 0000000000..f188f17120
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_array-like.js
@@ -0,0 +1,36 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat array like
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var obj = {
+ "length": 6,
+ "1": "A",
+ "3": "B",
+ "5": "C"
+};
+obj[Symbol.isConcatSpreadable] = true;
+var obj2 = {
+ length: 3,
+ "0": "0",
+ "1": "1",
+ "2": "2"
+};
+var arr = ["X", "Y", "Z"];
+
+var expected = [
+ void 0, "A", void 0, "B", void 0, "C",
+ obj2,
+ "X", "Y", "Z"
+];
+var actual = Array.prototype.concat.call(obj, obj2, arr);
+
+assert.compareArray(actual, expected, 'The value of actual is expected to equal the value of expected');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js
new file mode 100644
index 0000000000..5f8cbfaab4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_holey-sloppy-arguments.js
@@ -0,0 +1,21 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat holey sloppy arguments
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var args = (function(a) {
+ return arguments;
+})(1, 2, 3);
+delete args[1];
+args[Symbol.isConcatSpreadable] = true;
+assert.compareArray([1, void 0, 3, 1, void 0, 3], [].concat(args, args),
+ '[1, void 0, 3, 1, void 0, 3] must return the same value returned by [].concat(args, args)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js
new file mode 100644
index 0000000000..a4de0ef3a9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_large-typed-array.js
@@ -0,0 +1,52 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat large typed array
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+function concatTypedArray(type, elems, modulo) {
+ var items = new Array(elems);
+ var ta_by_len = new type(elems);
+ for (var i = 0; i < elems; ++i) {
+ ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
+ }
+ var ta = new type(items);
+ assert.compareArray([].concat(ta, ta), [ta, ta]);
+ ta[Symbol.isConcatSpreadable] = true;
+ assert.compareArray([].concat(ta), items);
+
+ assert.compareArray([].concat(ta_by_len, ta_by_len), [ta_by_len, ta_by_len]);
+ ta_by_len[Symbol.isConcatSpreadable] = true;
+ assert.compareArray([].concat(ta_by_len), items);
+
+ // TypedArray with fake `length`.
+ ta = new type(1);
+ var defValue = ta[0];
+ var expected = new Array(4000);
+ expected[0] = defValue;
+
+ Object.defineProperty(ta, "length", {
+ value: 4000
+ });
+ ta[Symbol.isConcatSpreadable] = true;
+ assert.compareArray([].concat(ta), expected);
+}
+
+// Float16Array cannot be included in this because it cannot precisely represent integers above 2048
+var max = [Math.pow(2, 8), Math.pow(2, 16), Math.pow(2, 32), false, false];
+[
+ Uint8Array,
+ Uint16Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array
+].forEach(function(ctor, i) {
+ concatTypedArray(ctor, 4000, max[i]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js
new file mode 100644
index 0000000000..6ff8e0b3e1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_length-throws.js
@@ -0,0 +1,27 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat length throws
+features: [Symbol.isConcatSpreadable]
+---*/
+var spreadablePoisonedLengthGetter = {};
+spreadablePoisonedLengthGetter[Symbol.isConcatSpreadable] = true;
+Object.defineProperty(spreadablePoisonedLengthGetter, "length", {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ [].concat(spreadablePoisonedLengthGetter);
+}, '[].concat(spreadablePoisonedLengthGetter) throws a Test262Error exception');
+
+assert.throws(Test262Error, function() {
+ Array.prototype.concat.call(spreadablePoisonedLengthGetter, 1, 2, 3);
+}, 'Array.prototype.concat.call(spreadablePoisonedLengthGetter, 1, 2, 3) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js
new file mode 100644
index 0000000000..bb5dd7277c
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_no-prototype.js
@@ -0,0 +1,16 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat no prototype
+---*/
+assert.sameValue(
+ Array.prototype.concat.prototype,
+ void 0,
+ 'The value of Array.prototype.concat.prototype is expected to be void 0'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js
new file mode 100644
index 0000000000..a6288b26d0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_non-array.js
@@ -0,0 +1,31 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: array-concat-non-array
+includes: [compareArray.js]
+---*/
+
+//
+// test262 --command "v8 --harmony-classes --harmony_object_literals" array-concat-non-array
+//
+class NonArray {
+ constructor() {
+ Array.apply(this, arguments);
+ }
+}
+
+var obj = new NonArray(1, 2, 3);
+var result = Array.prototype.concat.call(obj, 4, 5, 6);
+assert.sameValue(Array, result.constructor, 'The value of Array is expected to equal the value of result.constructor');
+assert.sameValue(
+ result instanceof NonArray,
+ false,
+ 'The result of evaluating (result instanceof NonArray) is expected to be false'
+);
+assert.compareArray(result, [obj, 4, 5, 6], 'The value of result is expected to be [obj, 4, 5, 6]');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js
new file mode 100644
index 0000000000..72a67f4295
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-throws.js
@@ -0,0 +1,24 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat sloppy arguments throws
+features: [Symbol.isConcatSpreadable]
+---*/
+var args = (function(a) {
+ return arguments;
+})(1, 2, 3);
+Object.defineProperty(args, 0, {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+args[Symbol.isConcatSpreadable] = true;
+assert.throws(Test262Error, function() {
+ return [].concat(args, args);
+}, 'return [].concat(args, args) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js
new file mode 100644
index 0000000000..36af587993
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments-with-dupes.js
@@ -0,0 +1,28 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat sloppy arguments with dupes
+flags: [noStrict]
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var args = (function(a, a, a) {
+ return arguments;
+})(1, 2, 3);
+args[Symbol.isConcatSpreadable] = true;
+assert.compareArray([].concat(args, args), [1, 2, 3, 1, 2, 3],
+ '[].concat((function(a, a, a) {return arguments;})(1, 2, 3), (function(a, a, a) {return arguments;})(1, 2, 3)) must return [1, 2, 3, 1, 2, 3]'
+);
+
+Object.defineProperty(args, "length", {
+ value: 6
+});
+assert.compareArray([].concat(args), [1, 2, 3, void 0, void 0, void 0],
+ '[].concat((function(a, a, a) {return arguments;})(1, 2, 3)) must return [1, 2, 3, void 0, void 0, void 0]'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js
new file mode 100644
index 0000000000..1027774fde
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_sloppy-arguments.js
@@ -0,0 +1,27 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat sloppy arguments
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var args = (function(a, b, c) {
+ return arguments;
+})(1, 2, 3);
+args[Symbol.isConcatSpreadable] = true;
+assert.compareArray([].concat(args, args), [1, 2, 3, 1, 2, 3],
+ '[].concat((function(a, b, c) {return arguments;})(1, 2, 3), (function(a, b, c) {return arguments;})(1, 2, 3)) must return [1, 2, 3, 1, 2, 3]'
+);
+
+Object.defineProperty(args, "length", {
+ value: 6
+});
+assert.compareArray([].concat(args), [1, 2, 3, void 0, void 0, void 0],
+ '[].concat((function(a, b, c) {return arguments;})(1, 2, 3)) must return [1, 2, 3, void 0, void 0, void 0]'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js
new file mode 100644
index 0000000000..2bb8b17ef3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_small-typed-array.js
@@ -0,0 +1,56 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat small typed array
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+function concatTypedArray(type, elems, modulo) {
+ var items = new Array(elems);
+ var ta_by_len = new type(elems);
+ for (var i = 0; i < elems; ++i) {
+ ta_by_len[i] = items[i] = modulo === false ? i : elems % modulo;
+ }
+ var ta = new type(items);
+ assert.compareArray([].concat(ta, ta), [ta, ta]);
+ ta[Symbol.isConcatSpreadable] = true;
+ assert.compareArray([].concat(ta), items);
+
+ assert.compareArray([].concat(ta_by_len, ta_by_len), [ta_by_len, ta_by_len]);
+ ta_by_len[Symbol.isConcatSpreadable] = true;
+ assert.compareArray([].concat(ta_by_len), items);
+
+ // TypedArray with fake `length`.
+ ta = new type(1);
+ var defValue = ta[0];
+ var expected = new Array(4000);
+ expected[0] = defValue;
+
+ Object.defineProperty(ta, "length", {
+ value: 4000
+ });
+ ta[Symbol.isConcatSpreadable] = true;
+ assert.compareArray([].concat(ta), expected);
+}
+var max = [Math.pow(2, 8), Math.pow(2, 16), Math.pow(2, 32), false, false];
+var TAs = [
+ Uint8Array,
+ Uint16Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array
+];
+if (typeof Float16Array !== 'undefined') {
+ max.push(false);
+ TAs.push(Float16Array);
+}
+
+TAs.forEach(function(ctor, i) {
+ concatTypedArray(ctor, 1, max[i]);
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js
new file mode 100644
index 0000000000..1a1c8cbdcf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-boolean-wrapper.js
@@ -0,0 +1,45 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable boolean wrapper
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var bool = new Boolean(true)
+// Boolean wrapper objects are not concat-spreadable by default
+assert.compareArray([bool], [].concat(bool), '[bool] must return the same value returned by [].concat(bool)');
+
+// Boolean wrapper objects may be individually concat-spreadable
+bool[Symbol.isConcatSpreadable] = true;
+bool.length = 3;
+bool[0] = 1, bool[1] = 2, bool[2] = 3;
+assert.compareArray([1, 2, 3], [].concat(bool),
+ '[1, 2, 3] must return the same value returned by [].concat(bool)'
+);
+
+Boolean.prototype[Symbol.isConcatSpreadable] = true;
+// Boolean wrapper objects may be concat-spreadable
+assert.compareArray([], [].concat(new Boolean(true)),
+ '[] must return the same value returned by [].concat(new Boolean(true))'
+);
+Boolean.prototype[0] = 1;
+Boolean.prototype[1] = 2;
+Boolean.prototype[2] = 3;
+Boolean.prototype.length = 3;
+assert.compareArray([1, 2, 3], [].concat(new Boolean(true)),
+ '[1, 2, 3] must return the same value returned by [].concat(new Boolean(true))'
+);
+
+// Boolean values are never concat-spreadable
+assert.compareArray([true], [].concat(true), '[true] must return the same value returned by [].concat(true)');
+delete Boolean.prototype[Symbol.isConcatSpreadable];
+delete Boolean.prototype[0];
+delete Boolean.prototype[1];
+delete Boolean.prototype[2];
+delete Boolean.prototype.length;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js
new file mode 100644
index 0000000000..6f692548b2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-function.js
@@ -0,0 +1,38 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable function
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var fn = function(a, b, c) {}
+// Functions are not concat-spreadable by default
+assert.compareArray([fn], [].concat(fn), '[fn] must return the same value returned by [].concat(fn)');
+
+// Functions may be individually concat-spreadable
+fn[Symbol.isConcatSpreadable] = true;
+fn[0] = 1, fn[1] = 2, fn[2] = 3;
+assert.compareArray([1, 2, 3], [].concat(fn), '[1, 2, 3] must return the same value returned by [].concat(fn)');
+
+Function.prototype[Symbol.isConcatSpreadable] = true;
+// Functions may be concat-spreadable
+assert.compareArray([void 0, void 0, void 0], [].concat(function(a, b, c) {}),
+ '[void 0, void 0, void 0] must return the same value returned by [].concat(function(a, b, c) {})'
+);
+Function.prototype[0] = 1;
+Function.prototype[1] = 2;
+Function.prototype[2] = 3;
+assert.compareArray([1, 2, 3], [].concat(function(a, b, c) {}),
+ '[1, 2, 3] must return the same value returned by [].concat(function(a, b, c) {})'
+);
+
+delete Function.prototype[Symbol.isConcatSpreadable];
+delete Function.prototype[0];
+delete Function.prototype[1];
+delete Function.prototype[2];
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js
new file mode 100644
index 0000000000..7027cb04da
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-getter-throws.js
@@ -0,0 +1,26 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable getter throws
+features: [Symbol.isConcatSpreadable]
+---*/
+var spreadablePoisonedGetter = {};
+Object.defineProperty(spreadablePoisonedGetter, Symbol.isConcatSpreadable, {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ [].concat(spreadablePoisonedGetter);
+}, '[].concat(spreadablePoisonedGetter) throws a Test262Error exception');
+
+assert.throws(Test262Error, function() {
+ Array.prototype.concat.call(spreadablePoisonedGetter, 1, 2, 3);
+}, 'Array.prototype.concat.call(spreadablePoisonedGetter, 1, 2, 3) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js
new file mode 100644
index 0000000000..08923aa009
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-number-wrapper.js
@@ -0,0 +1,43 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable number wrapper
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var num = new Number(true)
+// Number wrapper objects are not concat-spreadable by default
+assert.compareArray([num], [].concat(num), '[num] must return the same value returned by [].concat(num)');
+
+// Number wrapper objects may be individually concat-spreadable
+num[Symbol.isConcatSpreadable] = true;
+num.length = 3;
+num[0] = 1, num[1] = 2, num[2] = 3;
+assert.compareArray([1, 2, 3], [].concat(num), '[1, 2, 3] must return the same value returned by [].concat(num)');
+
+Number.prototype[Symbol.isConcatSpreadable] = true;
+// Number wrapper objects may be concat-spreadable
+assert.compareArray([], [].concat(new Number(123)),
+ '[] must return the same value returned by [].concat(new Number(123))'
+);
+Number.prototype[0] = 1;
+Number.prototype[1] = 2;
+Number.prototype[2] = 3;
+Number.prototype.length = 3;
+assert.compareArray([1, 2, 3], [].concat(new Number(123)),
+ '[1, 2, 3] must return the same value returned by [].concat(new Number(123))'
+);
+
+// Number values are never concat-spreadable
+assert.compareArray([true], [].concat(true), '[true] must return the same value returned by [].concat(true)');
+delete Number.prototype[Symbol.isConcatSpreadable];
+delete Number.prototype[0];
+delete Number.prototype[1];
+delete Number.prototype[2];
+delete Number.prototype.length;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js
new file mode 100644
index 0000000000..dca75da974
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-reg-exp.js
@@ -0,0 +1,41 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable reg exp
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var re = /abc/;
+// RegExps are not concat-spreadable by default
+assert.compareArray([].concat(re), [re], '[].concat(/abc/) must return [re]');
+
+// RegExps may be individually concat-spreadable
+re[Symbol.isConcatSpreadable] = true;
+re[0] = 1, re[1] = 2, re[2] = 3, re.length = 3;
+assert.compareArray([].concat(re), [1, 2, 3], '[].concat(/abc/) must return [1, 2, 3]');
+
+// RegExps may be concat-spreadable
+RegExp.prototype[Symbol.isConcatSpreadable] = true;
+RegExp.prototype.length = 3;
+
+assert.compareArray([].concat(/abc/), [void 0, void 0, void 0],
+ '[].concat(/abc/) must return [void 0, void 0, void 0]'
+);
+RegExp.prototype[0] = 1;
+RegExp.prototype[1] = 2;
+RegExp.prototype[2] = 3;
+assert.compareArray([].concat(/abc/), [1, 2, 3],
+ '[].concat(/abc/) must return [1, 2, 3]'
+);
+
+delete RegExp.prototype[Symbol.isConcatSpreadable];
+delete RegExp.prototype[0];
+delete RegExp.prototype[1];
+delete RegExp.prototype[2];
+delete RegExp.prototype.length;
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js
new file mode 100644
index 0000000000..1ede626d06
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-sparse-object.js
@@ -0,0 +1,25 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable sparse object
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var obj = {
+ length: 5
+};
+obj[Symbol.isConcatSpreadable] = true;
+assert.compareArray([void 0, void 0, void 0, void 0, void 0], [].concat(obj),
+ '[void 0, void 0, void 0, void 0, void 0] must return the same value returned by [].concat(obj)'
+);
+
+obj.length = 4000;
+assert.compareArray(new Array(4000), [].concat(obj),
+ 'new Array(4000) must return the same value returned by [].concat(obj)'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js
new file mode 100644
index 0000000000..e44fbc769a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_spreadable-string-wrapper.js
@@ -0,0 +1,34 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat Symbol.isConcatSpreadable string wrapper
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var str1 = new String("yuck\uD83D\uDCA9")
+// String wrapper objects are not concat-spreadable by default
+assert.compareArray([str1], [].concat(str1), '[str1] must return the same value returned by [].concat(str1)');
+
+// String wrapper objects may be individually concat-spreadable
+str1[Symbol.isConcatSpreadable] = true;
+assert.compareArray(["y", "u", "c", "k", "\uD83D", "\uDCA9"], [].concat(str1),
+ '["y", "u", "c", "k", "uD83D", "uDCA9"] must return the same value returned by [].concat(str1)'
+);
+
+String.prototype[Symbol.isConcatSpreadable] = true;
+// String wrapper objects may be concat-spreadable
+assert.compareArray(["y", "u", "c", "k", "\uD83D", "\uDCA9"], [].concat(new String("yuck\uD83D\uDCA9")),
+ '["y", "u", "c", "k", "uD83D", "uDCA9"] must return the same value returned by [].concat(new String("yuckuD83DuDCA9"))'
+);
+
+// String values are never concat-spreadable
+assert.compareArray(["yuck\uD83D\uDCA9"], [].concat("yuck\uD83D\uDCA9"),
+ '["yuckuD83DuDCA9"] must return the same value returned by [].concat("yuckuD83DuDCA9")'
+);
+delete String.prototype[Symbol.isConcatSpreadable];
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js
new file mode 100644
index 0000000000..34f81f0a45
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/Array.prototype.concat_strict-arguments.js
@@ -0,0 +1,28 @@
+// Copyright (c) 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.
+
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat strict arguments
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+var args = (function(a, b, c) {
+ "use strict";
+ return arguments;
+})(1, 2, 3);
+args[Symbol.isConcatSpreadable] = true;
+assert.compareArray([].concat(args, args), [1, 2, 3, 1, 2, 3],
+ '[].concat("(function(a, b, c) {"use strict"; return arguments;})(1, 2, 3)", "(function(a, b, c) {"use strict"; return arguments;})(1, 2, 3)") must return [1, 2, 3, 1, 2, 3]'
+);
+
+Object.defineProperty(args, "length", {
+ value: 6
+});
+assert.compareArray([].concat(args), [1, 2, 3, void 0, void 0, void 0],
+ '[].concat("(function(a, b, c) {"use strict"; return arguments;})(1, 2, 3)") must return [1, 2, 3, void 0, void 0, void 0]'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T1.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T1.js
new file mode 100644
index 0000000000..7d4bd82f39
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T1.js
@@ -0,0 +1,28 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: |
+ When the concat method is called with zero or more arguments item1, item2,
+ etc., it returns an array containing the array elements of the object followed by
+ the array elements of each argument in order
+es5id: 15.4.4.4_A1_T1
+description: Checking this algorithm, items are Array object
+---*/
+
+var x = new Array();
+var y = new Array(0, 1);
+var z = new Array(2, 3, 4);
+var arr = x.concat(y, z);
+
+arr.getClass = Object.prototype.toString;
+assert.sameValue(arr.getClass(), "[object Array]", 'arr.getClass() must return "[object Array]"');
+assert.sameValue(arr[0], 0, 'The value of arr[0] is expected to be 0');
+assert.sameValue(arr[1], 1, 'The value of arr[1] is expected to be 1');
+assert.sameValue(arr[2], 2, 'The value of arr[2] is expected to be 2');
+assert.sameValue(arr[3], 3, 'The value of arr[3] is expected to be 3');
+assert.sameValue(arr[4], 4, 'The value of arr[4] is expected to be 4');
+assert.sameValue(arr.length, 5, 'The value of arr.length is expected to be 5');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T2.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T2.js
new file mode 100644
index 0000000000..1ac86bfd21
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T2.js
@@ -0,0 +1,30 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: |
+ When the concat method is called with zero or more arguments item1, item2,
+ etc., it returns an array containing the array elements of the object followed by
+ the array elements of each argument in order
+es5id: 15.4.4.4_A1_T2
+description: Checking this algorithm, items are objects and primitives
+---*/
+
+var x = [0];
+var y = new Object();
+var z = new Array(1, 2);
+var arr = x.concat(y, z, -1, true, "NaN");
+
+arr.getClass = Object.prototype.toString;
+assert.sameValue(arr.getClass(), "[object Array]", 'arr.getClass() must return "[object Array]"');
+assert.sameValue(arr[0], 0, 'The value of arr[0] is expected to be 0');
+assert.sameValue(arr[1], y, 'The value of arr[1] is expected to equal the value of y');
+assert.sameValue(arr[2], 1, 'The value of arr[2] is expected to be 1');
+assert.sameValue(arr[3], 2, 'The value of arr[3] is expected to be 2');
+assert.sameValue(arr[4], -1, 'The value of arr[4] is expected to be -1');
+assert.sameValue(arr[5], true, 'The value of arr[5] is expected to be true');
+assert.sameValue(arr[6], "NaN", 'The value of arr[6] is expected to be "NaN"');
+assert.sameValue(arr.length, 7, 'The value of arr.length is expected to be 7');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T3.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T3.js
new file mode 100644
index 0000000000..efcd31f65d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T3.js
@@ -0,0 +1,24 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: |
+ When the concat method is called with zero or more arguments item1, item2,
+ etc., it returns an array containing the array elements of the object followed by
+ the array elements of each argument in order
+es5id: 15.4.4.4_A1_T3
+description: Checking this algorithm with no items
+---*/
+
+var x = [0, 1];
+var arr = x.concat();
+
+arr.getClass = Object.prototype.toString;
+assert.sameValue(arr.getClass(), "[object Array]", 'arr.getClass() must return "[object Array]"');
+assert.sameValue(arr[0], 0, 'The value of arr[0] is expected to be 0');
+assert.sameValue(arr[1], 1, 'The value of arr[1] is expected to be 1');
+assert.sameValue(arr.length, 2, 'The value of arr.length is expected to be 2');
+assert.notSameValue(arr, x, 'The value of arr is expected to not equal the value of `x`');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T4.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T4.js
new file mode 100644
index 0000000000..be7c04c42e
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A1_T4.js
@@ -0,0 +1,24 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: |
+ When the concat method is called with zero or more arguments item1, item2,
+ etc., it returns an array containing the array elements of the object followed by
+ the array elements of each argument in order
+es5id: 15.4.4.4_A1_T4
+description: Checking this algorithm, items are [], [,]
+---*/
+
+var x = [, 1];
+var arr = x.concat([], [, ]);
+
+arr.getClass = Object.prototype.toString;
+assert.sameValue(arr.getClass(), "[object Array]", 'arr.getClass() must return "[object Array]"');
+assert.sameValue(arr[0], undefined, 'The value of arr[0] is expected to equal undefined');
+assert.sameValue(arr[1], 1, 'The value of arr[1] is expected to be 1');
+assert.sameValue(arr[2], undefined, 'The value of arr[2] is expected to equal undefined');
+assert.sameValue(arr.length, 3, 'The value of arr.length is expected to be 3');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T1.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T1.js
new file mode 100644
index 0000000000..8cf2de37a2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T1.js
@@ -0,0 +1,30 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: |
+ The concat function is intentionally generic.
+ It does not require that its this value be an Array object
+es5id: 15.4.4.4_A2_T1
+description: Checking this for Object object, items are objects and primitives
+---*/
+
+var x = {};
+x.concat = Array.prototype.concat;
+var y = new Object();
+var z = new Array(1, 2);
+var arr = x.concat(y, z, -1, true, "NaN");
+
+arr.getClass = Object.prototype.toString;
+assert.sameValue(arr.getClass(), "[object Array]", 'arr.getClass() must return "[object Array]"');
+assert.sameValue(arr[0], x, 'The value of arr[0] is expected to equal the value of x');
+assert.sameValue(arr[1], y, 'The value of arr[1] is expected to equal the value of y');
+assert.sameValue(arr[2], 1, 'The value of arr[2] is expected to be 1');
+assert.sameValue(arr[3], 2, 'The value of arr[3] is expected to be 2');
+assert.sameValue(arr[4], -1, 'The value of arr[4] is expected to be -1');
+assert.sameValue(arr[5], true, 'The value of arr[5] is expected to be true');
+assert.sameValue(arr[6], "NaN", 'The value of arr[6] is expected to be "NaN"');
+assert.sameValue(arr.length, 7, 'The value of arr.length is expected to be 7');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T2.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T2.js
new file mode 100644
index 0000000000..8d0efd6b2f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A2_T2.js
@@ -0,0 +1,22 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: |
+ The concat function is intentionally generic.
+ It does not require that its this value be an Array object
+es5id: 15.4.4.4_A2_T2
+description: Checking this for Object object with no items
+---*/
+
+var x = {};
+x.concat = Array.prototype.concat;
+var arr = x.concat();
+
+arr.getClass = Object.prototype.toString;
+assert.sameValue(arr.getClass(), "[object Array]", 'arr.getClass() must return "[object Array]"');
+assert.sameValue(arr[0], x, 'The value of arr[0] is expected to equal the value of x');
+assert.sameValue(arr.length, 1, 'The value of arr.length is expected to be 1');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T1.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T1.js
new file mode 100644
index 0000000000..34ef8926c9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T1.js
@@ -0,0 +1,34 @@
+// Copyright 2009 the Sputnik authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+info: "[[Get]] from not an inherited property"
+es5id: 15.4.4.4_A3_T1
+description: >
+ [[Prototype]] of Array instance is Array.prototype, [[Prototype]
+ of Array.prototype is Object.prototype
+---*/
+
+Array.prototype[1] = 1;
+var x = [0];
+x.length = 2;
+var arr = x.concat();
+
+assert.sameValue(arr[0], 0, 'The value of arr[0] is expected to be 0');
+assert.sameValue(arr[1], 1, 'The value of arr[1] is expected to be 1');
+assert.sameValue(arr.hasOwnProperty('1'), true, 'arr.hasOwnProperty("1") must return true');
+
+Object.prototype[1] = 1;
+Object.prototype.length = 2;
+Object.prototype.concat = Array.prototype.concat;
+x = {
+ 0: 0
+};
+var arr = x.concat();
+
+assert.sameValue(arr[0], x, 'The value of arr[0] is expected to equal the value of x');
+assert.sameValue(arr[1], 1, 'The value of arr[1] is expected to be 1');
+assert.sameValue(arr.hasOwnProperty('1'), false, 'arr.hasOwnProperty("1") must return false');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js
new file mode 100644
index 0000000000..858b6080b0
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T2.js
@@ -0,0 +1,37 @@
+// Copyright (c) 2014 Ecma International. All rights reserved.
+// See LICENSE or https://github.com/tc39/test262/blob/HEAD/LICENSE
+
+/*---
+esid: sec-array.prototype.concat
+info: Array.prototype.concat uses [[Get]] on 'length' to determine array length
+es5id: 15.4.4.4_A3_T2
+description: >
+ checking whether non-ownProperties are seen, copied by Array.prototype.concat: Array.prototype[1]
+---*/
+
+var a = [0];
+
+assert.sameValue(a.length, 1, 'The value of a.length is expected to be 1');
+
+a.length = 3;
+
+assert.sameValue(a[1], undefined, 'The value of a[1] is expected to equal undefined');
+assert.sameValue(a[2], undefined, 'The value of a[2] is expected to equal undefined');
+
+Array.prototype[2] = 2;
+
+assert.sameValue(a[1], undefined, 'The value of a[1] is expected to equal undefined');
+assert.sameValue(a[2], 2, 'The value of a[2] is expected to be 2');
+assert.sameValue(a.hasOwnProperty('1'), false, 'a.hasOwnProperty("1") must return false');
+assert.sameValue(a.hasOwnProperty('2'), false, 'a.hasOwnProperty("2") must return false');
+
+var b = a.concat();
+
+assert.sameValue(b.length, 3, 'The value of b.length is expected to be 3');
+assert.sameValue(b[0], 0, 'The value of b[0] is expected to be 0');
+assert.sameValue(b[1], undefined, 'The value of b[1] is expected to equal undefined');
+assert.sameValue(b[2], 2, 'The value of b[2] is expected to be 2');
+assert.sameValue(b.hasOwnProperty('1'), false, 'b.hasOwnProperty("1") must return false');
+assert.sameValue(b.hasOwnProperty('2'), true, 'b.hasOwnProperty("2") must return true');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js
new file mode 100644
index 0000000000..270a2a0137
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/S15.4.4.4_A3_T3.js
@@ -0,0 +1,37 @@
+// Copyright (c) 2014 Ecma International. All rights reserved.
+// See LICENSE or https://github.com/tc39/test262/blob/HEAD/LICENSE
+
+/*---
+esid: sec-array.prototype.concat
+info: Array.prototype.concat uses [[Get]] on 'length' to determine array length
+es5id: 15.4.4.4_A3_T3
+description: >
+ checking whether non-ownProperties are seen, copied by Array.prototype.concat: Object.prototype[1]
+---*/
+
+var a = [0];
+
+assert.sameValue(a.length, 1, 'The value of a.length is expected to be 1');
+
+a.length = 3;
+
+assert.sameValue(a[1], undefined, 'The value of a[1] is expected to equal undefined');
+assert.sameValue(a[2], undefined, 'The value of a[2] is expected to equal undefined');
+
+Object.prototype[2] = 2;
+
+assert.sameValue(a[1], undefined, 'The value of a[1] is expected to equal undefined');
+assert.sameValue(a[2], 2, 'The value of a[2] is expected to be 2');
+assert.sameValue(a.hasOwnProperty('1'), false, 'a.hasOwnProperty("1") must return false');
+assert.sameValue(a.hasOwnProperty('2'), false, 'a.hasOwnProperty("2") must return false');
+
+var b = a.concat();
+
+assert.sameValue(b.length, 3, 'The value of b.length is expected to be 3');
+assert.sameValue(b[0], 0, 'The value of b[0] is expected to be 0');
+assert.sameValue(b[1], undefined, 'The value of b[1] is expected to equal undefined');
+assert.sameValue(b[2], 2, 'The value of b[2] is expected to be 2');
+assert.sameValue(b.hasOwnProperty('1'), false, 'b.hasOwnProperty("1") must return false');
+assert.sameValue(b.hasOwnProperty('2'), true, 'b.hasOwnProperty("2") must return true');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-exceeding-integer-limit.js b/js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-exceeding-integer-limit.js
new file mode 100644
index 0000000000..3e997498e9
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-exceeding-integer-limit.js
@@ -0,0 +1,42 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ TypeError is thrown if "length" of result array exceeds 2^53 - 1.
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ ii. Let len be ? LengthOfArrayLike(E).
+ iii. If n + len > 2^53 - 1, throw a TypeError exception.
+ [...]
+features: [Symbol.isConcatSpreadable, Proxy]
+---*/
+
+var spreadableLengthOutOfRange = {};
+spreadableLengthOutOfRange.length = Number.MAX_SAFE_INTEGER;
+spreadableLengthOutOfRange[Symbol.isConcatSpreadable] = true;
+
+assert.throws(TypeError, function() {
+ [1].concat(spreadableLengthOutOfRange);
+}, '[1].concat(spreadableLengthOutOfRange) throws a TypeError exception');
+
+var proxyForArrayWithLengthOutOfRange = new Proxy([], {
+ get: function(_target, key) {
+ if (key === "length") {
+ return Number.MAX_SAFE_INTEGER;
+ }
+ },
+});
+
+assert.throws(TypeError, function() {
+ [].concat(1, proxyForArrayWithLengthOutOfRange);
+}, '[].concat(1, proxyForArrayWithLengthOutOfRange) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-near-integer-limit.js b/js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-near-integer-limit.js
new file mode 100644
index 0000000000..438f520e16
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/arg-length-near-integer-limit.js
@@ -0,0 +1,39 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Elements are copied from a spreadable array-like object
+ whose "length" property is near the integer limit.
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ ii. Let len be ? LengthOfArrayLike(E).
+ iii. If n + len > 2^53 - 1, throw a TypeError exception.
+ iv. Repeat, while k < len
+ [...]
+ 3. If exists is true, then
+ a. Let subElement be ? Get(E, P).
+ [...]
+features: [Symbol.isConcatSpreadable]
+---*/
+
+var spreadableHasPoisonedIndex = {
+ length: Number.MAX_SAFE_INTEGER,
+ get 0() {
+ throw new Test262Error();
+ },
+};
+spreadableHasPoisonedIndex[Symbol.isConcatSpreadable] = true;
+
+assert.throws(Test262Error, function() {
+ [].concat(spreadableHasPoisonedIndex);
+}, '[].concat(spreadableHasPoisonedIndex) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/browser.js b/js/src/tests/test262/built-ins/Array/prototype/concat/browser.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/browser.js
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/call-with-boolean.js b/js/src/tests/test262/built-ins/Array/prototype/concat/call-with-boolean.js
new file mode 100644
index 0000000000..4f2f0bdbd1
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/call-with-boolean.js
@@ -0,0 +1,20 @@
+// Copyright (c) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: Array.prototype.concat applied to boolean primitive
+---*/
+
+assert.sameValue(
+ Array.prototype.concat.call(true)[0] instanceof Boolean,
+ true,
+ 'The result of evaluating (Array.prototype.concat.call(true)[0] instanceof Boolean) is expected to be true'
+);
+assert.sameValue(
+ Array.prototype.concat.call(false)[0] instanceof Boolean,
+ true,
+ 'The result of evaluating (Array.prototype.concat.call(false)[0] instanceof Boolean) is expected to be true'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-non-object.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-non-object.js
new file mode 100644
index 0000000000..e903ec6b66
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-non-object.js
@@ -0,0 +1,44 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Behavior when `constructor` property is neither an Object nor undefined
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 9. If IsConstructor(C) is false, throw a TypeError exception.
+---*/
+
+var a = [];
+
+a.constructor = null;
+assert.throws(TypeError, function() {
+ a.concat();
+}, 'a.concat() throws a TypeError exception');
+
+a = [];
+a.constructor = 1;
+assert.throws(TypeError, function() {
+ a.concat();
+}, 'a.concat() throws a TypeError exception');
+
+a = [];
+a.constructor = 'string';
+assert.throws(TypeError, function() {
+ a.concat();
+}, 'a.concat() throws a TypeError exception');
+
+a = [];
+a.constructor = true;
+assert.throws(TypeError, function() {
+ a.concat();
+}, 'a.concat() throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-poisoned.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-poisoned.js
new file mode 100644
index 0000000000..faaaf7c756
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-ctor-poisoned.js
@@ -0,0 +1,28 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Abrupt completion from `constructor` property access
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+---*/
+
+var a = [];
+
+Object.defineProperty(a, 'constructor', {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ a.concat();
+}, 'a.concat() throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-non-array.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-non-array.js
new file mode 100644
index 0000000000..6501c3270a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-non-array.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Constructor is ignored for non-Array values
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 3. Let isArray be ? IsArray(originalArray).
+ 4. If isArray is false, return ? ArrayCreate(length).
+---*/
+
+var obj = {
+ length: 0
+};
+var callCount = 0;
+var result;
+Object.defineProperty(obj, 'constructor', {
+ get: function() {
+ callCount += 1;
+ }
+});
+
+result = Array.prototype.concat.call(obj);
+
+assert.sameValue(callCount, 0, 'The value of callCount is expected to be 0');
+assert.sameValue(
+ Object.getPrototypeOf(result),
+ Array.prototype,
+ 'Object.getPrototypeOf(Array.prototype.concat.call(obj)) returns Array.prototype'
+);
+assert(Array.isArray(result), 'Array.isArray(result) must return true');
+assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1');
+assert.sameValue(result[0], obj, 'The value of result[0] is expected to equal the value of obj');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-array.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-array.js
new file mode 100644
index 0000000000..c23e02c0ce
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-array.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Prefer Array constructor of current realm record
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+ [...]
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ 6. If IsConstructor(C) is true, then
+ a. Let thisRealm be the current Realm Record.
+ b. Let realmC be ? GetFunctionRealm(C).
+ c. If thisRealm and realmC are not the same Realm Record, then
+ i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, let C
+ be undefined.
+ [...]
+features: [cross-realm, Symbol.species]
+---*/
+
+var array = [];
+var callCount = 0;
+var OArray = $262.createRealm().global.Array;
+var speciesDesc = {
+ get: function() {
+ callCount += 1;
+ }
+};
+var result;
+array.constructor = OArray;
+
+Object.defineProperty(Array, Symbol.species, speciesDesc);
+Object.defineProperty(OArray, Symbol.species, speciesDesc);
+
+result = array.concat();
+
+assert.sameValue(
+ Object.getPrototypeOf(result),
+ Array.prototype,
+ 'Object.getPrototypeOf(array.concat()) returns Array.prototype'
+);
+assert.sameValue(callCount, 0, 'The value of callCount is expected to be 0');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-non-array.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-non-array.js
new file mode 100644
index 0000000000..eaf05ad755
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-proto-from-ctor-realm-non-array.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Accept non-Array constructors from other realms
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+ [...]
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ 6. If IsConstructor(C) is true, then
+ a. Let thisRealm be the current Realm Record.
+ b. Let realmC be ? GetFunctionRealm(C).
+ c. If thisRealm and realmC are not the same Realm Record, then
+ i. If SameValue(C, realmC.[[Intrinsics]].[[%Array%]]) is true, let C
+ be undefined.
+ [...]
+features: [cross-realm, Symbol.species]
+---*/
+
+var array = [];
+var callCount = 0;
+var CustomCtor = function() {};
+var OObject = $262.createRealm().global.Object;
+var speciesDesc = {
+ get: function() {
+ callCount += 1;
+ }
+};
+var result;
+array.constructor = OObject;
+OObject[Symbol.species] = CustomCtor;
+
+Object.defineProperty(Array, Symbol.species, speciesDesc);
+
+result = array.concat();
+
+assert.sameValue(
+ Object.getPrototypeOf(result),
+ CustomCtor.prototype,
+ 'Object.getPrototypeOf(array.concat()) returns CustomCtor.prototype'
+);
+assert.sameValue(callCount, 0, 'The value of callCount is expected to be 0');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-proxy.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-proxy.js
new file mode 100644
index 0000000000..4ce82f5c7f
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-proxy.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Species constructor of a Proxy object whose target is an array
+info: |
+ [...]
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+ [...]
+ 7. Return A.
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 3. Let isArray be ? IsArray(originalArray).
+
+ 7.2.2 IsArray
+
+ [...]
+ 3. If argument is a Proxy exotic object, then
+ a. If the value of the [[ProxyHandler]] internal slot of argument is
+ null, throw a TypeError exception.
+ b. Let target be the value of the [[ProxyTarget]] internal slot of
+ argument.
+ c. Return ? IsArray(target).
+features: [Proxy, Symbol.species]
+---*/
+
+var array = [];
+var proxy = new Proxy(new Proxy(array, {}), {});
+var Ctor = function() {};
+var result;
+
+array.constructor = function() {};
+array.constructor[Symbol.species] = Ctor;
+
+result = Array.prototype.concat.call(proxy);
+
+assert.sameValue(
+ Object.getPrototypeOf(result),
+ Ctor.prototype,
+ 'Object.getPrototypeOf(Array.prototype.concat.call(proxy)) returns Ctor.prototype'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-revoked-proxy.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-revoked-proxy.js
new file mode 100644
index 0000000000..bac42fd509
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-revoked-proxy.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Abrupt completion from constructor that is a revoked Proxy object
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 3. Let isArray be ? IsArray(originalArray).
+
+ 7.2.2 IsArray
+
+ [...]
+ 3. If argument is a Proxy exotic object, then
+ a. If the value of the [[ProxyHandler]] internal slot of argument is
+ null, throw a TypeError exception.
+features: [Proxy]
+---*/
+
+var o = Proxy.revocable([], {});
+var callCount = 0;
+
+Object.defineProperty(o.proxy, 'constructor', {
+ get: function() {
+ callCount += 1;
+ }
+});
+o.revoke();
+
+assert.throws(TypeError, function() {
+ Array.prototype.concat.call(o.proxy);
+}, 'Array.prototype.concat.call(o.proxy) throws a TypeError exception');
+
+assert.sameValue(callCount, 0, 'The value of callCount is expected to be 0');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-abrupt.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-abrupt.js
new file mode 100644
index 0000000000..340a42f8cf
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-abrupt.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Species constructor returns an abrupt completion
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 7. If Type(C) is Object, then
+ a. Let C be ? Get(C, @@species).
+ b. If C is null, let C be undefined.
+ [...]
+ 10. Return ? Construct(C, « length »).
+features: [Symbol.species]
+---*/
+
+var Ctor = function() {
+ throw new Test262Error();
+};
+var a = [];
+a.constructor = {};
+a.constructor[Symbol.species] = Ctor;
+
+assert.throws(Test262Error, function() {
+ a.concat();
+}, 'a.concat() throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js
new file mode 100644
index 0000000000..fb102a6052
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-ctor.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Behavior when the @@species attribute is a non-constructor object
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 7. If Type(C) is Object, then
+ a. Let C be ? Get(C, @@species).
+ b. If C is null, let C be undefined.
+ [...]
+ 9. If IsConstructor(C) is false, throw a TypeError exception.
+includes: [isConstructor.js]
+features: [Symbol.species, Reflect.construct]
+---*/
+
+assert.sameValue(
+ isConstructor(parseInt),
+ false,
+ 'precondition: isConstructor(parseInt) must return false'
+);
+
+var a = [];
+
+a.constructor = {};
+a.constructor[Symbol.species] = parseInt;
+
+assert.throws(TypeError, function() {
+ a.concat();
+}, 'a.concat() throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible-spreadable.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible-spreadable.js
new file mode 100644
index 0000000000..f2d43b7293
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible-spreadable.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ TypeError is thrown if CreateDataProperty fails.
+ (result object is non-extensible, argument is spreadable)
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ iv. Repeat, while k < len
+ [...]
+ 3. If exists is true, then
+ [...]
+ b. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), subElement).
+ [...]
+
+ CreateDataPropertyOrThrow ( O, P, V )
+
+ [...]
+ 3. Let success be ? CreateDataProperty(O, P, V).
+ 4. If success is false, throw a TypeError exception.
+features: [Symbol.species]
+---*/
+
+var A = function(_length) {
+ this.length = 0;
+ Object.preventExtensions(this);
+};
+
+var arr = [];
+arr.constructor = {};
+arr.constructor[Symbol.species] = A;
+
+assert.throws(TypeError, function() {
+ arr.concat([1]);
+}, 'arr.concat([1]) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible.js
new file mode 100644
index 0000000000..a3bb4f0a60
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-non-extensible.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ TypeError is thrown if CreateDataProperty fails.
+ (result object is non-extensible, argument is not spreadable)
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ d. Else,
+ [...]
+ iii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), E).
+ [...]
+
+ CreateDataPropertyOrThrow ( O, P, V )
+
+ [...]
+ 3. Let success be ? CreateDataProperty(O, P, V).
+ 4. If success is false, throw a TypeError exception.
+features: [Symbol.species]
+---*/
+
+var A = function(_length) {
+ this.length = 0;
+ Object.preventExtensions(this);
+};
+
+var arr = [];
+arr.constructor = {};
+arr.constructor[Symbol.species] = A;
+
+assert.throws(TypeError, function() {
+ arr.concat(1);
+}, 'arr.concat(1) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-null.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-null.js
new file mode 100644
index 0000000000..0d0e7c7350
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-null.js
@@ -0,0 +1,38 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ A null value for the @@species constructor is interpreted as `undefined`
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 7. If Type(C) is Object, then
+ a. Let C be ? Get(C, @@species).
+ b. If C is null, let C be undefined.
+ 8. If C is undefined, return ? ArrayCreate(length).
+features: [Symbol.species]
+---*/
+
+var a = [];
+var result;
+
+a.constructor = {};
+a.constructor[Symbol.species] = null;
+
+result = a.concat();
+
+assert.sameValue(
+ Object.getPrototypeOf(result),
+ Array.prototype,
+ 'Object.getPrototypeOf(a.concat()) returns Array.prototype'
+);
+assert(Array.isArray(result), 'Array.isArray(result) must return true');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-poisoned.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-poisoned.js
new file mode 100644
index 0000000000..a4f8cfe80a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-poisoned.js
@@ -0,0 +1,33 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Abrupt completion from `@@species` property access
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 7. If Type(C) is Object, then
+ a. Let C be ? Get(C, @@species).
+features: [Symbol.species]
+---*/
+
+var a = [];
+a.constructor = {};
+
+Object.defineProperty(a.constructor, Symbol.species, {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ a.concat();
+}, 'a.concat() throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-undef.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-undef.js
new file mode 100644
index 0000000000..0c64e02017
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-undef.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ An undefined value for the @@species constructor triggers the creation of
+ an Array exotic object
+info: |
+ [...]
+ 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount).
+ [...]
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 7. If Type(C) is Object, then
+ a. Let C be ? Get(C, @@species).
+ b. If C is null, let C be undefined.
+ 8. If C is undefined, return ? ArrayCreate(length).
+features: [Symbol.species]
+---*/
+
+var a = [];
+var result;
+
+a.constructor = {};
+a.constructor[Symbol.species] = undefined;
+
+result = a.concat();
+
+assert.sameValue(
+ Object.getPrototypeOf(result),
+ Array.prototype,
+ 'Object.getPrototypeOf(a.concat()) returns Array.prototype'
+);
+assert(Array.isArray(result), 'Array.isArray(result) must return true');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property-spreadable.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property-spreadable.js
new file mode 100644
index 0000000000..49bbd170f4
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property-spreadable.js
@@ -0,0 +1,47 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ TypeError is thrown if CreateDataProperty fails.
+ (result object's "0" is non-configurable, argument is spreadable)
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ iv. Repeat, while k < len
+ [...]
+ 3. If exists is true, then
+ [...]
+ b. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), subElement).
+ [...]
+
+ CreateDataPropertyOrThrow ( O, P, V )
+
+ [...]
+ 3. Let success be ? CreateDataProperty(O, P, V).
+ 4. If success is false, throw a TypeError exception.
+features: [Symbol.species]
+---*/
+
+var A = function(_length) {
+ Object.defineProperty(this, "0", {
+ writable: true,
+ configurable: false,
+ });
+};
+
+var arr = [];
+arr.constructor = {};
+arr.constructor[Symbol.species] = A;
+
+assert.throws(TypeError, function() {
+ arr.concat([1]);
+}, 'arr.concat([1]) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property.js
new file mode 100644
index 0000000000..cbb724f417
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-configurable-property.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ TypeError is thrown if CreateDataProperty fails.
+ (result object's "0" is non-configurable, argument is non-spreadable)
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ d. Else,
+ [...]
+ iii. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), E).
+ [...]
+
+ CreateDataPropertyOrThrow ( O, P, V )
+
+ [...]
+ 3. Let success be ? CreateDataProperty(O, P, V).
+ 4. If success is false, throw a TypeError exception.
+features: [Symbol.species]
+---*/
+
+var A = function(_length) {
+ Object.defineProperty(this, "0", {
+ set: function(_value) {},
+ configurable: false,
+ });
+};
+
+var arr = [];
+arr.constructor = {};
+arr.constructor[Symbol.species] = A;
+
+assert.throws(TypeError, function() {
+ arr.concat(1);
+}, 'arr.concat(1) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property-spreadable.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property-spreadable.js
new file mode 100644
index 0000000000..98e0efc10d
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property-spreadable.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Non-writable properties are overwritten by CreateDataProperty.
+ (result object's "0" is non-writable, argument is spreadable)
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ iv. Repeat, while k < len
+ [...]
+ 3. If exists is true, then
+ [...]
+ b. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), subElement).
+ [...]
+features: [Symbol.species]
+includes: [propertyHelper.js]
+---*/
+
+var A = function(_length) {
+ Object.defineProperty(this, "0", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ });
+};
+
+var arr = [];
+arr.constructor = {};
+arr.constructor[Symbol.species] = A;
+
+var res = arr.concat([2]);
+
+verifyProperty(res, "0", {
+ value: 2,
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property.js
new file mode 100644
index 0000000000..b9268c91b3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species-with-non-writable-property.js
@@ -0,0 +1,49 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Non-writable properties are overwritten by CreateDataProperty.
+ (result object's "0" is non-writable, argument is not spreadable)
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ [...]
+ 5. Repeat, while items is not empty
+ [...]
+ c. If spreadable is true, then
+ [...]
+ iv. Repeat, while k < len
+ [...]
+ 3. If exists is true, then
+ [...]
+ b. Perform ? CreateDataPropertyOrThrow(A, ! ToString(n), subElement).
+ [...]
+features: [Symbol.species]
+includes: [propertyHelper.js]
+---*/
+
+var A = function(_length) {
+ Object.defineProperty(this, "0", {
+ value: 1,
+ writable: false,
+ enumerable: false,
+ configurable: true,
+ });
+};
+
+var arr = [];
+arr.constructor = {};
+arr.constructor[Symbol.species] = A;
+
+var res = arr.concat(2);
+
+verifyProperty(res, "0", {
+ value: 2,
+ writable: true,
+ enumerable: true,
+ configurable: true,
+});
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/create-species.js b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species.js
new file mode 100644
index 0000000000..60cc7138a5
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/create-species.js
@@ -0,0 +1,48 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Species constructor is used to create a new instance
+info: |
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+
+ 9.4.2.3 ArraySpeciesCreate
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+ 7. If Type(C) is Object, then
+ a. Let C be ? Get(C, @@species).
+ b. If C is null, let C be undefined.
+ [...]
+ 10. Return ? Construct(C, « length »).
+features: [Symbol.species]
+---*/
+
+var thisValue, args, result;
+var callCount = 0;
+var instance = [];
+var Ctor = function() {
+ callCount += 1;
+ thisValue = this;
+ args = arguments;
+ return instance;
+};
+var a = [];
+a.constructor = {};
+a.constructor[Symbol.species] = Ctor;
+
+result = a.concat();
+
+assert.sameValue(callCount, 1, 'The value of callCount is expected to be 1');
+assert.sameValue(
+ Object.getPrototypeOf(thisValue),
+ Ctor.prototype,
+ 'Object.getPrototypeOf(this) returns Ctor.prototype'
+);
+assert.sameValue(args.length, 1, 'The value of args.length is expected to be 1');
+assert.sameValue(args[0], 0, 'The value of args[0] is expected to be 0');
+assert.sameValue(result, instance, 'The value of result is expected to equal the value of instance');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-err.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-err.js
new file mode 100644
index 0000000000..e45bbd57ac
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-err.js
@@ -0,0 +1,40 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: Error thrown when accessing `Symbol.isConcatSpreadable` property
+info: |
+ 1. Let O be ToObject(this value).
+ 2. ReturnIfAbrupt(O).
+ 3. Let A be ArraySpeciesCreate(O, 0).
+ 4. ReturnIfAbrupt(A).
+ 5. Let n be 0.
+ 6. Let items be a List whose first element is O and whose subsequent
+ elements are, in left to right order, the arguments that were passed to
+ this function invocation.
+ 7. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the element.
+ b. Let spreadable be IsConcatSpreadable(E).
+ c. ReturnIfAbrupt(spreadable).
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be Get(O, @@isConcatSpreadable).
+ 3. ReturnIfAbrupt(spreadable).
+features: [Symbol.isConcatSpreadable]
+---*/
+
+var o = {};
+
+Object.defineProperty(o, Symbol.isConcatSpreadable, {
+ get: function() {
+ throw new Test262Error();
+ }
+});
+
+assert.throws(Test262Error, function() {
+ Array.prototype.concat.call(o);
+}, 'Array.prototype.concat.call(o) throws a Test262Error exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-order.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-order.js
new file mode 100644
index 0000000000..847dee557b
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-get-order.js
@@ -0,0 +1,75 @@
+// Copyright (C) 2020 Alexey Shvayka. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Symbol.isConcatSpreadable should be looked up once for `this value` and
+ once for each argument, after ArraySpeciesCreate routine.
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ 1. Let O be ? ToObject(this value).
+ 2. Let A be ? ArraySpeciesCreate(O, 0).
+ [...]
+ 5. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the element.
+ b. Let spreadable be ? IsConcatSpreadable(E).
+ [...]
+
+ ArraySpeciesCreate ( originalArray, length )
+
+ [...]
+ 5. Let C be ? Get(originalArray, "constructor").
+ [...]
+
+ Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be ? Get(O, @@isConcatSpreadable).
+ [...]
+includes: [compareArray.js]
+features: [Symbol.isConcatSpreadable]
+---*/
+
+var calls = [];
+var descConstructor = {
+ get: function() {
+ calls.push("constructor");
+ return Array;
+ },
+ configurable: true,
+};
+var descSpreadable = {
+ get: function() {
+ calls.push("isConcatSpreadable");
+ },
+ configurable: true,
+};
+
+var arr1 = [];
+Object.defineProperty(arr1, "constructor", descConstructor);
+Object.defineProperty(arr1, Symbol.isConcatSpreadable, descSpreadable);
+
+assert.compareArray(arr1.concat(1), [1], 'arr1.concat(1) must return [1]');
+assert.compareArray(
+ calls,
+ ["constructor", "isConcatSpreadable"],
+ 'The value of calls is expected to be ["constructor", "isConcatSpreadable"]'
+);
+
+calls = [];
+
+var arr2 = [];
+var arg = {};
+Object.defineProperty(arr2, "constructor", descConstructor);
+Object.defineProperty(arg, Symbol.isConcatSpreadable, descSpreadable);
+
+assert.compareArray(arr2.concat(arg), [arg], 'arr2.concat({}) must return [arg]');
+assert.compareArray(
+ calls,
+ ["constructor", "isConcatSpreadable"],
+ 'The value of calls is expected to be ["constructor", "isConcatSpreadable"]'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-is-array-proxy-revoked.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-is-array-proxy-revoked.js
new file mode 100644
index 0000000000..e242f57045
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-is-array-proxy-revoked.js
@@ -0,0 +1,52 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-isconcatspreadable
+description: Revoked proxy value produces a TypeError when supplied to IsArray
+info: |
+ [...]
+ 5. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the
+ element.
+ b. Let spreadable be ? IsConcatSpreadable(E).
+ c. If spreadable is true, then
+ [...]
+ e. Else E is added as a single item rather than spread,
+ [...]
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be ? Get(O, @@isConcatSpreadable).
+ 3. If spreadable is not undefined, return ToBoolean(spreadable).
+ 4. Return ? IsArray(O).
+
+ 7.2.2 IsArray
+
+ [...]
+ 3. If argument is a Proxy exotic object, then
+ a. If the value of the [[ProxyHandler]] internal slot of argument is null,
+ throw a TypeError exception.
+ b. Let target be the value of the [[ProxyTarget]] internal slot of
+ argument.
+ c. Return ? IsArray(target).
+features: [Proxy, Symbol.isConcatSpreadable]
+---*/
+
+var target = [];
+var handle = Proxy.revocable(target, {
+ get: function(_, key) {
+ // Defer proxy revocation until after property access to ensure that the
+ // expected TypeError originates from the IsArray operation.
+ if (key === Symbol.isConcatSpreadable) {
+ handle.revoke();
+ }
+ return target[key];
+ }
+});
+
+assert.throws(TypeError, function() {
+ [].concat(handle.proxy);
+}, '[].concat(handle.proxy) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy-revoked.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy-revoked.js
new file mode 100644
index 0000000000..41f4bfb6c3
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy-revoked.js
@@ -0,0 +1,45 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-isconcatspreadable
+description: >
+ Revoked proxy value produces a TypeError during access of
+ `Symbol.isConcatSpreadable` property
+info: |
+ [...]
+ 5. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the
+ element.
+ b. Let spreadable be ? IsConcatSpreadable(E).
+ c. If spreadable is true, then
+ [...]
+ e. Else E is added as a single item rather than spread,
+ [...]
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be ? Get(O, @@isConcatSpreadable).
+
+ 7.3.1 Get
+
+ [...]
+ 3. Return ? O.[[Get]](P, O).
+
+ 9.5.8 [[Get]]
+
+ [...]
+ 2. Let handler be O.[[ProxyHandler]].
+ 3. If handler is null, throw a TypeError exception.
+features: [Proxy]
+---*/
+
+var handle = Proxy.revocable([], {});
+
+handle.revoke();
+
+assert.throws(TypeError, function() {
+ [].concat(handle.proxy);
+}, '[].concat(handle.proxy) throws a TypeError exception');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy.js
new file mode 100644
index 0000000000..52dde72e68
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-proxy.js
@@ -0,0 +1,53 @@
+// Copyright (C) 2016 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-isconcatspreadable
+description: >
+ Proxies who final targets are arrays are considered spreadable
+info: |
+ [...]
+ 5. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the
+ element.
+ b. Let spreadable be ? IsConcatSpreadable(E).
+ c. If spreadable is true, then
+ [...]
+ e. Else E is added as a single item rather than spread,
+ [...]
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be ? Get(O, @@isConcatSpreadable).
+ 3. If spreadable is not undefined, return ToBoolean(spreadable).
+ 4. Return ? IsArray(O).
+
+ 7.2.2 IsArray
+
+ [...]
+ 3. If argument is a Proxy exotic object, then
+ a. If the value of the [[ProxyHandler]] internal slot of argument is null,
+ throw a TypeError exception.
+ b. Let target be the value of the [[ProxyTarget]] internal slot of
+ argument.
+ c. Return ? IsArray(target).
+features: [Proxy, Symbol.isConcatSpreadable]
+---*/
+
+var arrayProxy = new Proxy([], {});
+var arrayProxyProxy = new Proxy(arrayProxy, {});
+var spreadable = {};
+spreadable[Symbol.isConcatSpreadable] = true;
+var spreadableProxy = new Proxy(spreadable, {});
+
+assert.sameValue([].concat(arrayProxy).length, 0, 'The value of [].concat(arrayProxy).length is expected to be 0');
+assert.sameValue(
+ [].concat(arrayProxyProxy).length, 0, 'The value of [].concat(arrayProxyProxy).length is expected to be 0'
+);
+assert.sameValue(
+ [].concat(spreadableProxy).length,
+ 0,
+ 'The value of [].concat(spreadableProxy).length is expected to be 0'
+);
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-falsey.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-falsey.js
new file mode 100644
index 0000000000..c565bac64a
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-falsey.js
@@ -0,0 +1,57 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ The `Symbol.isConcatSpreadable` property is defined and coerces to `false`
+info: |
+ 1. Let O be ToObject(this value).
+ 2. ReturnIfAbrupt(O).
+ 3. Let A be ArraySpeciesCreate(O, 0).
+ 4. ReturnIfAbrupt(A).
+ 5. Let n be 0.
+ 6. Let items be a List whose first element is O and whose subsequent
+ elements are, in left to right order, the arguments that were passed to
+ this function invocation.
+ 7. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the element.
+ b. Let spreadable be IsConcatSpreadable(E).
+ c. ReturnIfAbrupt(spreadable).
+ d. If spreadable is true, then
+ [...]
+ e. Else E is added as a single item rather than spread,
+ [...]
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be Get(O, @@isConcatSpreadable).
+ 3. ReturnIfAbrupt(spreadable).
+ 4. If spreadable is not undefined, return ToBoolean(spreadable).
+features: [Symbol.isConcatSpreadable]
+---*/
+
+var item = [1, 2];
+var result;
+
+item[Symbol.isConcatSpreadable] = null;
+result = [].concat(item);
+assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1');
+assert.sameValue(result[0], item, 'The value of result[0] is expected to equal the value of item');
+
+item[Symbol.isConcatSpreadable] = false;
+result = [].concat(item);
+assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1');
+assert.sameValue(result[0], item, 'The value of result[0] is expected to equal the value of item');
+
+item[Symbol.isConcatSpreadable] = 0;
+result = [].concat(item);
+assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1');
+assert.sameValue(result[0], item, 'The value of result[0] is expected to equal the value of item');
+
+item[Symbol.isConcatSpreadable] = NaN;
+result = [].concat(item);
+assert.sameValue(result.length, 1, 'The value of result.length is expected to be 1');
+assert.sameValue(result[0], item, 'The value of result[0] is expected to equal the value of item');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-truthy.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-truthy.js
new file mode 100644
index 0000000000..9f08bfe6b6
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-truthy.js
@@ -0,0 +1,55 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ The `Symbol.isConcatSpreadable` property is defined and coerces to `true`
+info: |
+ 1. Let O be ToObject(this value).
+ 2. ReturnIfAbrupt(O).
+ 3. Let A be ArraySpeciesCreate(O, 0).
+ 4. ReturnIfAbrupt(A).
+ 5. Let n be 0.
+ 6. Let items be a List whose first element is O and whose subsequent
+ elements are, in left to right order, the arguments that were passed to
+ this function invocation.
+ 7. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the element.
+ b. Let spreadable be IsConcatSpreadable(E).
+ c. ReturnIfAbrupt(spreadable).
+ d. If spreadable is true, then
+ [...]
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be Get(O, @@isConcatSpreadable).
+ 3. ReturnIfAbrupt(spreadable).
+ 4. If spreadable is not undefined, return ToBoolean(spreadable).
+features: [Symbol, Symbol.isConcatSpreadable]
+---*/
+
+var item = {};
+var result;
+
+item[Symbol.isConcatSpreadable] = true;
+result = [].concat(item);
+assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+
+item[Symbol.isConcatSpreadable] = 86;
+result = [].concat(item);
+assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+
+item[Symbol.isConcatSpreadable] = 'string';
+result = [].concat(item);
+assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+
+item[Symbol.isConcatSpreadable] = Symbol();
+result = [].concat(item);
+assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+
+item[Symbol.isConcatSpreadable] = {};
+result = [].concat(item);
+assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-undefined.js b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-undefined.js
new file mode 100644
index 0000000000..9a66a6a168
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/is-concat-spreadable-val-undefined.js
@@ -0,0 +1,43 @@
+// Copyright (C) 2015 the V8 project authors. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+/*---
+esid: sec-array.prototype.concat
+description: >
+ The `Symbol.isConcatSpreadable` property is defined as the value `undefined`
+info: |
+ 1. Let O be ToObject(this value).
+ 2. ReturnIfAbrupt(O).
+ 3. Let A be ArraySpeciesCreate(O, 0).
+ 4. ReturnIfAbrupt(A).
+ 5. Let n be 0.
+ 6. Let items be a List whose first element is O and whose subsequent
+ elements are, in left to right order, the arguments that were passed to
+ this function invocation.
+ 7. Repeat, while items is not empty
+ a. Remove the first element from items and let E be the value of the element.
+ b. Let spreadable be IsConcatSpreadable(E).
+ c. ReturnIfAbrupt(spreadable).
+ d. If spreadable is true, then
+ [...]
+ e. Else E is added as a single item rather than spread,
+ [...]
+
+ ES6 22.1.3.1.1: Runtime Semantics: IsConcatSpreadable ( O )
+
+ 1. If Type(O) is not Object, return false.
+ 2. Let spreadable be Get(O, @@isConcatSpreadable).
+ 3. ReturnIfAbrupt(spreadable).
+ 4. If spreadable is not undefined, return ToBoolean(spreadable).
+ 5. Return IsArray(O).
+features: [Symbol.isConcatSpreadable]
+---*/
+
+var item = [];
+var result;
+
+item[Symbol.isConcatSpreadable] = undefined;
+result = [].concat(item);
+
+assert.sameValue(result.length, 0, 'The value of result.length is expected to be 0');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/length.js b/js/src/tests/test262/built-ins/Array/prototype/concat/length.js
new file mode 100644
index 0000000000..5bff590dfd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/length.js
@@ -0,0 +1,34 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ The "length" property of Array.prototype.concat
+info: |
+ 22.1.3.1 Array.prototype.concat ( ...arguments )
+
+ The length property of the concat method is 1.
+
+ 17 ECMAScript Standard Built-in Objects
+
+ Every built-in function object, including constructors, has a length property
+ whose value is an integer. Unless otherwise specified, this value is equal to
+ the largest number of named arguments shown in the subclause headings for the
+ function description. Optional parameters (which are indicated with brackets:
+ [ ]) or rest parameters (which are shown using the form «...name») are not
+ included in the default argument count.
+
+ Unless otherwise specified, the length property of a built-in function object
+ has the attributes { [[Writable]]: false, [[Enumerable]]: false,
+ [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(Array.prototype.concat.length, 1, 'The value of Array.prototype.concat.length is expected to be 1');
+
+verifyNotEnumerable(Array.prototype.concat, 'length');
+verifyNotWritable(Array.prototype.concat, 'length');
+verifyConfigurable(Array.prototype.concat, 'length');
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/name.js b/js/src/tests/test262/built-ins/Array/prototype/concat/name.js
new file mode 100644
index 0000000000..f81660ad08
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/name.js
@@ -0,0 +1,32 @@
+// Copyright (C) 2015 André Bargull. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ Array.prototype.concat.name is "concat".
+info: |
+ Array.prototype.concat ( ...arguments )
+
+ 17 ECMAScript Standard Built-in Objects:
+ Every built-in Function object, including constructors, that is not
+ identified as an anonymous function has a name property whose value
+ is a String.
+
+ Unless otherwise specified, the name property of a built-in Function
+ object, if it exists, has the attributes { [[Writable]]: false,
+ [[Enumerable]]: false, [[Configurable]]: true }.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(
+ Array.prototype.concat.name,
+ "concat",
+ 'The value of Array.prototype.concat.name is expected to be "concat"'
+);
+
+verifyNotEnumerable(Array.prototype.concat, "name");
+verifyNotWritable(Array.prototype.concat, "name");
+verifyConfigurable(Array.prototype.concat, "name");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/not-a-constructor.js b/js/src/tests/test262/built-ins/Array/prototype/concat/not-a-constructor.js
new file mode 100644
index 0000000000..10bdab75dd
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/not-a-constructor.js
@@ -0,0 +1,35 @@
+// Copyright (C) 2020 Rick Waldron. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-ecmascript-standard-built-in-objects
+description: >
+ Array.prototype.concat does not implement [[Construct]], is not new-able
+info: |
+ ECMAScript Function Objects
+
+ Built-in function objects that are not identified as constructors do not
+ implement the [[Construct]] internal method unless otherwise specified in
+ the description of a particular function.
+
+ sec-evaluatenew
+
+ ...
+ 7. If IsConstructor(constructor) is false, throw a TypeError exception.
+ ...
+includes: [isConstructor.js]
+features: [Reflect.construct, arrow-function]
+---*/
+
+assert.sameValue(
+ isConstructor(Array.prototype.concat),
+ false,
+ 'isConstructor(Array.prototype.concat) must return false'
+);
+
+assert.throws(TypeError, () => {
+ new Array.prototype.concat([]);
+}, 'new Array.prototype.concat([]) throws a TypeError exception');
+
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/prop-desc.js b/js/src/tests/test262/built-ins/Array/prototype/concat/prop-desc.js
new file mode 100644
index 0000000000..6dc2ebc718
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/prop-desc.js
@@ -0,0 +1,23 @@
+// Copyright (C) 2017 Leo Balter. All rights reserved.
+// This code is governed by the BSD license found in the LICENSE file.
+
+/*---
+esid: sec-array.prototype.concat
+description: >
+ "concat" property of Array.prototype
+info: |
+ 17 ECMAScript Standard Built-in Objects
+
+ Every other data property described in clauses 18 through 26 and in Annex B.2
+ has the attributes { [[Writable]]: true, [[Enumerable]]: false,
+ [[Configurable]]: true } unless otherwise specified.
+includes: [propertyHelper.js]
+---*/
+
+assert.sameValue(typeof Array.prototype.concat, 'function', 'The value of `typeof Array.prototype.concat` is expected to be "function"');
+
+verifyNotEnumerable(Array.prototype, "concat");
+verifyWritable(Array.prototype, "concat");
+verifyConfigurable(Array.prototype, "concat");
+
+reportCompare(0, 0);
diff --git a/js/src/tests/test262/built-ins/Array/prototype/concat/shell.js b/js/src/tests/test262/built-ins/Array/prototype/concat/shell.js
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/js/src/tests/test262/built-ins/Array/prototype/concat/shell.js