149 lines
4.0 KiB
C++
149 lines
4.0 KiB
C++
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
|
* 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()
|
|
{
|
|
cx = createContext();
|
|
if (!cx)
|
|
return false;
|
|
if (!JS::InitSelfHostedCode(cx))
|
|
return false;
|
|
JS_BeginRequest(cx);
|
|
global.init(cx);
|
|
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);
|
|
destroyContext();
|
|
cx = 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::execDontReport(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);
|
|
}
|
|
|
|
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.behaviors().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;
|
|
}
|