From 5cb1ba27d3f14a4af24df42020f99a3a668ee8e2 Mon Sep 17 00:00:00 2001 From: Mike Pennisi Date: Wed, 15 Jul 2015 18:45:38 -0400 Subject: [PATCH] Add tests for Array.from Limit tests to behavior of method when invoked with an iterable. --- .../Array/from/get-iter-method-err.js | 22 +++++++ test/built-ins/Array/from/iter-adv-err.js | 28 +++++++++ .../Array/from/iter-cstm-ctor-err.js | 26 ++++++++ test/built-ins/Array/from/iter-cstm-ctor.js | 46 ++++++++++++++ .../built-ins/Array/from/iter-get-iter-err.js | 22 +++++++ .../Array/from/iter-get-iter-val-err.js | 34 ++++++++++ test/built-ins/Array/from/iter-map-fn-args.js | 63 +++++++++++++++++++ test/built-ins/Array/from/iter-map-fn-err.js | 41 ++++++++++++ .../Array/from/iter-map-fn-return.js | 58 +++++++++++++++++ .../Array/from/iter-map-fn-this-arg.js | 49 +++++++++++++++ .../Array/from/iter-map-fn-this-non-strict.js | 50 +++++++++++++++ .../Array/from/iter-map-fn-this-strict.js | 49 +++++++++++++++ .../Array/from/iter-set-elem-prop-err.js | 45 +++++++++++++ .../Array/from/iter-set-elem-prop.js | 41 ++++++++++++ .../Array/from/iter-set-length-err.js | 33 ++++++++++ test/built-ins/Array/from/iter-set-length.js | 40 ++++++++++++ 16 files changed, 647 insertions(+) create mode 100644 test/built-ins/Array/from/get-iter-method-err.js create mode 100644 test/built-ins/Array/from/iter-adv-err.js create mode 100644 test/built-ins/Array/from/iter-cstm-ctor-err.js create mode 100644 test/built-ins/Array/from/iter-cstm-ctor.js create mode 100644 test/built-ins/Array/from/iter-get-iter-err.js create mode 100644 test/built-ins/Array/from/iter-get-iter-val-err.js create mode 100644 test/built-ins/Array/from/iter-map-fn-args.js create mode 100644 test/built-ins/Array/from/iter-map-fn-err.js create mode 100644 test/built-ins/Array/from/iter-map-fn-return.js create mode 100644 test/built-ins/Array/from/iter-map-fn-this-arg.js create mode 100644 test/built-ins/Array/from/iter-map-fn-this-non-strict.js create mode 100644 test/built-ins/Array/from/iter-map-fn-this-strict.js create mode 100644 test/built-ins/Array/from/iter-set-elem-prop-err.js create mode 100644 test/built-ins/Array/from/iter-set-elem-prop.js create mode 100644 test/built-ins/Array/from/iter-set-length-err.js create mode 100644 test/built-ins/Array/from/iter-set-length.js diff --git a/test/built-ins/Array/from/get-iter-method-err.js b/test/built-ins/Array/from/get-iter-method-err.js new file mode 100644 index 0000000000..745f108135 --- /dev/null +++ b/test/built-ins/Array/from/get-iter-method-err.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error accessing items' `Symbol.iterator` attribute +info: > + [...] + 4. Let usingIterator be GetMethod(items, @@iterator). + 5. ReturnIfAbrupt(usingIterator). +features: [Symbol.iterator] +---*/ + +var items = {}; +Object.defineProperty(items, Symbol.iterator, { + get: function() { + throw new Test262Error(); + } +}); + +assert.throws(Test262Error, function() { + Array.from(items); +}); diff --git a/test/built-ins/Array/from/iter-adv-err.js b/test/built-ins/Array/from/iter-adv-err.js new file mode 100644 index 0000000000..0b8259baeb --- /dev/null +++ b/test/built-ins/Array/from/iter-adv-err.js @@ -0,0 +1,28 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error advancing iterator +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + i. Let Pk be ToString(k). + ii. Let next be IteratorStep(iterator). + iii. ReturnIfAbrupt(next). +features: [Symbol.iterator] +---*/ + +var items = {}; +items[Symbol.iterator] = function() { + return { + next: function() { + throw new Test262Error(); + } + }; +}; + +assert.throws(Test262Error, function() { + Array.from(items); +}); diff --git a/test/built-ins/Array/from/iter-cstm-ctor-err.js b/test/built-ins/Array/from/iter-cstm-ctor-err.js new file mode 100644 index 0000000000..06733cb093 --- /dev/null +++ b/test/built-ins/Array/from/iter-cstm-ctor-err.js @@ -0,0 +1,26 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: > + Error creating object with custom constructor (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + a. If IsConstructor(C) is true, then + i. Let A be Construct(C). + b. Else, + i. Let A be ArrayCreate(0). + c. ReturnIfAbrupt(A). +features: [Symbol.iterator] +---*/ + +var C = function() { + throw new Test262Error(); +}; +var items = {}; +items[Symbol.iterator] = function() {}; + +assert.throws(Test262Error, function() { + Array.from.call(C, items); +}); diff --git a/test/built-ins/Array/from/iter-cstm-ctor.js b/test/built-ins/Array/from/iter-cstm-ctor.js new file mode 100644 index 0000000000..a19edeb9a3 --- /dev/null +++ b/test/built-ins/Array/from/iter-cstm-ctor.js @@ -0,0 +1,46 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Creating object with custom constructor (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + a. If IsConstructor(C) is true, then + i. Let A be Construct(C). + b. Else, + i. Let A be ArrayCreate(0). + c. ReturnIfAbrupt(A). +features: [Symbol.iterator] +---*/ + +var thisVal, args; +var callCount = 0; +var C = function() { + thisVal = this; + args = arguments; + callCount += 1; +}; +var result; +var items = {}; +items[Symbol.iterator] = function() { + return { + next: function() { + return { done: true }; + } + }; +}; + +result = Array.from.call(C, items); + +assert( + result instanceof C, 'Constructed value is an instance of the constructor' +); +assert.sameValue( + result.constructor, + C, + 'Constructed value correctly defines a `constructor` property' +); +assert.sameValue(callCount, 1, 'Constructor invoked exactly once'); +assert.sameValue(thisVal, result, 'Constructed value is returned'); +assert.sameValue(args.length, 0, 'Constructor invoked without arguments'); diff --git a/test/built-ins/Array/from/iter-get-iter-err.js b/test/built-ins/Array/from/iter-get-iter-err.js new file mode 100644 index 0000000000..edc5b1717e --- /dev/null +++ b/test/built-ins/Array/from/iter-get-iter-err.js @@ -0,0 +1,22 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error creating iterator object +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + d. Let iterator be GetIterator(items, usingIterator). + e. ReturnIfAbrupt(iterator). +features: [Symbol.iterator] +---*/ + +var items = {}; +items[Symbol.iterator] = function() { + throw new Test262Error(); +}; + +assert.throws(Test262Error, function() { + Array.from(items); +}); diff --git a/test/built-ins/Array/from/iter-get-iter-val-err.js b/test/built-ins/Array/from/iter-get-iter-val-err.js new file mode 100644 index 0000000000..976981d52e --- /dev/null +++ b/test/built-ins/Array/from/iter-get-iter-val-err.js @@ -0,0 +1,34 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error retrieving value of iterator result +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + v. Let nextValue be IteratorValue(next). + vi. ReturnIfAbrupt(nextValue). +features: [Symbol.iterator] +---*/ + +var items = {}; +var poisonedValue = {}; +Object.defineProperty(poisonedValue, 'value', { + get: function() { + throw new Test262Error(); + } +}); +items[Symbol.iterator] = function() { + return { + next: function() { + return poisonedValue; + } + }; +}; + +assert.throws(Test262Error, function() { + Array.from(items); +}); diff --git a/test/built-ins/Array/from/iter-map-fn-args.js b/test/built-ins/Array/from/iter-map-fn-args.js new file mode 100644 index 0000000000..c7f35b8234 --- /dev/null +++ b/test/built-ins/Array/from/iter-map-fn-args.js @@ -0,0 +1,63 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: > + Arguments of mapping function (traversed via iterator) +info: > + [...] + 2. If mapfn is undefined, let mapping be false. + 3. else + a. If IsCallable(mapfn) is false, throw a TypeError exception. + b. If thisArg was supplied, let T be thisArg; else let T be undefined. + c. Let mapping be true + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + vii. If mapping is true, then + 1. Let mappedValue be Call(mapfn, T, «nextValue, k»). + 2. If mappedValue is an abrupt completion, return + IteratorClose(iterator, mappedValue). + 3. Let mappedValue be mappedValue.[[value]]. +features: [Symbol.iterator] +---*/ + +var args = []; +var firstResult = { done: false, value: {} }; +var secondResult = { done: false, value: {} }; +var mapFn = function(value, idx) { + args.push(arguments); +}; +var items = {}; +var nextResult = firstResult; +var nextNextResult = secondResult; + +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextResult; + nextResult = nextNextResult; + nextNextResult = { done: true }; + + return result; + } + }; +}; + +Array.from(items, mapFn); + +assert.sameValue(args.length, 2, 'Iteration count'); + +assert.sameValue(args[0].length, 2, 'First iteration: arguments length'); +assert.sameValue( + args[0][0], firstResult.value, 'First iteration: first argument' +); +assert.sameValue(args[0][1], 0, 'First iteration: second argument'); + +assert.sameValue(args[1].length, 2, 'Second iteration: arguments length'); +assert.sameValue( + args[1][0], secondResult.value, 'Second iteration: first argument' +); +assert.sameValue(args[1][1], 1, 'Second iteration: second argument'); diff --git a/test/built-ins/Array/from/iter-map-fn-err.js b/test/built-ins/Array/from/iter-map-fn-err.js new file mode 100644 index 0000000000..a96b8f3c94 --- /dev/null +++ b/test/built-ins/Array/from/iter-map-fn-err.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error invoking map function (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + vii. If mapping is true, then + 1. Let mappedValue be Call(mapfn, T, «nextValue, k»). + 2. If mappedValue is an abrupt completion, return + IteratorClose(iterator, mappedValue). +features: [Symbol.iterator] +---*/ + +var closeCount = 0; +var mapFn = function() { + throw new Test262Error(); +}; +var items = {}; +items[Symbol.iterator] = function() { + return { + return: function() { + closeCount += 1; + }, + next: function() { + return { + done: false + }; + } + }; +}; + +assert.throws(Test262Error, function() { + Array.from(items, mapFn); +}); + +assert.sameValue(closeCount, 1); diff --git a/test/built-ins/Array/from/iter-map-fn-return.js b/test/built-ins/Array/from/iter-map-fn-return.js new file mode 100644 index 0000000000..ca4c8f3783 --- /dev/null +++ b/test/built-ins/Array/from/iter-map-fn-return.js @@ -0,0 +1,58 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Value returned by mapping function (traversed via iterator) +info: > + [...] + 2. If mapfn is undefined, let mapping be false. + 3. else + a. If IsCallable(mapfn) is false, throw a TypeError exception. + b. If thisArg was supplied, let T be thisArg; else let T be undefined. + c. Let mapping be true + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + vii. If mapping is true, then + 1. Let mappedValue be Call(mapfn, T, «nextValue, k»). + 2. If mappedValue is an abrupt completion, return + IteratorClose(iterator, mappedValue). + 3. Let mappedValue be mappedValue.[[value]]. +features: [Symbol.iterator] +---*/ + +var thisVals = []; +var nextResult = { done: false, value: {} }; +var nextNextResult = { done: false, value: {} }; +var firstReturnVal = {}; +var secondReturnVal = {}; +var mapFn = function(value, idx) { + var returnVal = nextReturnVal; + nextReturnVal = nextNextReturnVal; + nextNextReturnVal = null; + return returnVal; +}; +var nextReturnVal = firstReturnVal; +var nextNextReturnVal = secondReturnVal; +var items = {}; +var result; + +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextResult; + nextResult = nextNextResult; + nextNextResult = { done: true }; + + return result; + } + }; +}; + +result = Array.from(items, mapFn); + +assert.sameValue(result.length, 2); +assert.sameValue(result[0], firstReturnVal); +assert.sameValue(result[1], secondReturnVal); diff --git a/test/built-ins/Array/from/iter-map-fn-this-arg.js b/test/built-ins/Array/from/iter-map-fn-this-arg.js new file mode 100644 index 0000000000..26becec78b --- /dev/null +++ b/test/built-ins/Array/from/iter-map-fn-this-arg.js @@ -0,0 +1,49 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: > + `this` value of mapping function with custom `this` argument (traversed via iterator) +info: > + [...] + 2. If mapfn is undefined, let mapping be false. + 3. else + a. If IsCallable(mapfn) is false, throw a TypeError exception. + b. If thisArg was supplied, let T be thisArg; else let T be undefined. + c. Let mapping be true + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + vii. If mapping is true, then + 1. Let mappedValue be Call(mapfn, T, «nextValue, k»). +features: [Symbol.iterator] +---*/ + +var thisVals = []; +var nextResult = { done: false, value: {} }; +var nextNextResult = { done: false, value: {} }; +var mapFn = function() { + thisVals.push(this); +}; +var items = {}; +var thisVal = {}; + +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextResult; + nextResult = nextNextResult; + nextNextResult = { done: true }; + + return result; + } + }; +}; + +Array.from(items, mapFn, thisVal); + +assert.sameValue(thisVals.length, 2); +assert.sameValue(thisVals[0], thisVal, 'First iteration `this` value'); +assert.sameValue(thisVals[1], thisVal, 'Second iteration `this` value'); diff --git a/test/built-ins/Array/from/iter-map-fn-this-non-strict.js b/test/built-ins/Array/from/iter-map-fn-this-non-strict.js new file mode 100644 index 0000000000..c4e18eb029 --- /dev/null +++ b/test/built-ins/Array/from/iter-map-fn-this-non-strict.js @@ -0,0 +1,50 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: > + `this` value of mapping function in non-strict mode (traversed via iterator) +info: > + [...] + 2. If mapfn is undefined, let mapping be false. + 3. else + a. If IsCallable(mapfn) is false, throw a TypeError exception. + b. If thisArg was supplied, let T be thisArg; else let T be undefined. + c. Let mapping be true + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + vii. If mapping is true, then + 1. Let mappedValue be Call(mapfn, T, «nextValue, k»). +features: [Symbol.iterator] +flags: [noStrict] +---*/ + +var thisVals = []; +var nextResult = { done: false, value: {} }; +var nextNextResult = { done: false, value: {} }; +var mapFn = function() { + thisVals.push(this); +}; +var items = {}; +var global = function() { return this; }(); + +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextResult; + nextResult = nextNextResult; + nextNextResult = { done: true }; + + return result; + } + }; +}; + +Array.from(items, mapFn); + +assert.sameValue(thisVals.length, 2); +assert.sameValue(thisVals[0], global, 'First iteration `this` value'); +assert.sameValue(thisVals[1], global, 'Second iteration `this` value'); diff --git a/test/built-ins/Array/from/iter-map-fn-this-strict.js b/test/built-ins/Array/from/iter-map-fn-this-strict.js new file mode 100644 index 0000000000..bb17d90d81 --- /dev/null +++ b/test/built-ins/Array/from/iter-map-fn-this-strict.js @@ -0,0 +1,49 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: > + `this` value of mapping function in strict mode (traversed via iterator) +info: > + [...] + 2. If mapfn is undefined, let mapping be false. + 3. else + a. If IsCallable(mapfn) is false, throw a TypeError exception. + b. If thisArg was supplied, let T be thisArg; else let T be undefined. + c. Let mapping be true + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + vii. If mapping is true, then + 1. Let mappedValue be Call(mapfn, T, «nextValue, k»). +features: [Symbol.iterator] +flags: [onlyStrict] +---*/ + +var thisVals = []; +var nextResult = { done: false, value: {} }; +var nextNextResult = { done: false, value: {} }; +var mapFn = function() { + thisVals.push(this); +}; +var items = {}; + +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextResult; + nextResult = nextNextResult; + nextNextResult = { done: true }; + + return result; + } + }; +}; + +Array.from(items, mapFn); + +assert.sameValue(thisVals.length, 2); +assert.sameValue(thisVals[0], undefined, 'First iteration `this` value'); +assert.sameValue(thisVals[1], undefined, 'Second iteration `this` value'); diff --git a/test/built-ins/Array/from/iter-set-elem-prop-err.js b/test/built-ins/Array/from/iter-set-elem-prop-err.js new file mode 100644 index 0000000000..64945a070d --- /dev/null +++ b/test/built-ins/Array/from/iter-set-elem-prop-err.js @@ -0,0 +1,45 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error setting property on result value (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + ix. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, + mappedValue). + x. If defineStatus is an abrupt completion, return + IteratorClose(iterator, defineStatus). +features: [Symbol.iterator] +---*/ + +var C = function() { + Object.defineProperty(this, '0', { configurable: false }); +}; +var closeCount = 0; +var items = {}; +var nextResult = { done: false }; + +items[Symbol.iterator] = function() { + return { + return: function() { + closeCount += 1; + }, + next: function() { + var result = nextResult; + + nextResult = { done: true }; + + return result; + } + }; +}; + +assert.throws(TypeError, function() { + Array.from.call(C, items); +}); + +assert.sameValue(closeCount, 1); diff --git a/test/built-ins/Array/from/iter-set-elem-prop.js b/test/built-ins/Array/from/iter-set-elem-prop.js new file mode 100644 index 0000000000..91762fddde --- /dev/null +++ b/test/built-ins/Array/from/iter-set-elem-prop.js @@ -0,0 +1,41 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Setting property on result value (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + ix. Let defineStatus be CreateDataPropertyOrThrow(A, Pk, + mappedValue). +features: [Symbol.iterator] +---*/ + +var items = {}; +var firstIterResult = { done: false, value: {} }; +var secondIterResult = { done: false, value: {} }; +var thirdIterResult = { done: true, value: {} }; +var nextIterResult = firstIterResult; +var nextNextIterResult = secondIterResult; +var result; + +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextIterResult; + + nextIterResult = nextNextIterResult; + nextNextIterResult = thirdIterResult; + + return result; + } + }; +}; + +result = Array.from(items); + +assert.sameValue(result[0], firstIterResult.value); +assert.sameValue(result[1], secondIterResult.value); diff --git a/test/built-ins/Array/from/iter-set-length-err.js b/test/built-ins/Array/from/iter-set-length-err.js new file mode 100644 index 0000000000..3379ed7ec4 --- /dev/null +++ b/test/built-ins/Array/from/iter-set-length-err.js @@ -0,0 +1,33 @@ +// Copyright (C) 2015 the V8 project authors. All rights reserved. +// This code is governed by the BSD license found in the LICENSE file. +/*--- +es6id: 22.1.2.1 +description: Error setting length of object (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + iv. If next is false, then + 1. Let setStatus be Set(A, "length", k, true). + 2. ReturnIfAbrupt(setStatus). +features: [Symbol.iterator] +---*/ + +var C = function() {}; +var items = {}; +Object.defineProperty(C.prototype, 'length', { + set: function(_) { + throw new Test262Error(); + } +}); +items[Symbol.iterator] = function() { + return { + next: function() { return { done: true }; } + }; +}; + +assert.throws(Test262Error, function() { + Array.from.call(C, items); +}); diff --git a/test/built-ins/Array/from/iter-set-length.js b/test/built-ins/Array/from/iter-set-length.js new file mode 100644 index 0000000000..95913df721 --- /dev/null +++ b/test/built-ins/Array/from/iter-set-length.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. +/*--- +es6id: 22.1.2.1 +description: Setting length of object (traversed via iterator) +info: > + [...] + 6. If usingIterator is not undefined, then + [...] + g. Repeat + [...] + iv. If next is false, then + 1. Let setStatus be Set(A, "length", k, true). + 2. ReturnIfAbrupt(setStatus). + 3. Return A. +features: [Symbol.iterator] +---*/ + +var items = {}; +var result, nextIterResult, lastIterResult; +items[Symbol.iterator] = function() { + return { + next: function() { + var result = nextIterResult; + nextIterResult = lastIterResult; + return result; + } + }; +}; + +nextIterResult = lastIterResult = { done: true }; +result = Array.from(items); + +assert.sameValue(result.length, 0); + +nextIterResult = { done: false }; +lastIterResult = { done: true }; +result = Array.from(items); + +assert.sameValue(result.length, 1);