/* Any copyright is dedicated to the Public Domain.
 * http://creativecommons.org/licenses/publicdomain/ */

// Reflect.construct invokes constructors.

assertDeepEq(Reflect.construct(Object, []), {});
assertDeepEq(Reflect.construct(String, ["hello"]), new String("hello"));

// Constructing Date creates a real Date object.
var d = Reflect.construct(Date, [1776, 6, 4]);
assertEq(d instanceof Date, true);
assertEq(d.getFullYear(), 1776);  // non-generic method requires real Date object

// [[Construct]] methods don't necessarily create new objects.
var obj = {};
assertEq(Reflect.construct(Object, [obj]), obj);


// === Various kinds of constructors
// We've already seen some builtin constructors.
//
// JS functions:
function f(x) { this.x = x; }
assertDeepEq(Reflect.construct(f, [3]), new f(3));
f.prototype = Array.prototype;
assertDeepEq(Reflect.construct(f, [3]), new f(3));

// Bound functions:
var bound = f.bind(null, "carrot");
assertDeepEq(Reflect.construct(bound, []), new bound);

// Classes:
class Base {
    constructor(...args) {
        this.args = args;
        this.newTarget = new.target;
    }
}
class Derived extends Base {
    constructor(...args) { super(...args); }
}

assertDeepEq(Reflect.construct(Base, []), new Base);
assertDeepEq(Reflect.construct(Derived, [7]), new Derived(7));
g = Derived.bind(null, "q");
assertDeepEq(Reflect.construct(g, [8, 9]), new g(8, 9));

// Cross-compartment wrappers:
var g = newGlobal();
var local = {here: this};
g.eval("function F(arg) { this.arg = arg }");
assertDeepEq(Reflect.construct(g.F, [local]), new g.F(local));

// If first argument to Reflect.construct isn't a constructor, it throws a
// TypeError.
var nonConstructors = [
    {},
    Reflect.construct,  // builtin functions aren't constructors
    x => x + 1,
    Math.max.bind(null, 0),  // bound non-constructors aren't constructors
    ((x, y) => x > y).bind(null, 0),

    // A Proxy to a non-constructor function isn't a constructor, even if a
    // construct handler is present.
    new Proxy(Reflect.construct, {construct(){}}),
];
for (var obj of nonConstructors) {
    assertThrowsInstanceOf(() => Reflect.construct(obj, []), TypeError);
    assertThrowsInstanceOf(() => Reflect.construct(obj, [], Object), TypeError);
}


// === new.target tests

// If the newTarget argument to Reflect.construct is missing, the target is used.
function checkNewTarget() {
    assertEq(new.target, expected);
    expected = undefined;
}
var expected = checkNewTarget;
Reflect.construct(checkNewTarget, []);

// The newTarget argument is correctly passed to the constructor.
var constructors = [Object, Function, f, bound];
for (var ctor of constructors) {
    expected = ctor;
    Reflect.construct(checkNewTarget, [], ctor);
    assertEq(expected, undefined);
}

// The newTarget argument must be a constructor.
for (var v of SOME_PRIMITIVE_VALUES.concat(nonConstructors)) {
    assertThrowsInstanceOf(() => Reflect.construct(checkNewTarget, [], v), TypeError);
}

// The builtin Array constructor uses new.target.prototype and always
// creates a real array object.
function someConstructor() {}
var result = Reflect.construct(Array, [], someConstructor);
assertEq(Reflect.getPrototypeOf(result), someConstructor.prototype);
assertEq(result.length, 0);
assertEq(Array.isArray(result), true);


// For more Reflect.construct tests, see target.js and argumentsList.js.

reportCompare(0, 0);
