// Copyright 2013 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above // copyright notice, this list of conditions and the following // disclaimer in the documentation and/or other materials provided // with the distribution. // * Neither the name of Google Inc. nor the names of its // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // Flags: --allow-natives-syntax var NONE = 0; var READ_ONLY = 1; var DONT_ENUM = 2; var DONT_DELETE = 4; function assertHasOwnProperty(object, name, attrs) { assertTrue(object.hasOwnProperty(name)); var desc = Object.getOwnPropertyDescriptor(object, name); assertEquals(desc.writable, !(attrs & READ_ONLY)); assertEquals(desc.enumerable, !(attrs & DONT_ENUM)); assertEquals(desc.configurable, !(attrs & DONT_DELETE)); } function TestArrayPrototype() { assertHasOwnProperty(Array.prototype, 'entries', DONT_ENUM); assertHasOwnProperty(Array.prototype, 'keys', DONT_ENUM); assertHasOwnProperty(Array.prototype, Symbol.iterator, DONT_ENUM); assertEquals('entries', Array.prototype.entries.name); assertEquals('keys', Array.prototype.keys.name); assertEquals('values', Array.prototype[Symbol.iterator].name); } TestArrayPrototype(); function assertIteratorResult(value, done, result) { assertEquals({value: value, done: done}, result); } function TestValues() { var array = ['a', 'b', 'c']; var iterator = array[Symbol.iterator](); assertIteratorResult('a', false, iterator.next()); assertIteratorResult('b', false, iterator.next()); assertIteratorResult('c', false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); array.push('d'); assertIteratorResult(void 0, true, iterator.next()); } TestValues(); function TestValuesMutate() { var array = ['a', 'b', 'c']; var iterator = array[Symbol.iterator](); assertIteratorResult('a', false, iterator.next()); assertIteratorResult('b', false, iterator.next()); assertIteratorResult('c', false, iterator.next()); array.push('d'); assertIteratorResult('d', false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); } TestValuesMutate(); function TestKeys() { var array = ['a', 'b', 'c']; var iterator = array.keys(); assertIteratorResult(0, false, iterator.next()); assertIteratorResult(1, false, iterator.next()); assertIteratorResult(2, false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); array.push('d'); assertIteratorResult(void 0, true, iterator.next()); } TestKeys(); function TestKeysMutate() { var array = ['a', 'b', 'c']; var iterator = array.keys(); assertIteratorResult(0, false, iterator.next()); assertIteratorResult(1, false, iterator.next()); assertIteratorResult(2, false, iterator.next()); array.push('d'); assertIteratorResult(3, false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); } TestKeysMutate(); function TestEntries() { var array = ['a', 'b', 'c']; var iterator = array.entries(); assertIteratorResult([0, 'a'], false, iterator.next()); assertIteratorResult([1, 'b'], false, iterator.next()); assertIteratorResult([2, 'c'], false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); array.push('d'); assertIteratorResult(void 0, true, iterator.next()); } TestEntries(); function TestEntriesMutate() { var array = ['a', 'b', 'c']; var iterator = array.entries(); assertIteratorResult([0, 'a'], false, iterator.next()); assertIteratorResult([1, 'b'], false, iterator.next()); assertIteratorResult([2, 'c'], false, iterator.next()); array.push('d'); assertIteratorResult([3, 'd'], false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); } TestEntriesMutate(); function TestArrayIteratorPrototype() { var array = []; var iterator = array.keys(); var ArrayIteratorPrototype = iterator.__proto__; assertEquals(ArrayIteratorPrototype, array[Symbol.iterator]().__proto__); assertEquals(ArrayIteratorPrototype, array.keys().__proto__); assertEquals(ArrayIteratorPrototype, array.entries().__proto__); assertEquals(Object.prototype, ArrayIteratorPrototype.__proto__); assertFalse(ArrayIteratorPrototype.hasOwnProperty('constructor')); assertArrayEquals(['next'], Object.getOwnPropertyNames(ArrayIteratorPrototype)); assertHasOwnProperty(ArrayIteratorPrototype, 'next', DONT_ENUM); assertFalse(ArrayIteratorPrototype.hasOwnProperty(Symbol.iterator)); assertEquals("[object Array Iterator]", Object.prototype.toString.call(iterator)); assertEquals("Array Iterator", ArrayIteratorPrototype[Symbol.toStringTag]); var desc = Object.getOwnPropertyDescriptor( ArrayIteratorPrototype, Symbol.toStringTag); assertTrue(desc.configurable); assertFalse(desc.writable); assertEquals("Array Iterator", desc.value); } TestArrayIteratorPrototype(); function TestForArrayValues() { var buffer = []; var array = [0, 'a', true, false, null, /* hole */, undefined, NaN]; var i = 0; for (var value of array[Symbol.iterator]()) { buffer[i++] = value; } assertEquals(8, buffer.length); for (var i = 0; i < buffer.length; i++) { assertSame(array[i], buffer[i]); } } TestForArrayValues(); function TestForArrayKeys() { var buffer = []; var array = [0, 'a', true, false, null, /* hole */, undefined, NaN]; var i = 0; for (var key of array.keys()) { buffer[i++] = key; } assertEquals(8, buffer.length); for (var i = 0; i < buffer.length; i++) { assertEquals(i, buffer[i]); } } TestForArrayKeys(); function TestForArrayEntries() { var buffer = []; var array = [0, 'a', true, false, null, /* hole */, undefined, NaN]; var i = 0; for (var entry of array.entries()) { buffer[i++] = entry; } assertEquals(8, buffer.length); for (var i = 0; i < buffer.length; i++) { assertSame(array[i], buffer[i][1]); } for (var i = 0; i < buffer.length; i++) { assertEquals(i, buffer[i][0]); } } TestForArrayEntries(); function TestForArray() { var buffer = []; var array = [0, 'a', true, false, null, /* hole */, undefined, NaN]; var i = 0; for (var value of array) { buffer[i++] = value; } assertEquals(8, buffer.length); for (var i = 0; i < buffer.length; i++) { assertSame(array[i], buffer[i]); } } TestForArrayValues(); function TestNonOwnSlots() { var array = [0]; var iterator = array[Symbol.iterator](); var object = {__proto__: iterator}; assertThrows(function() { object.next(); }, TypeError); } TestNonOwnSlots(); function TestForDictionaryArray() { var array = []; array[1024] = 'c'; assertTrue(%HasDictionaryElements(array)); var iterator = array[Symbol.iterator](); for (var i = 0; i < 1024; ++i) { assertIteratorResult(void 0, false, iterator.next()); } assertIteratorResult('c', false, iterator.next()); assertIteratorResult(void 0, true, iterator.next()); } TestForDictionaryArray();