/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim: set ts=8 sts=4 et sw=4 tw=99:
 */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


#include "tests.h"

#include "jsfriendapi.h"

const size_t N = 1000;
static jsval argv[N];

static JSBool
constructHook(JSContext *cx, unsigned argc, jsval *vp)
{
    // Check that arguments were passed properly from JS_New.
    JS::RootedObject callee(cx, JSVAL_TO_OBJECT(JS_CALLEE(cx, vp)));

    JS::RootedObject obj(cx, JS_NewObjectForConstructor(cx, js::Jsvalify(&js::ObjectClass), vp));
    if (!obj) {
        JS_ReportError(cx, "test failed, could not construct object");
        return false;
    }
    if (strcmp(JS_GetClass(obj)->name, "Object") != 0) {
        JS_ReportError(cx, "test failed, wrong class for 'this'");
        return false;
    }
    if (argc != 3) {
        JS_ReportError(cx, "test failed, argc == %d", argc);
        return false;
    }
    if (!JSVAL_IS_INT(argv[2]) || JSVAL_TO_INT(argv[2]) != 2) {
        JS_ReportError(cx, "test failed, wrong value in argv[2]");
        return false;
    }
    if (!JS_IsConstructing(cx, vp)) {
        JS_ReportError(cx, "test failed, not constructing");
        return false;
    }

    // Perform a side-effect to indicate that this hook was actually called.
    if (!JS_SetElement(cx, callee, 0, &argv[0]))
        return false;

    *vp = OBJECT_TO_JSVAL(obj);
    argv[0] = argv[1] = argv[2] = JSVAL_VOID;  // trash the argv, perversely
    return true;
}

BEGIN_TEST(testNewObject_1)
{
    // Root the global argv test array. Only the first 2 entries really need to
    // be rooted, since we're only putting integers in the rest.
    CHECK(JS_AddNamedValueRoot(cx, &argv[0], "argv0"));
    CHECK(JS_AddNamedValueRoot(cx, &argv[1], "argv1"));

    JS::RootedValue v(cx);
    EVAL("Array", v.address());
    JS::RootedObject Array(cx, JSVAL_TO_OBJECT(v));

    // With no arguments.
    JS::RootedObject obj(cx, JS_New(cx, Array, 0, NULL));
    CHECK(obj);
    JS::RootedValue rt(cx, OBJECT_TO_JSVAL(obj));
    CHECK(JS_IsArrayObject(cx, obj));
    uint32_t len;
    CHECK(JS_GetArrayLength(cx, obj, &len));
    CHECK_EQUAL(len, 0);

    // With one argument.
    argv[0] = INT_TO_JSVAL(4);
    obj = JS_New(cx, Array, 1, argv);
    CHECK(obj);
    rt = OBJECT_TO_JSVAL(obj);
    CHECK(JS_IsArrayObject(cx, obj));
    CHECK(JS_GetArrayLength(cx, obj, &len));
    CHECK_EQUAL(len, 4);

    // With N arguments.
    for (size_t i = 0; i < N; i++)
        argv[i] = INT_TO_JSVAL(i);
    obj = JS_New(cx, Array, N, argv);
    CHECK(obj);
    rt = OBJECT_TO_JSVAL(obj);
    CHECK(JS_IsArrayObject(cx, obj));
    CHECK(JS_GetArrayLength(cx, obj, &len));
    CHECK_EQUAL(len, N);
    CHECK(JS_GetElement(cx, obj, N - 1, v.address()));
    CHECK_SAME(v, INT_TO_JSVAL(N - 1));

    // With JSClass.construct.
    static JSClass cls = {
        "testNewObject_1",
        0,
        JS_PropertyStub, JS_DeletePropertyStub, JS_PropertyStub, JS_StrictPropertyStub,
        JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, NULL,
        NULL, NULL, NULL, constructHook
    };
    JS::RootedObject ctor(cx, JS_NewObject(cx, &cls, NULL, NULL));
    CHECK(ctor);
    JS::RootedValue rt2(cx, OBJECT_TO_JSVAL(ctor));
    obj = JS_New(cx, ctor, 3, argv);
    CHECK(obj);
    CHECK(JS_GetElement(cx, ctor, 0, v.address()));
    CHECK_SAME(v, JSVAL_ZERO);

    JS_RemoveValueRoot(cx, &argv[0]);
    JS_RemoveValueRoot(cx, &argv[1]);

    return true;
}
END_TEST(testNewObject_1)
