// 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__);

  assertEquals('Array Iterator', %_ClassOf(array[Symbol.iterator]()));
  assertEquals('Array Iterator', %_ClassOf(array.keys()));
  assertEquals('Array Iterator', %_ClassOf(array.entries()));

  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();
