// Copyright 2015 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Flags: --allow-natives-syntax

// NOTE:
// Tests in this file are meant to run in the presence of an invalidated
// NoElementsProtector, as effected by the following line.
Array.prototype[0] = 42;
delete Array.prototype[0];


(function TestBasics() {
  var a = [1, 2];
  var b = [...a];
  assertArrayEquals([1, 2], b)

  assertArrayEquals(['a', 'b', 'c', 'd', 'e', 'f'],
                    ['a', ...'bc', 'd', ...'ef'])
})();


var log = [];

function* gen(n) {
  log.push(n, 1);
  yield 1;
  log.push(n, 2);
  yield 2;
  log.push(n, 3);
  yield 3;
  log.push(n, 'done');
}

function id(v) {
  log.push(v);
  return v;
}


(function TestGenerator() {
  assertArrayEquals([1, 2, 3], [...gen('a')]);
  assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
                    ['x', ...gen('a'), 'y', ...gen('b'), 'z']);
})();


(function TestOrderOfExecution() {
  log = [];
  assertArrayEquals(['x', 1, 2, 3, 'y', 1, 2, 3, 'z'],
                    [id('x'), ...gen('a'), id('y'), ...gen('b'), id('z')]);
  assertArrayEquals([
    'x', 'a', 1, 'a', 2, 'a', 3, 'a', 'done',
    'y', 'b', 1, 'b', 2, 'b', 3, 'b', 'done',
    'z'
  ], log);
})();


(function TestNotIterable() {
  var a;
  assertThrows(function() {
    a = [...42];
  }, TypeError);
  assertSame(undefined, a);


})();


(function TestInvalidIterator() {
  var iter = {
    [Symbol.iterator]: 42
  };
  var a;
  assertThrows(function() {
    a = [...iter];
  }, TypeError);
  assertSame(undefined, a);
})();


(function TestIteratorNotAnObject() {
  var iter = {
    [Symbol.iterator]() {
      return 42;
    }
  };
  var a;
  assertThrows(function() {
    a = [...iter];
  }, TypeError);
  assertSame(undefined, a);
})();


(function TestIteratorNoNext() {
  var iter = {
    [Symbol.iterator]() {
      return {};
    }
  };
  var a;
  assertThrows(function() {
    a = [...iter];
  }, TypeError);
  assertSame(undefined, a);
})();


(function TestIteratorResultDoneThrows() {
  function MyError() {}
  var iter = {
    [Symbol.iterator]() {
      return {
        next() {
          return {
            get done() {
              throw new MyError();
            }
          }
        }
      };
    }
  };
  var a;
  assertThrows(function() {
    a = [...iter];
  }, MyError);
  assertSame(undefined, a);
})();


(function TestIteratorResultValueThrows() {
  function MyError() {}
  var iter = {
    [Symbol.iterator]() {
      return {
        next() {
          return {
            done: false,
            get value() {
              throw new MyError();
            }
          }
        }
      };
    }
  };
  var a;
  assertThrows(function() {
    a = [...iter];
  }, MyError);
  assertSame(undefined, a);
})();


(function TestOptimize() {
  function f() {
    return [...'abc'];
  }
  %PrepareFunctionForOptimization(f);
  assertArrayEquals(['a', 'b', 'c'], f());
  %OptimizeFunctionOnNextCall(f);
  assertArrayEquals(['a', 'b', 'c'], f());
})();


(function TestDeoptimize() {
  var iter = {
    [Symbol.iterator]() {
      var i = 0;
      return {
        next() {
          %DeoptimizeFunction(f);
          return {value: ++i, done: i === 3};
        }
      };
    }
  };
  function f() {
    return [0, ...iter];
  }

  assertArrayEquals([0, 1, 2], f());
})();


(function TestPrototypeSetter1() {
  Object.defineProperty(Array.prototype, 3, {set() {throw 666}})
  Object.defineProperty(Array.prototype, 4, {set() {throw 666}})

  function f() {
    return ['a', ...['b', 'c', 'd'], 'e']
  }

  %PrepareFunctionForOptimization(f);
  assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
  %OptimizeFunctionOnNextCall(f);
  assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());

  delete Array.prototype[3];
  delete Array.prototype[4];
})();


(function TestPrototypeSetter2() {
  Object.defineProperty(Array.prototype.__proto__, 3, {set() {throw 666}})
  Object.defineProperty(Array.prototype.__proto__, 4, {set() {throw 666}})

  function f() {
    return ['a', ...['b', 'c', 'd'], 'e']
  }

  %PrepareFunctionForOptimization(f);
  assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
  %OptimizeFunctionOnNextCall(f);
  assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());

  delete Array.prototype.__proto__[3];
  delete Array.prototype.__proto__[4];
})();


(function TestPrototypeProxy() {
  const backup = Array.prototype.__proto__;
  Array.prototype.__proto__ = new Proxy({}, {set() {throw 666}});

  function f() {
    return ['a', ...['b', 'c', 'd'], 'e']
  }

  %PrepareFunctionForOptimization(f);
  assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());
  %OptimizeFunctionOnNextCall(f);
  assertArrayEquals(['a', 'b', 'c', 'd', 'e'], f());

  Object.setPrototypeOf(Array.prototype, backup);
})();
