1// Copyright 2013 the V8 project authors. All rights reserved.
2// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6//     * Redistributions of source code must retain the above copyright
7//       notice, this list of conditions and the following disclaimer.
8//     * Redistributions in binary form must reproduce the above
9//       copyright notice, this list of conditions and the following
10//       disclaimer in the documentation and/or other materials provided
11//       with the distribution.
12//     * Neither the name of Google Inc. nor the names of its
13//       contributors may be used to endorse or promote products derived
14//       from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28// Flags: --harmony-iteration --allow-natives-syntax
29
30function TestArrayPrototype() {
31  assertTrue(Array.prototype.hasOwnProperty('entries'));
32  assertTrue(Array.prototype.hasOwnProperty('values'));
33  assertTrue(Array.prototype.hasOwnProperty('keys'));
34
35  assertFalse(Array.prototype.propertyIsEnumerable('entries'));
36  assertFalse(Array.prototype.propertyIsEnumerable('values'));
37  assertFalse(Array.prototype.propertyIsEnumerable('keys'));
38}
39TestArrayPrototype();
40
41function assertIteratorResult(value, done, result) {
42  assertEquals({value: value, done: done}, result);
43}
44
45function TestValues() {
46  var array = ['a', 'b', 'c'];
47  var iterator = array.values();
48  assertIteratorResult('a', false, iterator.next());
49  assertIteratorResult('b', false, iterator.next());
50  assertIteratorResult('c', false, iterator.next());
51  assertIteratorResult(void 0, true, iterator.next());
52
53  array.push('d');
54  assertIteratorResult(void 0, true, iterator.next());
55}
56TestValues();
57
58function TestValuesMutate() {
59  var array = ['a', 'b', 'c'];
60  var iterator = array.values();
61  assertIteratorResult('a', false, iterator.next());
62  assertIteratorResult('b', false, iterator.next());
63  assertIteratorResult('c', false, iterator.next());
64  array.push('d');
65  assertIteratorResult('d', false, iterator.next());
66  assertIteratorResult(void 0, true, iterator.next());
67}
68TestValuesMutate();
69
70function TestKeys() {
71  var array = ['a', 'b', 'c'];
72  var iterator = array.keys();
73  assertIteratorResult(0, false, iterator.next());
74  assertIteratorResult(1, false, iterator.next());
75  assertIteratorResult(2, false, iterator.next());
76  assertIteratorResult(void 0, true, iterator.next());
77
78  array.push('d');
79  assertIteratorResult(void 0, true, iterator.next());
80}
81TestKeys();
82
83function TestKeysMutate() {
84  var array = ['a', 'b', 'c'];
85  var iterator = array.keys();
86  assertIteratorResult(0, false, iterator.next());
87  assertIteratorResult(1, false, iterator.next());
88  assertIteratorResult(2, false, iterator.next());
89  array.push('d');
90  assertIteratorResult(3, false, iterator.next());
91  assertIteratorResult(void 0, true, iterator.next());
92}
93TestKeysMutate();
94
95function TestEntries() {
96  var array = ['a', 'b', 'c'];
97  var iterator = array.entries();
98  assertIteratorResult([0, 'a'], false, iterator.next());
99  assertIteratorResult([1, 'b'], false, iterator.next());
100  assertIteratorResult([2, 'c'], false, iterator.next());
101  assertIteratorResult(void 0, true, iterator.next());
102
103  array.push('d');
104  assertIteratorResult(void 0, true, iterator.next());
105}
106TestEntries();
107
108function TestEntriesMutate() {
109  var array = ['a', 'b', 'c'];
110  var iterator = array.entries();
111  assertIteratorResult([0, 'a'], false, iterator.next());
112  assertIteratorResult([1, 'b'], false, iterator.next());
113  assertIteratorResult([2, 'c'], false, iterator.next());
114  array.push('d');
115  assertIteratorResult([3, 'd'], false, iterator.next());
116  assertIteratorResult(void 0, true, iterator.next());
117}
118TestEntriesMutate();
119
120function TestArrayIteratorPrototype() {
121  var array = [];
122  var iterator = array.values();
123
124  var ArrayIterator = iterator.constructor;
125  assertEquals(ArrayIterator.prototype, array.values().__proto__);
126  assertEquals(ArrayIterator.prototype, array.keys().__proto__);
127  assertEquals(ArrayIterator.prototype, array.entries().__proto__);
128
129  assertEquals(Object.prototype, ArrayIterator.prototype.__proto__);
130
131  assertEquals('Array Iterator', %_ClassOf(array.values()));
132  assertEquals('Array Iterator', %_ClassOf(array.keys()));
133  assertEquals('Array Iterator', %_ClassOf(array.entries()));
134
135  var prototypeDescriptor =
136      Object.getOwnPropertyDescriptor(ArrayIterator, 'prototype');
137  assertFalse(prototypeDescriptor.configurable);
138  assertFalse(prototypeDescriptor.enumerable);
139  assertFalse(prototypeDescriptor.writable);
140}
141TestArrayIteratorPrototype();
142
143function TestForArrayValues() {
144  var buffer = [];
145  var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
146  var i = 0;
147  for (var value of array.values()) {
148    buffer[i++] = value;
149  }
150
151  assertEquals(8, buffer.length);
152
153  for (var i = 0; i < buffer.length - 1; i++) {
154    assertEquals(array[i], buffer[i]);
155  }
156  assertTrue(isNaN(buffer[buffer.length - 1]));
157}
158TestForArrayValues();
159
160function TestForArrayKeys() {
161  var buffer = [];
162  var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
163  var i = 0;
164  for (var key of array.keys()) {
165    buffer[i++] = key;
166  }
167
168  assertEquals(8, buffer.length);
169
170  for (var i = 0; i < buffer.length; i++) {
171    assertEquals(i, buffer[i]);
172  }
173}
174TestForArrayKeys();
175
176function TestForArrayEntries() {
177  var buffer = [];
178  var array = [0, 'a', true, false, null, /* hole */, undefined, NaN];
179  var i = 0;
180  for (var entry of array.entries()) {
181    buffer[i++] = entry;
182  }
183
184  assertEquals(8, buffer.length);
185
186  for (var i = 0; i < buffer.length - 1; i++) {
187    assertEquals(array[i], buffer[i][1]);
188  }
189  assertTrue(isNaN(buffer[buffer.length - 1][1]));
190
191  for (var i = 0; i < buffer.length; i++) {
192    assertEquals(i, buffer[i][0]);
193  }
194}
195TestForArrayEntries();
196