Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Side by Side Diff: extensions/renderer/api_test_base.cc

Issue 399363002: Add support for writing unit tests for Mojo-backed apps/extensions APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698