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

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: rebase 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 <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 InitializeEnvironment();
109 RegisterModules();
110 }
111
112 void ApiTestBase::RegisterModules() {
113 v8_schema_registry_.reset(new V8SchemaRegistry);
114 const std::vector<std::pair<std::string, int> > resources =
115 Dispatcher::GetJsResources();
116 for (std::vector<std::pair<std::string, int> >::const_iterator resource =
117 resources.begin();
118 resource != resources.end();
119 ++resource) {
120 if (resource->first != "test_environment_specific_bindings")
121 env()->RegisterModule(resource->first, resource->second);
122 }
123 env()->module_system()->RegisterNativeHandler(
124 "logging",
125 scoped_ptr<NativeHandler>(new LoggingNativeHandler(env()->context())));
126 env()->module_system()->RegisterNativeHandler(
127 "schema_registry", v8_schema_registry_->AsNativeHandler());
128 env()->module_system()->RegisterNativeHandler(
129 "utils",
130 scoped_ptr<NativeHandler>(new UtilsNativeHandler(env()->context())));
131 env()->module_system()->RegisterNativeHandler(
132 "sendRequest",
133 scoped_ptr<NativeHandler>(
134 new SendRequestNatives(NULL, env()->context())));
135 env()->RegisterTestFile("test_environment_specific_bindings",
136 "unit_test_environment_specific_bindings.js");
137
138 env()->OverrideNativeHandler(
139 "v8_context",
140 "exports.GetAvailability = function() { return {is_available: true}; };");
141 env()->OverrideNativeHandler("activityLogger",
142 "exports.LogAPICall = function() {};");
143 env()->OverrideNativeHandler(
144 "process",
145 "exports.GetContextType = function() { return 'BLESSED_EXTENSION'; };"
146 "exports.GetExtensionId = function() { return 'id'; };"
147 "exports.GetManifestVersion = function() { return 2 };");
148 env()->OverrideNativeHandler(
149 "event_natives",
150 "exports.AttachEvent = function() {};"
151 "exports.DetachEvent = function() {};"
152 "exports.AttachFilteredEvent = function() {};"
153 "exports.AttachFilteredEvent = function() {};"
154 "exports.MatchAgainstEventFilter = function() { return [] };");
155
156 gin::ModuleRegistry::From(env()->context()->v8_context())
157 ->AddBuiltinModule(env()->isolate(),
158 mojo::js::Core::kModuleName,
159 mojo::js::Core::GetModule(env()->isolate()));
160 gin::ModuleRegistry::From(env()->context()->v8_context())
161 ->AddBuiltinModule(env()->isolate(),
162 mojo::js::Support::kModuleName,
163 mojo::js::Support::GetModule(env()->isolate()));
164 gin::Handle<TestServiceProvider> service_provider =
165 TestServiceProvider::Create(env()->isolate());
166 service_provider_ = service_provider.get();
167 gin::ModuleRegistry::From(env()->context()->v8_context())
168 ->AddBuiltinModule(env()->isolate(),
169 "content/public/renderer/service_provider",
170 service_provider.ToV8());
171 }
172
173 void ApiTestBase::InitializeEnvironment() {
174 gin::Dictionary global(env()->isolate(),
175 env()->context()->v8_context()->Global());
176 gin::Dictionary navigator(gin::Dictionary::CreateEmpty(env()->isolate()));
177 navigator.Set("appVersion", base::StringPiece(""));
178 global.Set("navigator", navigator);
179 gin::Dictionary chrome(gin::Dictionary::CreateEmpty(env()->isolate()));
180 global.Set("chrome", chrome);
181 gin::Dictionary extension(gin::Dictionary::CreateEmpty(env()->isolate()));
182 chrome.Set("extension", extension);
183 gin::Dictionary runtime(gin::Dictionary::CreateEmpty(env()->isolate()));
184 chrome.Set("runtime", runtime);
185 }
186
187 void ApiTestBase::RunTest(const std::string& file_name,
188 const std::string& test_name) {
189 env()->RegisterTestFile("testBody", file_name);
190 ExpectNoAssertionsMade();
191 base::RunLoop run_loop;
192 gin::ModuleRegistry::From(env()->context()->v8_context())->AddBuiltinModule(
193 env()->isolate(),
194 "testNatives",
195 TestNatives::Create(env()->isolate(), run_loop.QuitClosure()).ToV8());
196 base::MessageLoop::current()->PostTask(FROM_HERE,
197 base::Bind(&ApiTestBase::RunTestInner,
198 base::Unretained(this),
199 test_name,
200 run_loop.QuitClosure()));
201 base::MessageLoop::current()->PostTask(
202 FROM_HERE,
203 base::Bind(&ApiTestBase::RunPromisesAgain, base::Unretained(this)));
204 run_loop.Run();
205 }
206
207 void ApiTestBase::RunTestInner(const std::string& test_name,
208 const base::Closure& quit_closure) {
209 v8::HandleScope scope(env()->isolate());
210 ModuleSystem::NativesEnabledScope natives_enabled(env()->module_system());
211 v8::Handle<v8::Value> result =
212 env()->module_system()->CallModuleMethod("testBody", test_name);
213 if (!result->IsTrue()) {
214 base::MessageLoop::current()->PostTask(FROM_HERE, quit_closure);
215 FAIL() << "Failed to run test \"" << test_name << "\"";
216 }
217 }
218
219 void ApiTestBase::RunPromisesAgain() {
220 RunResolvedPromises();
221 base::MessageLoop::current()->PostTask(
222 FROM_HERE,
223 base::Bind(&ApiTestBase::RunPromisesAgain, base::Unretained(this)));
224 }
225
226 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698