OLD | NEW |
(Empty) | |
| 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. |
| 4 |
| 5 #include "extensions/renderer/api_test_base.h" |
| 6 |
| 7 #include <vector> |
| 8 |
| 9 #include "base/run_loop.h" |
| 10 #include "extensions/common/extension_urls.h" |
| 11 #include "extensions/renderer/dispatcher.h" |
| 12 #include "extensions/renderer/logging_native_handler.h" |
| 13 #include "extensions/renderer/send_request_natives.h" |
| 14 #include "extensions/renderer/utils_native_handler.h" |
| 15 #include "gin/converter.h" |
| 16 #include "gin/dictionary.h" |
| 17 #include "mojo/bindings/js/core.h" |
| 18 #include "mojo/bindings/js/handle.h" |
| 19 #include "mojo/bindings/js/support.h" |
| 20 #include "mojo/public/cpp/bindings/interface_request.h" |
| 21 #include "mojo/public/cpp/system/core.h" |
| 22 |
| 23 namespace extensions { |
| 24 namespace { |
| 25 |
| 26 // Natives for the implementation of the unit test version of chrome.test. Calls |
| 27 // the provided |quit_closure| when either notifyPass or notifyFail is called. |
| 28 class TestNatives : public gin::Wrappable<TestNatives> { |
| 29 public: |
| 30 static gin::Handle<TestNatives> Create(v8::Isolate* isolate, |
| 31 const base::Closure& quit_closure) { |
| 32 return gin::CreateHandle(isolate, new TestNatives(quit_closure)); |
| 33 } |
| 34 |
| 35 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( |
| 36 v8::Isolate* isolate) OVERRIDE { |
| 37 return Wrappable<TestNatives>::GetObjectTemplateBuilder(isolate) |
| 38 .SetMethod("Log", &TestNatives::Log) |
| 39 .SetMethod("NotifyPass", &TestNatives::NotifyPass) |
| 40 .SetMethod("NotifyFail", &TestNatives::NotifyFail); |
| 41 } |
| 42 |
| 43 void Log(const std::string& value) { logs_ += value + "\n"; } |
| 44 void NotifyPass() { FinishTesting(); } |
| 45 |
| 46 void NotifyFail(const std::string& message) { |
| 47 FinishTesting(); |
| 48 FAIL() << logs_ << message; |
| 49 } |
| 50 |
| 51 void FinishTesting() { |
| 52 base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure_); |
| 53 } |
| 54 |
| 55 static gin::WrapperInfo kWrapperInfo; |
| 56 |
| 57 private: |
| 58 explicit TestNatives(const base::Closure& quit_closure) |
| 59 : quit_closure_(quit_closure) {} |
| 60 |
| 61 const base::Closure quit_closure_; |
| 62 std::string logs_; |
| 63 }; |
| 64 |
| 65 gin::WrapperInfo TestNatives::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| 66 |
| 67 } // namespace |
| 68 |
| 69 gin::WrapperInfo TestServiceProvider::kWrapperInfo = {gin::kEmbedderNativeGin}; |
| 70 |
| 71 gin::Handle<TestServiceProvider> TestServiceProvider::Create( |
| 72 v8::Isolate* isolate) { |
| 73 return gin::CreateHandle(isolate, new TestServiceProvider()); |
| 74 } |
| 75 |
| 76 TestServiceProvider::~TestServiceProvider() { |
| 77 } |
| 78 |
| 79 gin::ObjectTemplateBuilder TestServiceProvider::GetObjectTemplateBuilder( |
| 80 v8::Isolate* isolate) { |
| 81 return Wrappable<TestServiceProvider>::GetObjectTemplateBuilder(isolate) |
| 82 .SetMethod("connectToService", &TestServiceProvider::ConnectToService); |
| 83 } |
| 84 |
| 85 mojo::Handle TestServiceProvider::ConnectToService( |
| 86 const std::string& service_name) { |
| 87 EXPECT_EQ(1u, service_factories_.count(service_name)) |
| 88 << "Unregistered service " << service_name << " requested."; |
| 89 mojo::MessagePipe pipe; |
| 90 std::map<std::string, |
| 91 base::Callback<void(mojo::ScopedMessagePipeHandle)> >::iterator it = |
| 92 service_factories_.find(service_name); |
| 93 if (it != service_factories_.end()) |
| 94 it->second.Run(pipe.handle0.Pass()); |
| 95 return pipe.handle1.release(); |
| 96 } |
| 97 |
| 98 TestServiceProvider::TestServiceProvider() { |
| 99 } |
| 100 |
| 101 ApiTestBase::ApiTestBase() { |
| 102 } |
| 103 ApiTestBase::~ApiTestBase() { |
| 104 } |
| 105 |
| 106 void ApiTestBase::SetUp() { |
| 107 ModuleSystemTest::SetUp(); |
| 108 service_provider_ = TestServiceProvider::Create(env()->isolate()); |
| 109 InitializeEnvironment(); |
| 110 RegisterModules(); |
| 111 } |
| 112 |
| 113 void ApiTestBase::RegisterModules() { |
| 114 v8_schema_registry_.reset(new V8SchemaRegistry); |
| 115 const std::vector<std::pair<std::string, int> > resources = |
| 116 Dispatcher::GetJsResources(); |
| 117 for (std::vector<std::pair<std::string, int> >::const_iterator resource = |
| 118 resources.begin(); |
| 119 resource != resources.end(); |
| 120 ++resource) { |
| 121 if (resource->first != "test_delegate") |
| 122 env()->RegisterModule(resource->first, resource->second); |
| 123 } |
| 124 env()->module_system()->RegisterNativeHandler( |
| 125 "logging", |
| 126 scoped_ptr<NativeHandler>(new LoggingNativeHandler(env()->context()))); |
| 127 env()->module_system()->RegisterNativeHandler( |
| 128 "schema_registry", v8_schema_registry_->AsNativeHandler()); |
| 129 env()->module_system()->RegisterNativeHandler( |
| 130 "utils", |
| 131 scoped_ptr<NativeHandler>(new UtilsNativeHandler(env()->context()))); |
| 132 env()->module_system()->RegisterNativeHandler( |
| 133 "sendRequest", |
| 134 scoped_ptr<NativeHandler>( |
| 135 new SendRequestNatives(NULL, env()->context()))); |
| 136 env()->RegisterTestFile("test_delegate", |
| 137 "test_custom_bindings_unittest_delegate.js"); |
| 138 |
| 139 env()->OverrideNativeHandler( |
| 140 "v8_context", |
| 141 "exports.GetAvailability = function() { return {is_available: true}; };"); |
| 142 env()->OverrideNativeHandler("activityLogger", |
| 143 "exports.LogAPICall = function() {};"); |
| 144 env()->OverrideNativeHandler( |
| 145 "process", |
| 146 "exports.GetContextType = function() { return 'BLESSED_EXTENSION'; };" |
| 147 "exports.GetExtensionId = function() { return 'id'; };" |
| 148 "exports.GetManifestVersion = function() { return 2 };"); |
| 149 env()->OverrideNativeHandler( |
| 150 "event_natives", |
| 151 "exports.AttachEvent = function() {};" |
| 152 "exports.DetachEvent = function() {};" |
| 153 "exports.AttachFilteredEvent = function() {};" |
| 154 "exports.AttachFilteredEvent = function() {};" |
| 155 "exports.MatchAgainstEventFilter = function() { return [] };"); |
| 156 |
| 157 gin::ModuleRegistry::From(env()->context()->v8_context()) |
| 158 ->AddBuiltinModule(env()->isolate(), |
| 159 mojo::js::Core::kModuleName, |
| 160 mojo::js::Core::GetModule(env()->isolate())); |
| 161 gin::ModuleRegistry::From(env()->context()->v8_context()) |
| 162 ->AddBuiltinModule(env()->isolate(), |
| 163 mojo::js::Support::kModuleName, |
| 164 mojo::js::Support::GetModule(env()->isolate())); |
| 165 gin::ModuleRegistry::From(env()->context()->v8_context()) |
| 166 ->AddBuiltinModule(env()->isolate(), |
| 167 "content/public/renderer/service_provider", |
| 168 service_provider_.ToV8()); |
| 169 } |
| 170 |
| 171 void ApiTestBase::InitializeEnvironment() { |
| 172 gin::Dictionary global(env()->isolate(), |
| 173 env()->context()->v8_context()->Global()); |
| 174 gin::Dictionary navigator(gin::Dictionary::CreateEmpty(env()->isolate())); |
| 175 navigator.Set("appVersion", base::StringPiece("")); |
| 176 global.Set("navigator", navigator); |
| 177 gin::Dictionary chrome(gin::Dictionary::CreateEmpty(env()->isolate())); |
| 178 global.Set("chrome", chrome); |
| 179 gin::Dictionary extension(gin::Dictionary::CreateEmpty(env()->isolate())); |
| 180 chrome.Set("extension", extension); |
| 181 gin::Dictionary runtime(gin::Dictionary::CreateEmpty(env()->isolate())); |
| 182 chrome.Set("runtime", runtime); |
| 183 } |
| 184 |
| 185 void ApiTestBase::RunTest(const std::string& file_name, |
| 186 const std::string& test_name) { |
| 187 env()->RegisterTestFile("testBody", file_name); |
| 188 ExpectNoAssertionsMade(); |
| 189 base::RunLoop run_loop; |
| 190 gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule( |
| 191 env()->isolate(), |
| 192 "testNatives", |
| 193 TestNatives::Create(env()->isolate(), run_loop.QuitClosure()).ToV8()); |
| 194 base::MessageLoop::current()->PostTask(FROM_HERE, |
| 195 base::Bind(&ApiTestBase::RunTestInner, |
| 196 base::Unretained(this), |
| 197 test_name, |
| 198 run_loop.QuitClosure())); |
| 199 base::MessageLoop::current()->PostTask( |
| 200 FROM_HERE, |
| 201 base::Bind(&ApiTestBase::RunPromisesAgain, base::Unretained(this))); |
| 202 run_loop.Run(); |
| 203 } |
| 204 |
| 205 void ApiTestBase::RunTestInner(const std::string& test_name, |
| 206 const base::Closure& quit_closure) { |
| 207 v8::HandleScope scope(env()->isolate()); |
| 208 ModuleSystem::NativesEnabledScope natives_enabled(env()->module_system()); |
| 209 v8::Handle<v8::Value> result = |
| 210 env()->module_system()->CallModuleMethod("testBody", test_name); |
| 211 if (!result->IsTrue()) { |
| 212 base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure); |
| 213 FAIL() << "Failed to run test \"" << test_name << "\""; |
| 214 } |
| 215 } |
| 216 |
| 217 void ApiTestBase::RunPromisesAgain() { |
| 218 RunResolvedPromises(); |
| 219 base::MessageLoop::current()->PostTask( |
| 220 FROM_HERE, |
| 221 base::Bind(&ApiTestBase::RunPromisesAgain, base::Unretained(this))); |
| 222 } |
| 223 |
| 224 } // namespace extensions |
OLD | NEW |