Add ICU message format support
[chromium-blink-merge.git] / extensions / renderer / module_system_test.cc
blobebdba3b477bf25e669bfa66e361f5b9d9aafdbb2
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "extensions/renderer/module_system_test.h"
7 #include <map>
8 #include <string>
10 #include "base/callback.h"
11 #include "base/files/file_path.h"
12 #include "base/files/file_util.h"
13 #include "base/lazy_instance.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/path_service.h"
16 #include "base/stl_util.h"
17 #include "base/strings/string_piece.h"
18 #include "extensions/common/extension_paths.h"
19 #include "extensions/renderer/logging_native_handler.h"
20 #include "extensions/renderer/object_backed_native_handler.h"
21 #include "extensions/renderer/utils_native_handler.h"
22 #include "ui/base/resource/resource_bundle.h"
24 namespace extensions {
25 namespace {
27 class FailsOnException : public ModuleSystem::ExceptionHandler {
28 public:
29 FailsOnException() : ModuleSystem::ExceptionHandler(nullptr) {}
30 void HandleUncaughtException(const v8::TryCatch& try_catch) override {
31 FAIL() << "Uncaught exception: " << CreateExceptionString(try_catch);
35 } // namespace
37 // Native JS functions for doing asserts.
38 class ModuleSystemTestEnvironment::AssertNatives
39 : public ObjectBackedNativeHandler {
40 public:
41 explicit AssertNatives(ScriptContext* context)
42 : ObjectBackedNativeHandler(context),
43 assertion_made_(false),
44 failed_(false) {
45 RouteFunction(
46 "AssertTrue",
47 base::Bind(&AssertNatives::AssertTrue, base::Unretained(this)));
48 RouteFunction(
49 "AssertFalse",
50 base::Bind(&AssertNatives::AssertFalse, base::Unretained(this)));
53 bool assertion_made() { return assertion_made_; }
54 bool failed() { return failed_; }
56 void AssertTrue(const v8::FunctionCallbackInfo<v8::Value>& args) {
57 CHECK_EQ(1, args.Length());
58 assertion_made_ = true;
59 failed_ = failed_ || !args[0]->ToBoolean(args.GetIsolate())->Value();
62 void AssertFalse(const v8::FunctionCallbackInfo<v8::Value>& args) {
63 CHECK_EQ(1, args.Length());
64 assertion_made_ = true;
65 failed_ = failed_ || args[0]->ToBoolean(args.GetIsolate())->Value();
68 private:
69 bool assertion_made_;
70 bool failed_;
73 // Source map that operates on std::strings.
74 class ModuleSystemTestEnvironment::StringSourceMap
75 : public ModuleSystem::SourceMap {
76 public:
77 StringSourceMap() {}
78 ~StringSourceMap() override {}
80 v8::Local<v8::Value> GetSource(v8::Isolate* isolate,
81 const std::string& name) override {
82 if (source_map_.count(name) == 0)
83 return v8::Undefined(isolate);
84 return v8::String::NewFromUtf8(isolate, source_map_[name].c_str());
87 bool Contains(const std::string& name) override {
88 return source_map_.count(name);
91 void RegisterModule(const std::string& name, const std::string& source) {
92 CHECK_EQ(0u, source_map_.count(name)) << "Module " << name << " not found";
93 source_map_[name] = source;
96 private:
97 std::map<std::string, std::string> source_map_;
100 ModuleSystemTestEnvironment::ModuleSystemTestEnvironment(v8::Isolate* isolate)
101 : isolate_(isolate),
102 context_holder_(new gin::ContextHolder(isolate_)),
103 handle_scope_(isolate_),
104 source_map_(new StringSourceMap()) {
105 context_holder_->SetContext(v8::Context::New(isolate));
106 context_.reset(new ScriptContext(context_holder_->context(),
107 nullptr, // WebFrame
108 nullptr, // Extension
109 Feature::BLESSED_EXTENSION_CONTEXT,
110 nullptr, // Effective Extension
111 Feature::BLESSED_EXTENSION_CONTEXT));
112 context_->v8_context()->Enter();
113 assert_natives_ = new AssertNatives(context_.get());
116 scoped_ptr<ModuleSystem> module_system(
117 new ModuleSystem(context_.get(), source_map_.get()));
118 context_->set_module_system(module_system.Pass());
120 ModuleSystem* module_system = context_->module_system();
121 module_system->RegisterNativeHandler(
122 "assert", scoped_ptr<NativeHandler>(assert_natives_));
123 module_system->RegisterNativeHandler(
124 "logging",
125 scoped_ptr<NativeHandler>(new LoggingNativeHandler(context_.get())));
126 module_system->RegisterNativeHandler(
127 "utils",
128 scoped_ptr<NativeHandler>(new UtilsNativeHandler(context_.get())));
129 module_system->SetExceptionHandlerForTest(
130 scoped_ptr<ModuleSystem::ExceptionHandler>(new FailsOnException));
133 ModuleSystemTestEnvironment::~ModuleSystemTestEnvironment() {
134 if (context_->is_valid())
135 ShutdownModuleSystem();
138 void ModuleSystemTestEnvironment::RegisterModule(const std::string& name,
139 const std::string& code) {
140 source_map_->RegisterModule(name, code);
143 void ModuleSystemTestEnvironment::RegisterModule(const std::string& name,
144 int resource_id) {
145 const std::string& code = ResourceBundle::GetSharedInstance()
146 .GetRawDataResource(resource_id)
147 .as_string();
148 source_map_->RegisterModule(name, code);
151 void ModuleSystemTestEnvironment::OverrideNativeHandler(
152 const std::string& name,
153 const std::string& code) {
154 RegisterModule(name, code);
155 context_->module_system()->OverrideNativeHandlerForTest(name);
158 void ModuleSystemTestEnvironment::RegisterTestFile(
159 const std::string& module_name,
160 const std::string& file_name) {
161 base::FilePath test_js_file_path;
162 ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &test_js_file_path));
163 test_js_file_path = test_js_file_path.AppendASCII(file_name);
164 std::string test_js;
165 ASSERT_TRUE(base::ReadFileToString(test_js_file_path, &test_js));
166 source_map_->RegisterModule(module_name, test_js);
169 void ModuleSystemTestEnvironment::ShutdownGin() {
170 context_holder_.reset();
173 void ModuleSystemTestEnvironment::ShutdownModuleSystem() {
174 CHECK(context_->is_valid());
175 context_->v8_context()->Exit();
176 context_->Invalidate();
179 v8::Local<v8::Object> ModuleSystemTestEnvironment::CreateGlobal(
180 const std::string& name) {
181 v8::EscapableHandleScope handle_scope(isolate_);
182 v8::Local<v8::Object> object = v8::Object::New(isolate_);
183 isolate_->GetCurrentContext()->Global()->Set(
184 v8::String::NewFromUtf8(isolate_, name.c_str()), object);
185 return handle_scope.Escape(object);
188 ModuleSystemTest::ModuleSystemTest()
189 : isolate_(v8::Isolate::GetCurrent()),
190 should_assertions_be_made_(true) {
193 ModuleSystemTest::~ModuleSystemTest() {
196 void ModuleSystemTest::SetUp() {
197 env_ = CreateEnvironment();
200 void ModuleSystemTest::TearDown() {
201 // All tests must assert at least once unless otherwise specified.
202 EXPECT_EQ(should_assertions_be_made_,
203 env_->assert_natives()->assertion_made());
204 EXPECT_FALSE(env_->assert_natives()->failed());
205 env_.reset();
206 v8::HeapStatistics stats;
207 isolate_->GetHeapStatistics(&stats);
208 size_t old_heap_size = 0;
209 // Run the GC until the heap size reaches a steady state to ensure that
210 // all the garbage is collected.
211 while (stats.used_heap_size() != old_heap_size) {
212 old_heap_size = stats.used_heap_size();
213 isolate_->RequestGarbageCollectionForTesting(
214 v8::Isolate::kFullGarbageCollection);
215 isolate_->GetHeapStatistics(&stats);
219 scoped_ptr<ModuleSystemTestEnvironment> ModuleSystemTest::CreateEnvironment() {
220 return make_scoped_ptr(new ModuleSystemTestEnvironment(isolate_));
223 void ModuleSystemTest::ExpectNoAssertionsMade() {
224 should_assertions_be_made_ = false;
227 void ModuleSystemTest::RunResolvedPromises() {
228 isolate_->RunMicrotasks();
231 } // namespace extensions