diff options
Diffstat (limited to 'js/src/jsapi-tests/testNewObject.cpp')
-rw-r--r-- | js/src/jsapi-tests/testNewObject.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/js/src/jsapi-tests/testNewObject.cpp b/js/src/jsapi-tests/testNewObject.cpp new file mode 100644 index 000000000..32bcb5afd --- /dev/null +++ b/js/src/jsapi-tests/testNewObject.cpp @@ -0,0 +1,121 @@ +/* -*- 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 "jsapi-tests/tests.h" + +static bool +constructHook(JSContext* cx, unsigned argc, JS::Value* vp) +{ + JS::CallArgs args = CallArgsFromVp(argc, vp); + + // Check that arguments were passed properly from JS_New. + + JS::RootedObject obj(cx, JS_NewPlainObject(cx)); + if (!obj) { + JS_ReportErrorASCII(cx, "test failed, could not construct object"); + return false; + } + if (strcmp(JS_GetClass(obj)->name, "Object") != 0) { + JS_ReportErrorASCII(cx, "test failed, wrong class for 'this'"); + return false; + } + if (args.length() != 3) { + JS_ReportErrorASCII(cx, "test failed, argc == %d", args.length()); + return false; + } + if (!args[0].isInt32() || args[2].toInt32() != 2) { + JS_ReportErrorASCII(cx, "test failed, wrong value in args[2]"); + return false; + } + if (!args.isConstructing()) { + JS_ReportErrorASCII(cx, "test failed, not constructing"); + return false; + } + + // Perform a side-effect to indicate that this hook was actually called. + JS::RootedValue value(cx, args[0]); + JS::RootedObject callee(cx, &args.callee()); + if (!JS_SetElement(cx, callee, 0, value)) + return false; + + args.rval().setObject(*obj); + + // trash the argv, perversely + args[0].setUndefined(); + args[1].setUndefined(); + args[2].setUndefined(); + + return true; +} + +BEGIN_TEST(testNewObject_1) +{ + static const size_t N = 1000; + JS::AutoValueVector argv(cx); + CHECK(argv.resize(N)); + + JS::RootedValue v(cx); + EVAL("Array", &v); + JS::RootedObject Array(cx, v.toObjectOrNull()); + + bool isArray; + + // With no arguments. + JS::RootedObject obj(cx, JS_New(cx, Array, JS::HandleValueArray::empty())); + CHECK(obj); + JS::RootedValue rt(cx, JS::ObjectValue(*obj)); + CHECK(JS_IsArrayObject(cx, obj, &isArray)); + CHECK(isArray); + uint32_t len; + CHECK(JS_GetArrayLength(cx, obj, &len)); + CHECK_EQUAL(len, 0u); + + // With one argument. + argv[0].setInt32(4); + obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, 1)); + CHECK(obj); + rt = JS::ObjectValue(*obj); + CHECK(JS_IsArrayObject(cx, obj, &isArray)); + CHECK(isArray); + CHECK(JS_GetArrayLength(cx, obj, &len)); + CHECK_EQUAL(len, 4u); + + // With N arguments. + for (size_t i = 0; i < N; i++) + argv[i].setInt32(i); + obj = JS_New(cx, Array, JS::HandleValueArray::subarray(argv, 0, N)); + CHECK(obj); + rt = JS::ObjectValue(*obj); + CHECK(JS_IsArrayObject(cx, obj, &isArray)); + CHECK(isArray); + CHECK(JS_GetArrayLength(cx, obj, &len)); + CHECK_EQUAL(len, N); + CHECK(JS_GetElement(cx, obj, N - 1, &v)); + CHECK(v.isInt32(N - 1)); + + // With JSClass.construct. + static const JSClassOps clsOps = { + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, nullptr, nullptr, + nullptr, nullptr, constructHook + }; + static const JSClass cls = { + "testNewObject_1", + 0, + &clsOps + }; + JS::RootedObject ctor(cx, JS_NewObject(cx, &cls)); + CHECK(ctor); + JS::RootedValue rt2(cx, JS::ObjectValue(*ctor)); + obj = JS_New(cx, ctor, JS::HandleValueArray::subarray(argv, 0, 3)); + CHECK(obj); + CHECK(JS_GetElement(cx, ctor, 0, &v)); + CHECK(v.isInt32(0)); + + return true; +} +END_TEST(testNewObject_1) |