summaryrefslogtreecommitdiffstats
path: root/chrome/test/base/v8_unit_test.cc
diff options
context:
space:
mode:
authorscr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-03 01:25:29 +0000
committerscr@chromium.org <scr@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-03 01:25:29 +0000
commit369d25ca02211727361c11af0b8e8db2b234d421 (patch)
tree0d21be7adaca018c56a0728eb5a790f109e2ca1c /chrome/test/base/v8_unit_test.cc
parent1e29b4e78e03e519bf8e79160d827c22a0c39de0 (diff)
downloadchromium_src-369d25ca02211727361c11af0b8e8db2b234d421.zip
chromium_src-369d25ca02211727361c11af0b8e8db2b234d421.tar.gz
chromium_src-369d25ca02211727361c11af0b8e8db2b234d421.tar.bz2
Allow javascript unit tests using webui test_api framework.
I moved javascript2webui.js over to chrome/test/base/js2gtest.js and shared it across webui and unit tests with an extra parameter for test type, which governs the few differences, such as what to include/subclass from and the flavor of gtest (TEST_F v. IN_PROC_BROWSER_TEST_F). v8_unit_test implemented 2 main methods to make it work with the generated C++ - AddLibrary - loads the file in the test context - RunJavascriptF - launches the runTest with the testFixture and testName, coordinating with Error and ChromeSend to report results. Helper functions: - Error - watches for console.error, noting failure if seen. - ChromeSend - pulls apart the result from the test_api's call to chrome.send('testResult', [ok, msg]) R=arv@chromium.org BUG=87820 TEST=unit_tests --gtest_filter=FrameworkUnitTest.* Review URL: http://codereview.chromium.org/8418015 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@108391 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/test/base/v8_unit_test.cc')
-rw-r--r--chrome/test/base/v8_unit_test.cc191
1 files changed, 176 insertions, 15 deletions
diff --git a/chrome/test/base/v8_unit_test.cc b/chrome/test/base/v8_unit_test.cc
index 798a03f..92406ed 100644
--- a/chrome/test/base/v8_unit_test.cc
+++ b/chrome/test/base/v8_unit_test.cc
@@ -4,17 +4,166 @@
#include "chrome/test/base/v8_unit_test.h"
+#include "base/file_util.h"
+#include "base/logging.h"
+#include "base/path_service.h"
#include "base/string_piece.h"
#include "base/stringprintf.h"
+#include "chrome/common/chrome_paths.h"
-V8UnitTest::V8UnitTest() {}
+namespace {
+
+// |args| are passed through the various JavaScript logging functions such as
+// console.log. Returns a string appropriate for logging with LOG(severity).
+std::string LogArgs2String(const v8::Arguments& args) {
+ std::string message;
+ bool first = true;
+ for (int i = 0; i < args.Length(); i++) {
+ v8::HandleScope handle_scope;
+ if (first)
+ first = false;
+ else
+ message += " ";
+
+ v8::String::Utf8Value str(args[i]);
+ message += *str;
+ }
+ return message;
+}
+
+// Whether errors were seen.
+bool had_errors = false;
+
+// testDone results.
+bool testResult_ok = false;
+
+// Location of test data (currently test/data/webui).
+FilePath test_data_directory;
+
+// Location of generated test data (<(PROGRAM_DIR)/test_data).
+FilePath gen_test_data_directory;
+
+} // namespace
+
+V8UnitTest::V8UnitTest() {
+ InitPathsAndLibraries();
+}
V8UnitTest::~V8UnitTest() {}
+void V8UnitTest::AddLibrary(const FilePath& library_path) {
+ user_libraries_.push_back(library_path);
+}
+
+bool V8UnitTest::ExecuteJavascriptLibraries() {
+ std::string utf8_content;
+ for (std::vector<FilePath>::iterator user_libraries_iterator =
+ user_libraries_.begin();
+ user_libraries_iterator != user_libraries_.end();
+ ++user_libraries_iterator) {
+ std::string library_content;
+ FilePath library_file(*user_libraries_iterator);
+ if (!user_libraries_iterator->IsAbsolute()) {
+ FilePath gen_file = gen_test_data_directory.Append(library_file);
+ library_file = file_util::PathExists(gen_file) ? gen_file :
+ test_data_directory.Append(*user_libraries_iterator);
+ }
+ if (!file_util::ReadFileToString(library_file, &library_content)) {
+ ADD_FAILURE() << library_file.value();
+ return false;
+ }
+ ExecuteScriptInContext(library_content, library_file.MaybeAsASCII());
+ if (::testing::Test::HasFatalFailure())
+ return false;
+ }
+ return true;
+}
+
+bool V8UnitTest::RunJavascriptTestF(
+ const std::string& testFixture, const std::string& testName) {
+ had_errors = false;
+ testResult_ok = false;
+ std::string test_js;
+ if (!ExecuteJavascriptLibraries())
+ return false;
+
+ v8::Context::Scope context_scope(context_);
+ v8::HandleScope handle_scope;
+
+ v8::Handle<v8::Value> functionProperty =
+ context_->Global()->Get(v8::String::New("runTest"));
+ EXPECT_FALSE(functionProperty.IsEmpty());
+ if (::testing::Test::HasNonfatalFailure())
+ return false;
+ EXPECT_TRUE(functionProperty->IsFunction());
+ if (::testing::Test::HasNonfatalFailure())
+ return false;
+ v8::Handle<v8::Function> function =
+ v8::Handle<v8::Function>::Cast(functionProperty);
+
+ v8::Local<v8::Array> params = v8::Array::New();
+ params->Set(0, v8::String::New(testFixture.data(), testFixture.size()));
+ params->Set(1, v8::String::New(testName.data(), testName.size()));
+ v8::Handle<v8::Value> args[] = {
+ v8::Boolean::New(false),
+ v8::String::New("RUN_TEST_F"),
+ params
+ };
+
+ v8::TryCatch try_catch;
+ v8::Handle<v8::Value> result = function->Call(context_->Global(), 3, args);
+ // The test fails if an exception was thrown.
+ EXPECT_FALSE(result.IsEmpty());
+ if (::testing::Test::HasNonfatalFailure())
+ return false;
+
+ // Ok if ran successfully, passed tests, and didn't have console errors.
+ return result->BooleanValue() && testResult_ok && !had_errors;
+}
+
+void V8UnitTest::InitPathsAndLibraries() {
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_data_directory));
+ test_data_directory = test_data_directory.AppendASCII("webui");
+ ASSERT_TRUE(PathService::Get(chrome::DIR_GEN_TEST_DATA,
+ &gen_test_data_directory));
+
+ FilePath mockPath;
+ ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &mockPath));
+ mockPath = mockPath.AppendASCII("chrome");
+ mockPath = mockPath.AppendASCII("third_party");
+ mockPath = mockPath.AppendASCII("mock4js");
+ mockPath = mockPath.AppendASCII("mock4js.js");
+ AddLibrary(mockPath);
+
+ FilePath testApiPath;
+ ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &testApiPath));
+ testApiPath = testApiPath.AppendASCII("webui");
+ testApiPath = testApiPath.AppendASCII("test_api.js");
+ AddLibrary(testApiPath);
+}
+
void V8UnitTest::SetUp() {
v8::Handle<v8::ObjectTemplate> global = v8::ObjectTemplate::New();
- global->Set(v8::String::New("log"),
- v8::FunctionTemplate::New(&V8UnitTest::Log));
+ v8::Handle<v8::String> logString = v8::String::New("log");
+ v8::Handle<v8::FunctionTemplate> logFunction =
+ v8::FunctionTemplate::New(&V8UnitTest::Log);
+ global->Set(logString, logFunction);
+
+ // Set up chrome object for chrome.send().
+ v8::Handle<v8::ObjectTemplate> chrome = v8::ObjectTemplate::New();
+ global->Set(v8::String::New("chrome"), chrome);
+ chrome->Set(v8::String::New("send"),
+ v8::FunctionTemplate::New(&V8UnitTest::ChromeSend));
+
+ // Set up console object for console.log(), etc.
+ v8::Handle<v8::ObjectTemplate> console = v8::ObjectTemplate::New();
+ global->Set(v8::String::New("console"), console);
+ console->Set(logString, logFunction);
+ console->Set(v8::String::New("info"), logFunction);
+ console->Set(v8::String::New("warn"), logFunction);
+ console->Set(v8::String::New("error"),
+ v8::FunctionTemplate::New(&V8UnitTest::Error));
+
context_ = v8::Context::New(NULL, global);
}
@@ -85,18 +234,30 @@ void V8UnitTest::TestFunction(const std::string& function_name) {
// static
v8::Handle<v8::Value> V8UnitTest::Log(const v8::Arguments& args) {
- std::string message;
- bool first = true;
- for (int i = 0; i < args.Length(); i++) {
- v8::HandleScope handle_scope;
- if (first) {
- first = false;
- } else {
- message += " ";
- }
- v8::String::Utf8Value str(args[i]);
- message += *str;
+ LOG(INFO) << LogArgs2String(args);
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> V8UnitTest::Error(const v8::Arguments& args) {
+ had_errors = true;
+ LOG(ERROR) << LogArgs2String(args);
+ return v8::Undefined();
+}
+
+v8::Handle<v8::Value> V8UnitTest::ChromeSend(const v8::Arguments& args) {
+ v8::HandleScope handle_scope;
+ EXPECT_EQ(2, args.Length());
+ if (::testing::Test::HasNonfatalFailure())
+ return v8::Undefined();
+ v8::String::Utf8Value message(args[0]);
+ v8::Handle<v8::Array> testResult(args[1].As<v8::Array>());
+ EXPECT_EQ(2U, testResult->Length());
+ if (::testing::Test::HasNonfatalFailure())
+ return v8::Undefined();
+ testResult_ok = testResult->Get(0)->BooleanValue();
+ if (!testResult_ok) {
+ v8::String::Utf8Value message(testResult->Get(1));
+ LOG(ERROR) << *message;
}
- std::cout << message << "\n";
return v8::Undefined();
}