blob: a40c99b738a7ee87a515cd42109d497aa55b526d [file] [log] [blame]
/* -*- 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"
#include <stdio.h>
#include "js/Initialization.h"
#include "js/RootingAPI.h"
JSAPITest* JSAPITest::list;
bool JSAPITest::init()
{
rt = createRuntime();
if (!rt)
return false;
cx = createContext();
if (!cx)
return false;
JS_BeginRequest(cx);
global.init(rt);
createGlobal();
if (!global)
return false;
JS_EnterCompartment(cx, global);
return true;
}
void JSAPITest::uninit()
{
if (oldCompartment) {
JS_LeaveCompartment(cx, oldCompartment);
oldCompartment = nullptr;
}
if (global) {
JS_LeaveCompartment(cx, nullptr);
global = nullptr;
}
if (cx) {
JS_EndRequest(cx);
JS_DestroyContext(cx);
cx = nullptr;
}
if (rt) {
destroyRuntime();
rt = nullptr;
}
}
bool JSAPITest::exec(const char* bytes, const char* filename, int lineno)
{
JS::RootedValue v(cx);
JS::CompileOptions opts(cx);
opts.setFileAndLine(filename, lineno);
return JS::Evaluate(cx, opts, bytes, strlen(bytes), &v) ||
fail(JSAPITestString(bytes), filename, lineno);
}
bool JSAPITest::evaluate(const char* bytes, const char* filename, int lineno,
JS::MutableHandleValue vp)
{
JS::CompileOptions opts(cx);
opts.setFileAndLine(filename, lineno);
return JS::Evaluate(cx, opts, bytes, strlen(bytes), vp) ||
fail(JSAPITestString(bytes), filename, lineno);
}
bool JSAPITest::definePrint()
{
return JS_DefineFunction(cx, global, "print", (JSNative) print, 0, 0);
}
JSObject * JSAPITest::createGlobal(JSPrincipals* principals)
{
/* Create the global object. */
JS::RootedObject newGlobal(cx);
JS::CompartmentOptions options;
options.setVersion(JSVERSION_LATEST);
newGlobal = JS_NewGlobalObject(cx, getGlobalClass(), principals, JS::FireOnNewGlobalHook,
options);
if (!newGlobal)
return nullptr;
JSAutoCompartment ac(cx, newGlobal);
/* Populate the global object with the standard globals, like Object and
Array. */
if (!JS_InitStandardClasses(cx, newGlobal))
return nullptr;
global = newGlobal;
return newGlobal;
}
int main(int argc, char* argv[])
{
int total = 0;
int failures = 0;
const char* filter = (argc == 2) ? argv[1] : nullptr;
if (!JS_Init()) {
printf("TEST-UNEXPECTED-FAIL | jsapi-tests | JS_Init() failed.\n");
return 1;
}
for (JSAPITest* test = JSAPITest::list; test; test = test->next) {
const char* name = test->name();
if (filter && strstr(name, filter) == nullptr)
continue;
total += 1;
printf("%s\n", name);
if (!test->init()) {
printf("TEST-UNEXPECTED-FAIL | %s | Failed to initialize.\n", name);
failures++;
test->uninit();
continue;
}
if (test->run(test->global)) {
printf("TEST-PASS | %s | ok\n", name);
} else {
JSAPITestString messages = test->messages();
printf("%s | %s | %.*s\n",
(test->knownFail ? "TEST-KNOWN-FAIL" : "TEST-UNEXPECTED-FAIL"),
name, (int) messages.length(), messages.begin());
if (!test->knownFail)
failures++;
}
test->uninit();
}
JS_ShutDown();
if (failures) {
printf("\n%d unexpected failure%s.\n", failures, (failures == 1 ? "" : "s"));
return 1;
}
printf("\nPassed: ran %d tests.\n", total);
return 0;
}