Chromium Code Reviews| 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 "base/run_loop.h" | |
| 8 #include "extensions/common/extension_urls.h" | |
| 9 #include "extensions/renderer/logging_native_handler.h" | |
| 10 #include "extensions/renderer/send_request_natives.h" | |
| 11 #include "extensions/renderer/utils_native_handler.h" | |
| 12 #include "gin/converter.h" | |
| 13 #include "gin/dictionary.h" | |
| 14 #include "grit/content_resources.h" | |
| 15 #include "grit/extensions_renderer_resources.h" | |
| 16 #include "mojo/bindings/js/core.h" | |
| 17 #include "mojo/bindings/js/handle.h" | |
| 18 #include "mojo/bindings/js/support.h" | |
| 19 #include "mojo/public/cpp/bindings/interface_request.h" | |
| 20 #include "mojo/public/cpp/system/core.h" | |
| 21 #include "mojo/public/js/bindings/constants.h" | |
| 22 | |
| 23 namespace extensions { | |
| 24 namespace { | |
| 25 | |
| 26 class TestNatives : public gin::Wrappable<TestNatives> { | |
| 27 public: | |
| 28 static gin::Handle<TestNatives> Create(v8::Isolate* isolate, | |
| 29 base::RunLoop* run_loop) { | |
| 30 return gin::CreateHandle(isolate, new TestNatives(run_loop)); | |
| 31 } | |
| 32 | |
| 33 virtual gin::ObjectTemplateBuilder GetObjectTemplateBuilder( | |
| 34 v8::Isolate* isolate) OVERRIDE { | |
| 35 return Wrappable<TestNatives>::GetObjectTemplateBuilder(isolate) | |
| 36 .SetMethod("Log", &TestNatives::Log) | |
| 37 .SetMethod("NotifyPass", &TestNatives::NotifyPass) | |
| 38 .SetMethod("NotifyFail", &TestNatives::NotifyFail); | |
| 39 } | |
| 40 | |
| 41 void Log(const std::string& value) { logs_ += value + "\n"; } | |
| 42 void NotifyPass() { FinishTesting(); } | |
| 43 | |
| 44 void NotifyFail(const std::string& message) { | |
| 45 FinishTesting(); | |
| 46 FAIL() << logs_ << message; | |
| 47 } | |
| 48 | |
| 49 void FinishTesting() { | |
| 50 base::MessageLoop::current()->PostTask(FROM_HERE, run_loop_->QuitClosure()); | |
|
not at google - send to devlin
2014/07/18 15:09:13
do you mean to also pump the message loop here? ho
Sam McNally
2014/07/21 03:56:27
The test functions and their callbacks run on the
| |
| 51 } | |
| 52 | |
| 53 static gin::WrapperInfo kWrapperInfo; | |
| 54 | |
| 55 private: | |
| 56 explicit TestNatives(base::RunLoop* run_loop) : run_loop_(run_loop) {} | |
| 57 | |
| 58 base::RunLoop* run_loop_; | |
| 59 std::string logs_; | |
| 60 }; | |
| 61 | |
| 62 gin::WrapperInfo TestNatives::kWrapperInfo = {gin::kEmbedderNativeGin}; | |
| 63 | |
| 64 } // namespace | |
| 65 | |
| 66 gin::WrapperInfo TestServiceProvider::kWrapperInfo = {gin::kEmbedderNativeGin}; | |
| 67 | |
| 68 gin::Handle<TestServiceProvider> TestServiceProvider::Create( | |
| 69 v8::Isolate* isolate) { | |
| 70 return gin::CreateHandle(isolate, new TestServiceProvider()); | |
| 71 } | |
| 72 | |
| 73 TestServiceProvider::~TestServiceProvider() { | |
| 74 } | |
| 75 | |
| 76 gin::ObjectTemplateBuilder TestServiceProvider::GetObjectTemplateBuilder( | |
| 77 v8::Isolate* isolate) { | |
| 78 return Wrappable<TestServiceProvider>::GetObjectTemplateBuilder(isolate) | |
| 79 .SetMethod("connectToService", &TestServiceProvider::ConnectToService); | |
| 80 } | |
| 81 | |
| 82 mojo::Handle TestServiceProvider::ConnectToService( | |
| 83 const std::string& service_name) { | |
| 84 EXPECT_EQ(1u, service_factories_.count(service_name)) | |
| 85 << "Unregistered service " << service_name << " requested."; | |
| 86 mojo::MessagePipe pipe; | |
| 87 std::map<std::string, | |
| 88 base::Callback<void(mojo::ScopedMessagePipeHandle)> >::iterator it = | |
| 89 service_factories_.find(service_name); | |
| 90 if (it != service_factories_.end()) | |
| 91 it->second.Run(pipe.handle0.Pass()); | |
| 92 return pipe.handle1.release(); | |
| 93 } | |
| 94 | |
| 95 TestServiceProvider::TestServiceProvider() { | |
| 96 } | |
| 97 | |
| 98 ApiTestBase::ApiTestBase() { | |
| 99 } | |
| 100 ApiTestBase::~ApiTestBase() { | |
| 101 } | |
| 102 | |
| 103 void ApiTestBase::SetUp() { | |
| 104 ModuleSystemTest::SetUp(); | |
| 105 service_provider_ = TestServiceProvider::Create(env()->isolate()); | |
| 106 InitializeEnvironment(); | |
| 107 RegisterModules(); | |
| 108 } | |
| 109 | |
| 110 void ApiTestBase::RegisterModules() { | |
| 111 v8_schema_registry_.reset(new V8SchemaRegistry); | |
| 112 env()->RegisterModule("json_schema", IDR_JSON_SCHEMA_JS); | |
|
not at google - send to devlin
2014/07/18 15:09:13
shame to need to do all of this, since it means th
Sam McNally
2014/07/21 03:56:27
Done.
| |
| 113 env()->RegisterModule("lastError", IDR_LAST_ERROR_JS); | |
| 114 env()->RegisterModule(kEventBindings, IDR_EVENT_BINDINGS_JS); | |
| 115 env()->RegisterModule("schemaUtils", IDR_SCHEMA_UTILS_JS); | |
| 116 env()->RegisterModule("sendRequest", IDR_SEND_REQUEST_JS); | |
| 117 env()->RegisterModule("uncaught_exception_handler", | |
| 118 IDR_UNCAUGHT_EXCEPTION_HANDLER_JS); | |
| 119 env()->RegisterModule("unload_event", IDR_UNLOAD_EVENT_JS); | |
| 120 env()->RegisterModule("utils", IDR_UTILS_JS); | |
| 121 env()->RegisterModule("binding", IDR_BINDING_JS); | |
| 122 env()->module_system()->RegisterNativeHandler( | |
| 123 "logging", | |
| 124 scoped_ptr<NativeHandler>(new LoggingNativeHandler(env()->context()))); | |
| 125 env()->module_system()->RegisterNativeHandler( | |
| 126 "schema_registry", v8_schema_registry_->AsNativeHandler()); | |
| 127 env()->module_system()->RegisterNativeHandler( | |
| 128 "utils", | |
| 129 scoped_ptr<NativeHandler>(new UtilsNativeHandler(env()->context()))); | |
| 130 env()->module_system()->RegisterNativeHandler( | |
| 131 "sendRequest", | |
| 132 scoped_ptr<NativeHandler>( | |
| 133 new SendRequestNatives(NULL, env()->context()))); | |
| 134 env()->RegisterTestFile("test", "test_unittest_custom_bindings.js"); | |
| 135 | |
| 136 env()->OverrideNativeHandler( | |
| 137 "v8_context", | |
| 138 "exports.GetAvailability = function() { return {is_available: true}; };"); | |
| 139 env()->OverrideNativeHandler("activityLogger", | |
| 140 "exports.LogAPICall = function() {};"); | |
| 141 env()->OverrideNativeHandler( | |
| 142 "process", | |
| 143 "exports.GetContextType = function() { return 'BLESSED_EXTENSION'; };" | |
| 144 "exports.GetExtensionId = function() { return 'id'; };" | |
| 145 "exports.GetManifestVersion = function() { return 2 };"); | |
| 146 env()->OverrideNativeHandler( | |
| 147 "event_natives", | |
| 148 "exports.AttachEvent = function() {};" | |
| 149 "exports.DetachEvent = function() {};" | |
| 150 "exports.AttachFilteredEvent = function() {};" | |
| 151 "exports.AttachFilteredEvent = function() {};" | |
| 152 "exports.MatchAgainstEventFilter = function() { return [] };"); | |
| 153 | |
| 154 env()->RegisterModule(mojo::kCodecModuleName, IDR_MOJO_CODEC_JS); | |
| 155 env()->RegisterModule(mojo::kConnectionModuleName, IDR_MOJO_CONNECTION_JS); | |
| 156 env()->RegisterModule(mojo::kConnectorModuleName, IDR_MOJO_CONNECTOR_JS); | |
| 157 env()->RegisterModule(mojo::kRouterModuleName, IDR_MOJO_ROUTER_JS); | |
| 158 env()->RegisterModule(mojo::kUnicodeModuleName, IDR_MOJO_UNICODE_JS); | |
| 159 gin::ModuleRegistry::From(env()->context()->v8_context()) | |
| 160 ->AddBuiltinModule(env()->isolate(), | |
| 161 mojo::js::Core::kModuleName, | |
| 162 mojo::js::Core::GetModule(env()->isolate())); | |
| 163 gin::ModuleRegistry::From(env()->context()->v8_context()) | |
| 164 ->AddBuiltinModule(env()->isolate(), | |
| 165 mojo::js::Support::kModuleName, | |
| 166 mojo::js::Support::GetModule(env()->isolate())); | |
| 167 gin::ModuleRegistry::From(env()->context()->v8_context()) | |
| 168 ->AddBuiltinModule(env()->isolate(), | |
| 169 "content/public/renderer/service_provider", | |
| 170 service_provider_.ToV8()); | |
| 171 gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule( | |
| 172 env()->isolate(), | |
| 173 "testNatives", | |
| 174 TestNatives::Create(env()->isolate(), &run_loop_).ToV8()); | |
| 175 } | |
| 176 | |
| 177 void ApiTestBase::InitializeEnvironment() { | |
| 178 gin::Dictionary global(env()->isolate(), | |
| 179 env()->context()->v8_context()->Global()); | |
| 180 gin::Dictionary navigator(gin::Dictionary::CreateEmpty(env()->isolate())); | |
| 181 navigator.Set("appVersion", base::StringPiece("")); | |
| 182 global.Set("navigator", navigator); | |
| 183 gin::Dictionary chrome(gin::Dictionary::CreateEmpty(env()->isolate())); | |
| 184 global.Set("chrome", chrome); | |
| 185 gin::Dictionary extension(gin::Dictionary::CreateEmpty(env()->isolate())); | |
| 186 chrome.Set("extension", extension); | |
| 187 gin::Dictionary runtime(gin::Dictionary::CreateEmpty(env()->isolate())); | |
| 188 chrome.Set("runtime", runtime); | |
| 189 } | |
| 190 | |
| 191 void ApiTestBase::RunTest(const std::string& file_name, | |
| 192 const std::string& test_name) { | |
| 193 env()->RegisterTestFile("testBody", file_name); | |
| 194 ExpectNoAssertionsMade(); | |
| 195 base::MessageLoop::current()->PostTask( | |
| 196 FROM_HERE, | |
| 197 base::Bind( | |
| 198 &ApiTestBase::RunTestInner, base::Unretained(this), test_name)); | |
| 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 v8::HandleScope scope(env()->isolate()); | |
| 207 ModuleSystem::NativesEnabledScope natives_enabled(env()->module_system()); | |
| 208 v8::Handle<v8::Value> result = | |
| 209 env()->module_system()->CallModuleMethod("testBody", test_name); | |
| 210 if (!result->IsTrue()) { | |
| 211 run_loop_.Quit(); | |
| 212 FAIL() << "Failed to run test \"" << test_name << "\""; | |
| 213 } | |
| 214 } | |
| 215 | |
| 216 void ApiTestBase::RunPromisesAgain() { | |
| 217 RunResolvedPromises(); | |
| 218 base::MessageLoop::current()->PostTask( | |
| 219 FROM_HERE, | |
| 220 base::Bind(&ApiTestBase::RunPromisesAgain, base::Unretained(this))); | |
| 221 } | |
| 222 | |
| 223 } // namespace extensions | |
| OLD | NEW |