From 4980fd264e49aab0fe0193ecd08f41890292a1ae Mon Sep 17 00:00:00 2001 From: jugglinmike Date: Tue, 3 May 2016 12:42:38 -0400 Subject: [PATCH] Add tests for ArraySpeciesCreate (#600) Assert the expected behavior of the ArraySpeciesCreate abstract operation in the 5 Array instance methods from which it is invoked. This change set does not include tests for ECMAScript realm considerations because Test262 does not currently expose a mechanism for interfacing with realms. --- .../concat/create-ctor-non-object.js | 43 ++++++++++++++ .../prototype/concat/create-ctor-poisoned.js | 27 +++++++++ .../prototype/concat/create-non-array.js | 33 +++++++++++ .../prototype/concat/create-revoked-proxy.js | 39 +++++++++++++ .../prototype/concat/create-species-abrupt.js | 33 +++++++++++ .../concat/create-species-non-ctor.js | 32 ++++++++++ .../prototype/concat/create-species-null.js | 33 +++++++++++ .../concat/create-species-poisoned.js | 32 ++++++++++ .../prototype/concat/create-species-undef.js | 35 +++++++++++ .../Array/prototype/concat/create-species.js | 43 ++++++++++++++ .../filter/create-ctor-non-object.js | 50 ++++++++++++++++ .../prototype/filter/create-ctor-poisoned.js | 31 ++++++++++ .../prototype/filter/create-non-array.js | 33 +++++++++++ .../prototype/filter/create-revoked-proxy.js | 43 ++++++++++++++ .../prototype/filter/create-species-abrupt.js | 37 ++++++++++++ .../filter/create-species-non-ctor.js | 36 ++++++++++++ .../prototype/filter/create-species-null.js | 34 +++++++++++ .../filter/create-species-poisoned.js | 36 ++++++++++++ .../prototype/filter/create-species-undef.js | 35 +++++++++++ .../Array/prototype/filter/create-species.js | 44 ++++++++++++++ .../prototype/map/create-ctor-non-object.js | 50 ++++++++++++++++ .../prototype/map/create-ctor-poisoned.js | 31 ++++++++++ .../map/create-non-array-invalid-len.js | 38 ++++++++++++ .../Array/prototype/map/create-non-array.js | 32 ++++++++++ .../prototype/map/create-revoked-proxy.js | 43 ++++++++++++++ .../prototype/map/create-species-abrupt.js | 37 ++++++++++++ .../prototype/map/create-species-non-ctor.js | 36 ++++++++++++ .../prototype/map/create-species-null.js | 34 +++++++++++ .../prototype/map/create-species-poisoned.js | 36 ++++++++++++ .../map/create-species-undef-invalid-len.js | 58 +++++++++++++++++++ .../prototype/map/create-species-undef.js | 35 +++++++++++ .../Array/prototype/map/create-species.js | 44 ++++++++++++++ .../prototype/slice/create-ctor-non-object.js | 44 ++++++++++++++ .../prototype/slice/create-ctor-poisoned.js | 28 +++++++++ .../slice/create-non-array-invalid-len.js | 43 ++++++++++++++ .../Array/prototype/slice/create-non-array.js | 32 ++++++++++ .../prototype/slice/create-revoked-proxy.js | 40 +++++++++++++ .../prototype/slice/create-species-abrupt.js | 34 +++++++++++ .../slice/create-species-neg-zero.js | 46 +++++++++++++++ .../slice/create-species-non-ctor.js | 33 +++++++++++ .../prototype/slice/create-species-null.js | 34 +++++++++++ .../slice/create-species-poisoned.js | 33 +++++++++++ .../slice/create-species-undef-invalid-len.js | 55 ++++++++++++++++++ .../prototype/slice/create-species-undef.js | 35 +++++++++++ .../Array/prototype/slice/create-species.js | 44 ++++++++++++++ .../splice/create-ctor-non-object.js | 44 ++++++++++++++ .../prototype/splice/create-ctor-poisoned.js | 28 +++++++++ .../splice/create-non-array-invalid-len.js | 43 ++++++++++++++ .../prototype/splice/create-non-array.js | 33 +++++++++++ .../prototype/splice/create-revoked-proxy.js | 40 +++++++++++++ .../prototype/splice/create-species-abrupt.js | 34 +++++++++++ .../splice/create-species-neg-zero.js | 50 ++++++++++++++++ .../splice/create-species-non-ctor.js | 33 +++++++++++ .../prototype/splice/create-species-null.js | 34 +++++++++++ .../splice/create-species-poisoned.js | 33 +++++++++++ .../create-species-undef-invalid-len.js | 55 ++++++++++++++++++ .../prototype/splice/create-species-undef.js | 35 +++++++++++ .../Array/prototype/splice/create-species.js | 44 ++++++++++++++ 58 files changed, 2210 insertions(+) create mode 100644 test/built-ins/Array/prototype/concat/create-ctor-non-object.js create mode 100644 test/built-ins/Array/prototype/concat/create-ctor-poisoned.js create mode 100644 test/built-ins/Array/prototype/concat/create-non-array.js create mode 100644 test/built-ins/Array/prototype/concat/create-revoked-proxy.js create mode 100644 test/built-ins/Array/prototype/concat/create-species-abrupt.js create mode 100644 test/built-ins/Array/prototype/concat/create-species-non-ctor.js create mode 100644 test/built-ins/Array/prototype/concat/create-species-null.js create mode 100644 test/built-ins/Array/prototype/concat/create-species-poisoned.js create mode 100644 test/built-ins/Array/prototype/concat/create-species-undef.js create mode 100644 test/built-ins/Array/prototype/concat/create-species.js create mode 100644 test/built-ins/Array/prototype/filter/create-ctor-non-object.js create mode 100644 test/built-ins/Array/prototype/filter/create-ctor-poisoned.js create mode 100644 test/built-ins/Array/prototype/filter/create-non-array.js create mode 100644 test/built-ins/Array/prototype/filter/create-revoked-proxy.js create mode 100644 test/built-ins/Array/prototype/filter/create-species-abrupt.js create mode 100644 test/built-ins/Array/prototype/filter/create-species-non-ctor.js create mode 100644 test/built-ins/Array/prototype/filter/create-species-null.js create mode 100644 test/built-ins/Array/prototype/filter/create-species-poisoned.js create mode 100644 test/built-ins/Array/prototype/filter/create-species-undef.js create mode 100644 test/built-ins/Array/prototype/filter/create-species.js create mode 100644 test/built-ins/Array/prototype/map/create-ctor-non-object.js create mode 100644 test/built-ins/Array/prototype/map/create-ctor-poisoned.js create mode 100644 test/built-ins/Array/prototype/map/create-non-array-invalid-len.js create mode 100644 test/built-ins/Array/prototype/map/create-non-array.js create mode 100644 test/built-ins/Array/prototype/map/create-revoked-proxy.js create mode 100644 test/built-ins/Array/prototype/map/create-species-abrupt.js create mode 100644 test/built-ins/Array/prototype/map/create-species-non-ctor.js create mode 100644 test/built-ins/Array/prototype/map/create-species-null.js create mode 100644 test/built-ins/Array/prototype/map/create-species-poisoned.js create mode 100644 test/built-ins/Array/prototype/map/create-species-undef-invalid-len.js create mode 100644 test/built-ins/Array/prototype/map/create-species-undef.js create mode 100644 test/built-ins/Array/prototype/map/create-species.js create mode 100644 test/built-ins/Array/prototype/slice/create-ctor-non-object.js create mode 100644 test/built-ins/Array/prototype/slice/create-ctor-poisoned.js create mode 100644 test/built-ins/Array/prototype/slice/create-non-array-invalid-len.js create mode 100644 test/built-ins/Array/prototype/slice/create-non-array.js create mode 100644 test/built-ins/Array/prototype/slice/create-revoked-proxy.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-abrupt.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-neg-zero.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-non-ctor.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-null.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-poisoned.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-undef-invalid-len.js create mode 100644 test/built-ins/Array/prototype/slice/create-species-undef.js create mode 100644 test/built-ins/Array/prototype/slice/create-species.js create mode 100644 test/built-ins/Array/prototype/splice/create-ctor-non-object.js create mode 100644 test/built-ins/Array/prototype/splice/create-ctor-poisoned.js create mode 100644 test/built-ins/Array/prototype/splice/create-non-array-invalid-len.js create mode 100644 test/built-ins/Array/prototype/splice/create-non-array.js create mode 100644 test/built-ins/Array/prototype/splice/create-revoked-proxy.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-abrupt.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-neg-zero.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-non-ctor.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-null.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-poisoned.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-undef-invalid-len.js create mode 100644 test/built-ins/Array/prototype/splice/create-species-undef.js create mode 100644 test/built-ins/Array/prototype/splice/create-species.js diff --git a/test/built-ins/Array/prototype/concat/create-ctor-non-object.js b/test/built-ins/Array/prototype/concat/create-ctor-non-object.js new file mode 100644 index 0000000000..fe8e058654 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-ctor-non-object.js @@ -0,0 +1,43 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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(); +}, 'null value'); + +a = []; +a.constructor = 1; +assert.throws(TypeError, function() { + a.concat(); +}, 'number value'); + +a = []; +a.constructor = 'string'; +assert.throws(TypeError, function() { + a.concat(); +}, 'string value'); + +a = []; +a.constructor = true; +assert.throws(TypeError, function() { + a.concat(); +}, 'boolean value'); diff --git a/test/built-ins/Array/prototype/concat/create-ctor-poisoned.js b/test/built-ins/Array/prototype/concat/create-ctor-poisoned.js new file mode 100644 index 0000000000..672d33acc5 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-ctor-poisoned.js @@ -0,0 +1,27 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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(); +}); diff --git a/test/built-ins/Array/prototype/concat/create-non-array.js b/test/built-ins/Array/prototype/concat/create-non-array.js new file mode 100644 index 0000000000..171e2baab4 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-non-array.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. +/*--- +es6id: 22.1.3.1 +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, '`constructor` property not accessed'); +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); +assert.sameValue(result.length, 1, 'array created with appropriate length'); +assert.sameValue(result[0], obj); diff --git a/test/built-ins/Array/prototype/concat/create-revoked-proxy.js b/test/built-ins/Array/prototype/concat/create-revoked-proxy.js new file mode 100644 index 0000000000..fb18d87a41 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-revoked-proxy.js @@ -0,0 +1,39 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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); +}); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); diff --git a/test/built-ins/Array/prototype/concat/create-species-abrupt.js b/test/built-ins/Array/prototype/concat/create-species-abrupt.js new file mode 100644 index 0000000000..3a89c85bfc --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-species-abrupt.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. +/*--- +es6id: 22.1.3.1 +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(); +}); diff --git a/test/built-ins/Array/prototype/concat/create-species-non-ctor.js b/test/built-ins/Array/prototype/concat/create-species-non-ctor.js new file mode 100644 index 0000000000..b3cf0fdda2 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-species-non-ctor.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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. +features: [Symbol.species] +---*/ + +var a = []; + +a.constructor = {}; +a.constructor[Symbol.species] = parseInt; + +assert.throws(TypeError, function() { + a.concat(); +}); diff --git a/test/built-ins/Array/prototype/concat/create-species-null.js b/test/built-ins/Array/prototype/concat/create-species-null.js new file mode 100644 index 0000000000..29486b5bb5 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-species-null.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. +/*--- +es6id: 22.1.3.1 +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); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/concat/create-species-poisoned.js b/test/built-ins/Array/prototype/concat/create-species-poisoned.js new file mode 100644 index 0000000000..a6203df1b2 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-species-poisoned.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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(); +}); diff --git a/test/built-ins/Array/prototype/concat/create-species-undef.js b/test/built-ins/Array/prototype/concat/create-species-undef.js new file mode 100644 index 0000000000..6a2aea17ea --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-species-undef.js @@ -0,0 +1,35 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/concat/create-species.js b/test/built-ins/Array/prototype/concat/create-species.js new file mode 100644 index 0000000000..a035008ed1 --- /dev/null +++ b/test/built-ins/Array/prototype/concat/create-species.js @@ -0,0 +1,43 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.1 +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, 'Constructor invoked exactly once'); +assert.sameValue(Object.getPrototypeOf(thisValue), Ctor.prototype); +assert.sameValue(args.length, 1, 'Constructor invoked with a single argument'); +assert.sameValue(args[0], 0); +assert.sameValue(result, instance); diff --git a/test/built-ins/Array/prototype/filter/create-ctor-non-object.js b/test/built-ins/Array/prototype/filter/create-ctor-non-object.js new file mode 100644 index 0000000000..988fed039e --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-ctor-non-object.js @@ -0,0 +1,50 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: > + Behavior when `constructor` property is neither an Object nor undefined +info: | + [...] + 5. 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 = []; +var callCount = 0; +var cb = function() { callCount += 0; }; + +a.constructor = null; +assert.throws(TypeError, function() { + a.filter(cb); +}, 'null value'); +assert.sameValue(callCount, 0, 'callback not invoked (null value)'); + +a = []; +a.constructor = 1; +assert.throws(TypeError, function() { + a.filter(cb); +}, 'number value'); +assert.sameValue(callCount, 0, 'callback not invoked (number value)'); + +a = []; +a.constructor = 'string'; +assert.throws(TypeError, function() { + a.filter(cb); +}, 'string value'); +assert.sameValue(callCount, 0, 'callback not invoked (string value)'); + +a = []; +a.constructor = true; +assert.throws(TypeError, function() { + a.filter(cb); +}, 'boolean value'); +assert.sameValue(callCount, 0, 'callback not invoked (boolean value)'); diff --git a/test/built-ins/Array/prototype/filter/create-ctor-poisoned.js b/test/built-ins/Array/prototype/filter/create-ctor-poisoned.js new file mode 100644 index 0000000000..a766e68961 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-ctor-poisoned.js @@ -0,0 +1,31 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: Abrupt completion from `constructor` property access +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, 0). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 5. Let C be ? Get(originalArray, "constructor"). +---*/ + +var a = []; +var callCount = 0; +var cb = function() { callCount += 1; }; + +Object.defineProperty(a, 'constructor', { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + a.filter(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/filter/create-non-array.js b/test/built-ins/Array/prototype/filter/create-non-array.js new file mode 100644 index 0000000000..32ef7736f7 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-non-array.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. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: Constructor is ignored for non-Array values +info: | + [...] + 5. 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.filter.call(obj, function() {}); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); +assert.sameValue(result.length, 0, 'array created with appropriate length'); diff --git a/test/built-ins/Array/prototype/filter/create-revoked-proxy.js b/test/built-ins/Array/prototype/filter/create-revoked-proxy.js new file mode 100644 index 0000000000..aecf766f9b --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-revoked-proxy.js @@ -0,0 +1,43 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: Abrupt completion from constructor that is a revoked Proxy object +info: | + [...] + 5. 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 ctorCount = 0; +var cbCount = 0; +var cb = function() { cbCount += 1; }; + +Object.defineProperty(o.proxy, 'constructor', { + get: function() { + ctorCount += 1; + } +}); +o.revoke(); + +assert.throws(TypeError, function() { + Array.prototype.filter.call(o.proxy, cb); +}); + +assert.sameValue(ctorCount, 0, '`constructor` property not accessed'); +assert.sameValue(cbCount, 0, 'callback not invoked'); diff --git a/test/built-ins/Array/prototype/filter/create-species-abrupt.js b/test/built-ins/Array/prototype/filter/create-species-abrupt.js new file mode 100644 index 0000000000..42a4f2eda8 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-species-abrupt.js @@ -0,0 +1,37 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: Species constructor returns an abrupt completion +info: | + [...] + 5. 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 callCount = 0; +var cb = function() { callCount += 1; }; +var a = []; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +assert.throws(Test262Error, function() { + a.filter(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/filter/create-species-non-ctor.js b/test/built-ins/Array/prototype/filter/create-species-non-ctor.js new file mode 100644 index 0000000000..cf5fba2ce8 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-species-non-ctor.js @@ -0,0 +1,36 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: > + Behavior when the @@species attribute is a non-constructor object +info: | + [...] + 5. 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. +features: [Symbol.species] +---*/ + +var a = []; +var callCount = 0; +var cb = function() { callCount += 1; }; + +a.constructor = {}; +a.constructor[Symbol.species] = parseInt; + +assert.throws(TypeError, function() { + a.filter(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/filter/create-species-null.js b/test/built-ins/Array/prototype/filter/create-species-null.js new file mode 100644 index 0000000000..8173f4965d --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-species-null.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. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: > + A null value for the @@species constructor is interpreted as `undefined` +info: | + [...] + 5. 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.filter(function() {}); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/filter/create-species-poisoned.js b/test/built-ins/Array/prototype/filter/create-species-poisoned.js new file mode 100644 index 0000000000..9edd338af7 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-species-poisoned.js @@ -0,0 +1,36 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: Abrupt completion from `@@species` property access +info: | + [...] + 5. 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 = []; +var callCount = 0; +var cb = function() { callCount += 1; }; +a.constructor = {}; + +Object.defineProperty(a.constructor, Symbol.species, { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + a.filter(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/filter/create-species-undef.js b/test/built-ins/Array/prototype/filter/create-species-undef.js new file mode 100644 index 0000000000..6ac8e349f5 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-species-undef.js @@ -0,0 +1,35 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: > + An undefined value for the @@species constructor triggers the creation of + an Array exotic object +info: | + [...] + 5. 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] = undefined; + +result = a.filter(function() {}); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/filter/create-species.js b/test/built-ins/Array/prototype/filter/create-species.js new file mode 100644 index 0000000000..01eedd6898 --- /dev/null +++ b/test/built-ins/Array/prototype/filter/create-species.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. +/*--- +es6id: 22.1.3.7 +esid: sec-array.prototype.filter +description: Species constructor is used to create a new instance +info: | + [...] + 5. 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 = [1, 2, 3, 4, 5, 6, 7]; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +result = a.filter(function() {}); + +assert.sameValue(callCount, 1, 'Constructor invoked exactly once'); +assert.sameValue(Object.getPrototypeOf(thisValue), Ctor.prototype); +assert.sameValue(args.length, 1, 'Constructor invoked with a single argument'); +assert.sameValue(args[0], 0); +assert.sameValue(result, instance); diff --git a/test/built-ins/Array/prototype/map/create-ctor-non-object.js b/test/built-ins/Array/prototype/map/create-ctor-non-object.js new file mode 100644 index 0000000000..b020704a2a --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-ctor-non-object.js @@ -0,0 +1,50 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: > + Behavior when `constructor` property is neither an Object nor undefined +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 5. Let C be ? Get(originalArray, "constructor"). + [...] + 9. If IsConstructor(C) is false, throw a TypeError exception. +---*/ + +var a = []; +var callCount = 0; +var cb = function() { callCount += 0; }; + +a.constructor = null; +assert.throws(TypeError, function() { + a.map(cb); +}, 'null value'); +assert.sameValue(callCount, 0, 'callback not invoked (null value)'); + +a = []; +a.constructor = 1; +assert.throws(TypeError, function() { + a.map(cb); +}, 'number value'); +assert.sameValue(callCount, 0, 'callback not invoked (number value)'); + +a = []; +a.constructor = 'string'; +assert.throws(TypeError, function() { + a.map(cb); +}, 'string value'); +assert.sameValue(callCount, 0, 'callback not invoked (string value)'); + +a = []; +a.constructor = true; +assert.throws(TypeError, function() { + a.map(cb); +}, 'boolean value'); +assert.sameValue(callCount, 0, 'callback not invoked (boolean value)'); diff --git a/test/built-ins/Array/prototype/map/create-ctor-poisoned.js b/test/built-ins/Array/prototype/map/create-ctor-poisoned.js new file mode 100644 index 0000000000..f99c51bdd1 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-ctor-poisoned.js @@ -0,0 +1,31 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Abrupt completion from `constructor` property access +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 5. Let C be ? Get(originalArray, "constructor"). +---*/ + +var a = []; +var callCount = 0; +var cb = function() { callCount += 1; }; + +Object.defineProperty(a, 'constructor', { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + a.map(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/map/create-non-array-invalid-len.js b/test/built-ins/Array/prototype/map/create-non-array-invalid-len.js new file mode 100644 index 0000000000..484b77e6f9 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-non-array-invalid-len.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. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Abrupt completion from creating a new array +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 3. Let isArray be ? IsArray(originalArray). + 4. If isArray is false, return ? ArrayCreate(length). + + 9.4.2.2 ArrayCreate + + [...] + 3. If length>232-1, throw a RangeError exception. +---*/ + +var callCount = 0; +var obj = { length: Math.pow(2, 32) }; +var cb = function() { + callCount += 1; +}; + +assert.throws(RangeError, function() { + Array.prototype.map.call(obj, cb); +}); + +assert.sameValue( + callCount, + 0, + 'RangeError thrown during array creation, not property modification' +); diff --git a/test/built-ins/Array/prototype/map/create-non-array.js b/test/built-ins/Array/prototype/map/create-non-array.js new file mode 100644 index 0000000000..05f315eba5 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-non-array.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Constructor is ignored for non-Array values +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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.map.call(obj, function() {}); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/map/create-revoked-proxy.js b/test/built-ins/Array/prototype/map/create-revoked-proxy.js new file mode 100644 index 0000000000..a725bc8778 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-revoked-proxy.js @@ -0,0 +1,43 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Abrupt completion from constructor that is a revoked Proxy object +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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 ctorCount = 0; +var cbCount = 0; +var cb = function() { cbCount += 1; }; + +Object.defineProperty(o.proxy, 'constructor', { + get: function() { + ctorCount += 1; + } +}); +o.revoke(); + +assert.throws(TypeError, function() { + Array.prototype.map.call(o.proxy, cb); +}); + +assert.sameValue(ctorCount, 0, '`constructor` property not accessed'); +assert.sameValue(cbCount, 0, 'callback not invoked'); diff --git a/test/built-ins/Array/prototype/map/create-species-abrupt.js b/test/built-ins/Array/prototype/map/create-species-abrupt.js new file mode 100644 index 0000000000..dec04db2eb --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species-abrupt.js @@ -0,0 +1,37 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Species constructor returns an abrupt completion +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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 callCount = 0; +var cb = function() { callCount += 1; }; +var a = []; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +assert.throws(Test262Error, function() { + a.map(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/map/create-species-non-ctor.js b/test/built-ins/Array/prototype/map/create-species-non-ctor.js new file mode 100644 index 0000000000..50657fef70 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species-non-ctor.js @@ -0,0 +1,36 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: > + Behavior when the @@species attribute is a non-constructor object +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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. +features: [Symbol.species] +---*/ + +var a = []; +var callCount = 0; +var cb = function() { callCount += 1; }; + +a.constructor = {}; +a.constructor[Symbol.species] = parseInt; + +assert.throws(TypeError, function() { + a.map(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/map/create-species-null.js b/test/built-ins/Array/prototype/map/create-species-null.js new file mode 100644 index 0000000000..54b7a97d29 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species-null.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. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: > + A null value for the @@species constructor is interpreted as `undefined` +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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.map(function() {}); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/map/create-species-poisoned.js b/test/built-ins/Array/prototype/map/create-species-poisoned.js new file mode 100644 index 0000000000..11fb340d32 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species-poisoned.js @@ -0,0 +1,36 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Abrupt completion from `@@species` property access +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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 = []; +var callCount = 0; +var cb = function() { callCount += 1; }; +a.constructor = {}; + +Object.defineProperty(a.constructor, Symbol.species, { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + a.map(cb); +}); +assert.sameValue(callCount, 0); diff --git a/test/built-ins/Array/prototype/map/create-species-undef-invalid-len.js b/test/built-ins/Array/prototype/map/create-species-undef-invalid-len.js new file mode 100644 index 0000000000..bcd89aadf3 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species-undef-invalid-len.js @@ -0,0 +1,58 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: > + An undefined value for the @@species constructor triggers the creation of + an Array exotic object +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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). + + 9.4.2.2 ArrayCreate + + [...] + 3. If length>232-1, throw a RangeError exception. +features: [Proxy] +---*/ + +var array = []; +var maxLength = Math.pow(2, 32); +var cbCount = 0; +var setCount = 0; +var cb = function() { cbCount += 1; }; +var proxy = new Proxy(array, { + get: function(_, name) { + if (name === 'length') { + return maxLength; + } + return array[name]; + }, + set: function() { + setCount += 1; + return true; + } +}); + +assert.throws(RangeError, function() { + Array.prototype.map.call(proxy, cb); +}); + +assert.sameValue( + setCount, + 0, + 'RangeError thrown during array creation, not property modification' +); +assert.sameValue(cbCount, 0, 'callback function not invoked'); diff --git a/test/built-ins/Array/prototype/map/create-species-undef.js b/test/built-ins/Array/prototype/map/create-species-undef.js new file mode 100644 index 0000000000..593714f2d9 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species-undef.js @@ -0,0 +1,35 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: > + An undefined value for the @@species constructor triggers the creation of + an Array exotic object +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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.map(function() {}); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/map/create-species.js b/test/built-ins/Array/prototype/map/create-species.js new file mode 100644 index 0000000000..ebcbdf9522 --- /dev/null +++ b/test/built-ins/Array/prototype/map/create-species.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. +/*--- +es6id: 22.1.3.16 +esid: sec-array.prototype.map +description: Species constructor is used to create a new instance +info: | + [...] + 5. Let A be ? ArraySpeciesCreate(O, len). + [...] + + 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 = [1, 2, 3, 4, 5]; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +result = a.map(function() {}); + +assert.sameValue(callCount, 1, 'Constructor invoked exactly once'); +assert.sameValue(Object.getPrototypeOf(thisValue), Ctor.prototype); +assert.sameValue(args.length, 1, 'Constructor invoked with a single argument'); +assert.sameValue(args[0], 5); +assert.sameValue(result, instance); diff --git a/test/built-ins/Array/prototype/slice/create-ctor-non-object.js b/test/built-ins/Array/prototype/slice/create-ctor-non-object.js new file mode 100644 index 0000000000..07d95cd580 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: > + Behavior when `constructor` property is neither an Object nor undefined +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice(); +}, 'null value'); + +a = []; +a.constructor = 1; +assert.throws(TypeError, function() { + a.slice(); +}, 'number value'); + +a = []; +a.constructor = 'string'; +assert.throws(TypeError, function() { + a.slice(); +}, 'string value'); + +a = []; +a.constructor = true; +assert.throws(TypeError, function() { + a.slice(); +}, 'boolean value'); diff --git a/test/built-ins/Array/prototype/slice/create-ctor-poisoned.js b/test/built-ins/Array/prototype/slice/create-ctor-poisoned.js new file mode 100644 index 0000000000..678fc0a117 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Abrupt completion from `constructor` property access +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice(); +}); diff --git a/test/built-ins/Array/prototype/slice/create-non-array-invalid-len.js b/test/built-ins/Array/prototype/slice/create-non-array-invalid-len.js new file mode 100644 index 0000000000..c809860842 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-non-array-invalid-len.js @@ -0,0 +1,43 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Abrupt completion from creating a new array +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 3. Let isArray be ? IsArray(originalArray). + 4. If isArray is false, return ? ArrayCreate(length). + + 9.4.2.2 ArrayCreate + + [...] + 3. If length>232-1, throw a RangeError exception. +---*/ + +var callCount = 0; +var maxLength = Math.pow(2, 32); +var obj = Object.defineProperty({}, 'length', { + get: function() { + return maxLength; + }, + set: function() { + callCount += 1; + } +}); + +assert.throws(RangeError, function() { + Array.prototype.slice.call(obj); +}); + +assert.sameValue( + callCount, + 0, + 'RangeError thrown during array creation, not property modification' +); diff --git a/test/built-ins/Array/prototype/slice/create-non-array.js b/test/built-ins/Array/prototype/slice/create-non-array.js new file mode 100644 index 0000000000..9061638d0f --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-non-array.js @@ -0,0 +1,32 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Constructor is ignored for non-Array values +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice.call(obj); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/slice/create-revoked-proxy.js b/test/built-ins/Array/prototype/slice/create-revoked-proxy.js new file mode 100644 index 0000000000..7b8e160e2c --- /dev/null +++ b/test/built-ins/Array/prototype/slice/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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Abrupt completion from constructor that is a revoked Proxy object +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice.call(o.proxy); +}); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); diff --git a/test/built-ins/Array/prototype/slice/create-species-abrupt.js b/test/built-ins/Array/prototype/slice/create-species-abrupt.js new file mode 100644 index 0000000000..aaa92accb2 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Species constructor returns an abrupt completion +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice(); +}); diff --git a/test/built-ins/Array/prototype/slice/create-species-neg-zero.js b/test/built-ins/Array/prototype/slice/create-species-neg-zero.js new file mode 100644 index 0000000000..f72df09eb8 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-species-neg-zero.js @@ -0,0 +1,46 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: The value `-0` is converted to `0` +info: | + [...] + 3. Let relativeStart be ? ToInteger(start). + 4. If relativeStart < 0, let k be max((len + relativeStart), 0); else let k + be min(relativeStart, len). + 5. If end is undefined, let relativeEnd be len; else let relativeEnd be ? + ToInteger(end). + 6. If relativeEnd < 0, let final be max((len + relativeEnd), 0); else let + final be min(relativeEnd, len). + 7. Let count be max(final - k, 0). + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 2. If length is -0, let length be +0. + [...] + 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 args; +var Ctor = function() { + args = arguments; +}; +var a = []; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +a.slice(0, -0); + +assert.sameValue(args.length, 1); +assert.sameValue(args[0], 0); diff --git a/test/built-ins/Array/prototype/slice/create-species-non-ctor.js b/test/built-ins/Array/prototype/slice/create-species-non-ctor.js new file mode 100644 index 0000000000..fd094ea159 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-species-non-ctor.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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: > + Behavior when the @@species attribute is a non-constructor object +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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. +features: [Symbol.species] +---*/ + +var a = []; + +a.constructor = {}; +a.constructor[Symbol.species] = parseInt; + +assert.throws(TypeError, function() { + a.slice(); +}); diff --git a/test/built-ins/Array/prototype/slice/create-species-null.js b/test/built-ins/Array/prototype/slice/create-species-null.js new file mode 100644 index 0000000000..38bcae57a9 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-species-null.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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: > + A null value for the @@species constructor is interpreted as `undefined` +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice(); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/slice/create-species-poisoned.js b/test/built-ins/Array/prototype/slice/create-species-poisoned.js new file mode 100644 index 0000000000..3bb17c11e7 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Abrupt completion from `@@species` property access +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice(); +}); diff --git a/test/built-ins/Array/prototype/slice/create-species-undef-invalid-len.js b/test/built-ins/Array/prototype/slice/create-species-undef-invalid-len.js new file mode 100644 index 0000000000..48c2bd7e32 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-species-undef-invalid-len.js @@ -0,0 +1,55 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: > + An undefined value for the @@species constructor triggers the creation of + an Array exotic object +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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). + + 9.4.2.2 ArrayCreate + + [...] + 3. If length>232-1, throw a RangeError exception. +features: [Proxy] +---*/ + +var array = []; +var maxLength = Math.pow(2, 32); +var callCount = 0; +var proxy = new Proxy(array, { + get: function(_, name) { + if (name === 'length') { + return maxLength; + } + return array[name]; + }, + set: function() { + callCount += 1; + return true; + } +}); + +assert.throws(RangeError, function() { + Array.prototype.slice.call(proxy); +}); + +assert.sameValue( + callCount, + 0, + 'RangeError thrown during array creation, not property modification' +); diff --git a/test/built-ins/Array/prototype/slice/create-species-undef.js b/test/built-ins/Array/prototype/slice/create-species-undef.js new file mode 100644 index 0000000000..c17bc73dd1 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-species-undef.js @@ -0,0 +1,35 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: > + An undefined value for the @@species constructor triggers the creation of + an Array exotic object +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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.slice(); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/slice/create-species.js b/test/built-ins/Array/prototype/slice/create-species.js new file mode 100644 index 0000000000..6b099b09c8 --- /dev/null +++ b/test/built-ins/Array/prototype/slice/create-species.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. +/*--- +es6id: 22.1.3.23 +esid: sec-array.prototype.slice +description: Species constructor is used to create a new instance +info: | + [...] + 8. Let A be ? ArraySpeciesCreate(O, count). + [...] + + 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 = [1, 2, 3, 4, 5]; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +result = a.slice(1, -1); + +assert.sameValue(callCount, 1, 'Constructor invoked exactly once'); +assert.sameValue(Object.getPrototypeOf(thisValue), Ctor.prototype); +assert.sameValue(args.length, 1, 'Constructor invoked with a single argument'); +assert.sameValue(args[0], 3); +assert.sameValue(result, instance); diff --git a/test/built-ins/Array/prototype/splice/create-ctor-non-object.js b/test/built-ins/Array/prototype/splice/create-ctor-non-object.js new file mode 100644 index 0000000000..5c96cae9fc --- /dev/null +++ b/test/built-ins/Array/prototype/splice/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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: > + Behavior when `constructor` property is neither an Object nor undefined +info: | + [...] + 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). + [...] + + 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.splice(); +}, 'null value'); + +a = []; +a.constructor = 1; +assert.throws(TypeError, function() { + a.splice(); +}, 'number value'); + +a = []; +a.constructor = 'string'; +assert.throws(TypeError, function() { + a.splice(); +}, 'string value'); + +a = []; +a.constructor = true; +assert.throws(TypeError, function() { + a.splice(); +}, 'boolean value'); diff --git a/test/built-ins/Array/prototype/splice/create-ctor-poisoned.js b/test/built-ins/Array/prototype/splice/create-ctor-poisoned.js new file mode 100644 index 0000000000..0fceaffa89 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Abrupt completion from `constructor` property access +info: | + [...] + 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). + [...] + + 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.splice(); +}); diff --git a/test/built-ins/Array/prototype/splice/create-non-array-invalid-len.js b/test/built-ins/Array/prototype/splice/create-non-array-invalid-len.js new file mode 100644 index 0000000000..eca772858c --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-non-array-invalid-len.js @@ -0,0 +1,43 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Abrupt completion from creating a new array +info: | + [...] + 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 3. Let isArray be ? IsArray(originalArray). + 4. If isArray is false, return ? ArrayCreate(length). + + 9.4.2.2 ArrayCreate + + [...] + 3. If length>232-1, throw a RangeError exception. +---*/ + +var callCount = 0; +var maxLength = Math.pow(2, 32); +var obj = Object.defineProperty({}, 'length', { + get: function() { + return maxLength; + }, + set: function() { + callCount += 1; + } +}); + +assert.throws(RangeError, function() { + Array.prototype.splice.call(obj, 0); +}); + +assert.sameValue( + callCount, + 0, + 'RangeError thrown during array creation, not property modification' +); diff --git a/test/built-ins/Array/prototype/splice/create-non-array.js b/test/built-ins/Array/prototype/splice/create-non-array.js new file mode 100644 index 0000000000..0af93e8c5a --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-non-array.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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Constructor is ignored for non-Array values +info: | + [...] + 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). + [...] + + 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.splice.call(obj); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); +assert.sameValue(result.length, 0, 'array created with appropriate length'); diff --git a/test/built-ins/Array/prototype/splice/create-revoked-proxy.js b/test/built-ins/Array/prototype/splice/create-revoked-proxy.js new file mode 100644 index 0000000000..dfcd5e8d2e --- /dev/null +++ b/test/built-ins/Array/prototype/splice/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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Abrupt completion from constructor that is a revoked Proxy object +info: | + [...] + 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). + [...] + + 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.splice.call(o.proxy); +}); + +assert.sameValue(callCount, 0, '`constructor` property not accessed'); diff --git a/test/built-ins/Array/prototype/splice/create-species-abrupt.js b/test/built-ins/Array/prototype/splice/create-species-abrupt.js new file mode 100644 index 0000000000..efa51d4820 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Species constructor returns an abrupt completion +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. + [...] + 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.splice(); +}); diff --git a/test/built-ins/Array/prototype/splice/create-species-neg-zero.js b/test/built-ins/Array/prototype/splice/create-species-neg-zero.js new file mode 100644 index 0000000000..f6a0d6f064 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-species-neg-zero.js @@ -0,0 +1,50 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: The value `-0` is converted to `0` +info: | + [...] + 3. Let relativeStart be ? ToInteger(start). + 4. If relativeStart < 0, let actualStart be max((len + relativeStart), 0); + else let actualStart be min(relativeStart, len). + 5. If the number of actual arguments is 0, then + [...] + 6. Else if the number of actual arguments is 1, then + [...] + 7. Else, + a. Let insertCount be the number of actual arguments minus 2. + b. Let dc be ? ToInteger(deleteCount). + c. Let actualDeleteCount be min(max(dc, 0), len - actualStart). + [...] + 9. Let A be ? ArraySpeciesCreate(O, actualDeleteCount). + [...] + + 9.4.2.3 ArraySpeciesCreate + + [...] + 2. If length is -0, let length be +0. + [...] + 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 args; +var Ctor = function() { + args = arguments; +}; +var a = []; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +a.splice(0, -0); + +assert.sameValue(args.length, 1); +assert.sameValue(args[0], 0); diff --git a/test/built-ins/Array/prototype/splice/create-species-non-ctor.js b/test/built-ins/Array/prototype/splice/create-species-non-ctor.js new file mode 100644 index 0000000000..ebc5b1a349 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-species-non-ctor.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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: > + Behavior when the @@species attribute is a non-constructor 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. + [...] + 9. If IsConstructor(C) is false, throw a TypeError exception. +features: [Symbol.species] +---*/ + +var a = []; + +a.constructor = {}; +a.constructor[Symbol.species] = parseInt; + +assert.throws(TypeError, function() { + a.splice(); +}); diff --git a/test/built-ins/Array/prototype/splice/create-species-null.js b/test/built-ins/Array/prototype/splice/create-species-null.js new file mode 100644 index 0000000000..eb85d10e05 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-species-null.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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: > + A null value for the @@species constructor is interpreted as `undefined` +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] = null; + +result = a.splice(); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/splice/create-species-poisoned.js b/test/built-ins/Array/prototype/splice/create-species-poisoned.js new file mode 100644 index 0000000000..54f725bbd7 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Abrupt completion from `@@species` property access +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). +features: [Symbol.species] +---*/ + +var a = []; +a.constructor = {}; + +Object.defineProperty(a.constructor, Symbol.species, { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + a.splice(); +}); diff --git a/test/built-ins/Array/prototype/splice/create-species-undef-invalid-len.js b/test/built-ins/Array/prototype/splice/create-species-undef-invalid-len.js new file mode 100644 index 0000000000..055d95713b --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-species-undef-invalid-len.js @@ -0,0 +1,55 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +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). + + 9.4.2.2 ArrayCreate + + [...] + 3. If length>232-1, throw a RangeError exception. +features: [Proxy] +---*/ + +var array = []; +var maxLength = Math.pow(2, 32); +var callCount = 0; +var proxy = new Proxy(array, { + get: function(_, name) { + if (name === 'length') { + return maxLength; + } + return array[name]; + }, + set: function() { + callCount += 1; + return true; + } +}); + +assert.throws(RangeError, function() { + Array.prototype.splice.call(proxy, 0); +}); + +assert.sameValue( + callCount, + 0, + 'RangeError thrown during array creation, not property modification' +); diff --git a/test/built-ins/Array/prototype/splice/create-species-undef.js b/test/built-ins/Array/prototype/splice/create-species-undef.js new file mode 100644 index 0000000000..3b70b66ecd --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-species-undef.js @@ -0,0 +1,35 @@ +// Copyright (C) 2016 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +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.splice(); + +assert.sameValue(Object.getPrototypeOf(result), Array.prototype); +assert(Array.isArray(result), 'result is an Array exotic object'); diff --git a/test/built-ins/Array/prototype/splice/create-species.js b/test/built-ins/Array/prototype/splice/create-species.js new file mode 100644 index 0000000000..f30e28f282 --- /dev/null +++ b/test/built-ins/Array/prototype/splice/create-species.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. +/*--- +es6id: 22.1.3.26 +esid: sec-array.prototype.splice +description: Species constructor is used to create a new instance +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. + [...] + 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 = [1, 2, 3, 4, 5]; +a.constructor = {}; +a.constructor[Symbol.species] = Ctor; + +result = a.splice(2); + +assert.sameValue(callCount, 1, 'Constructor invoked exactly once'); +assert.sameValue(Object.getPrototypeOf(thisValue), Ctor.prototype); +assert.sameValue(args.length, 1, 'Constructor invoked with a single argument'); +assert.sameValue(args[0], 3); +assert.sameValue(result, instance);