// 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: --harmony-species

// Test the ES2015 @@species feature

'use strict';

// Subclasses of Array construct themselves under map, etc

class MyArray extends Array { }

assertEquals(MyArray, new MyArray().map(()=>{}).constructor);
assertEquals(MyArray, new MyArray().filter(()=>{}).constructor);
assertEquals(MyArray, new MyArray().slice().constructor);
assertEquals(MyArray, new MyArray().splice().constructor);
assertEquals(MyArray, new MyArray().concat([1]).constructor);
assertEquals(1, new MyArray().concat([1])[0]);

// Subclasses can override @@species to return the another class

class MyOtherArray extends Array {
  static get [Symbol.species]() { return MyArray; }
}

assertEquals(MyArray, new MyOtherArray().map(()=>{}).constructor);
assertEquals(MyArray, new MyOtherArray().filter(()=>{}).constructor);
assertEquals(MyArray, new MyOtherArray().slice().constructor);
assertEquals(MyArray, new MyOtherArray().splice().constructor);
assertEquals(MyArray, new MyOtherArray().concat().constructor);

// Array  methods on non-arrays return arrays

class MyNonArray extends Array {
  static get [Symbol.species]() { return MyObject; }
}

class MyObject { }

assertEquals(MyObject,
             Array.prototype.map.call(new MyNonArray(), ()=>{}).constructor);
assertEquals(MyObject,
             Array.prototype.filter.call(new MyNonArray(), ()=>{}).constructor);
assertEquals(MyObject,
             Array.prototype.slice.call(new MyNonArray()).constructor);
assertEquals(MyObject,
             Array.prototype.splice.call(new MyNonArray()).constructor);
assertEquals(MyObject,
             Array.prototype.concat.call(new MyNonArray()).constructor);

assertEquals(undefined,
             Array.prototype.map.call(new MyNonArray(), ()=>{}).length);
assertEquals(undefined,
             Array.prototype.filter.call(new MyNonArray(), ()=>{}).length);
assertEquals(undefined,
             Array.prototype.concat.call(new MyNonArray(), ()=>{}).length);
// slice and splice actually do explicitly define the length for some reason
assertEquals(0, Array.prototype.slice.call(new MyNonArray()).length);
assertEquals(0, Array.prototype.splice.call(new MyNonArray()).length);

// Cross-realm Arrays build same-realm arrays

var realm = Realm.create();
assertEquals(Array,
             Array.prototype.map.call(
                 Realm.eval(realm, "[]"), ()=>{}).constructor);
assertFalse(Array === Realm.eval(realm, "[]").map(()=>{}).constructor);
assertFalse(Array === Realm.eval(realm, "[].map(()=>{}).constructor"));
assertEquals(Array,
             Array.prototype.concat.call(
                 Realm.eval(realm, "[]")).constructor);

// Defaults when constructor or @@species is missing or non-constructor

class MyDefaultArray extends Array {
  static get [Symbol.species]() { return undefined; }
}
assertEquals(Array, new MyDefaultArray().map(()=>{}).constructor);

class MyOtherDefaultArray extends Array { }
assertEquals(MyOtherDefaultArray,
             new MyOtherDefaultArray().map(()=>{}).constructor);
MyOtherDefaultArray.prototype.constructor = undefined;
assertEquals(Array, new MyOtherDefaultArray().map(()=>{}).constructor);
assertEquals(Array, new MyOtherDefaultArray().concat().constructor);

// Exceptions propagated when getting constructor @@species throws

class SpeciesError extends Error { }
class ConstructorError extends Error { }
class MyThrowingArray extends Array {
  static get [Symbol.species]() { throw new SpeciesError; }
}
assertThrows(() => new MyThrowingArray().map(()=>{}), SpeciesError);
Object.defineProperty(MyThrowingArray.prototype, 'constructor', {
    get() { throw new ConstructorError; }
});
assertThrows(() => new MyThrowingArray().map(()=>{}), ConstructorError);

// Previously unexpected errors from setting properties in arrays throw

class FrozenArray extends Array {
  constructor(...args) {
    super(...args);
    Object.freeze(this);
  }
}
assertThrows(() => new FrozenArray([1]).map(()=>0), TypeError);
assertThrows(() => new FrozenArray([1]).filter(()=>true), TypeError);
assertThrows(() => new FrozenArray([1]).slice(0, 1), TypeError);
assertThrows(() => new FrozenArray([1]).splice(0, 1), TypeError);
assertThrows(() => new FrozenArray([]).concat([1]), TypeError);

// Verify call counts and constructor parameters

var count;
var params;
class MyObservedArray extends Array {
  constructor(...args) {
    super(...args);
    params = args;
  }
  static get [Symbol.species]() {
    count++
    return this;
  }
}

count = 0;
params = undefined;
assertEquals(MyObservedArray,
             new MyObservedArray().map(()=>{}).constructor);
assertEquals(1, count);
assertArrayEquals([0], params);

count = 0;
params = undefined;
assertEquals(MyObservedArray,
             new MyObservedArray().filter(()=>{}).constructor);
assertEquals(1, count);
assertArrayEquals([0], params);

count = 0;
params = undefined;
assertEquals(MyObservedArray,
             new MyObservedArray().concat().constructor);
assertEquals(1, count);
assertArrayEquals([0], params);

count = 0;
params = undefined;
assertEquals(MyObservedArray,
             new MyObservedArray().slice().constructor);
assertEquals(1, count);
assertArrayEquals([0], params);

count = 0;
params = undefined;
assertEquals(MyObservedArray,
             new MyObservedArray().splice().constructor);
assertEquals(1, count);
assertArrayEquals([0], params);

// @@species constructor can be a Proxy, and the realm access doesn't
// crash

class MyProxyArray extends Array { }
let ProxyArray = new Proxy(MyProxyArray, {});
MyProxyArray.constructor = ProxyArray;

assertEquals(MyProxyArray, new ProxyArray().map(()=>{}).constructor);
