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

Side by Side Diff: extensions/renderer/bindings/api_event_handler_unittest.cc

Issue 2973903002: [Extensions Bindings] Introduce a supportsLazyListeners property (Closed)
Patch Set: . Created 3 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
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "extensions/renderer/bindings/api_event_handler.h" 5 #include "extensions/renderer/bindings/api_event_handler.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback_helpers.h" 8 #include "base/callback_helpers.h"
9 #include "base/memory/ptr_util.h" 9 #include "base/memory/ptr_util.h"
10 #include "base/optional.h" 10 #include "base/optional.h"
11 #include "base/test/mock_callback.h" 11 #include "base/test/mock_callback.h"
12 #include "base/values.h" 12 #include "base/values.h"
13 #include "extensions/common/event_filtering_info.h" 13 #include "extensions/common/event_filtering_info.h"
14 #include "extensions/renderer/bindings/api_binding_test.h" 14 #include "extensions/renderer/bindings/api_binding_test.h"
15 #include "extensions/renderer/bindings/api_binding_test_util.h" 15 #include "extensions/renderer/bindings/api_binding_test_util.h"
16 #include "gin/arguments.h" 16 #include "gin/arguments.h"
17 #include "gin/converter.h" 17 #include "gin/converter.h"
18 #include "gin/public/context_holder.h" 18 #include "gin/public/context_holder.h"
19 #include "testing/gmock/include/gmock/gmock.h" 19 #include "testing/gmock/include/gmock/gmock.h"
20 20
21 namespace extensions { 21 namespace extensions {
22 22
23 namespace { 23 namespace {
24 24
25 const char kAddListenerFunction[] =
26 "(function(event, listener) { event.addListener(listener); })";
27 const char kRemoveListenerFunction[] =
28 "(function(event, listener) { event.removeListener(listener); })";
29
25 using MockEventChangeHandler = ::testing::StrictMock< 30 using MockEventChangeHandler = ::testing::StrictMock<
26 base::MockCallback<APIEventHandler::EventListenersChangedMethod>>; 31 base::MockCallback<APIEventHandler::EventListenersChangedMethod>>;
27 32
28 void DoNothingOnEventListenersChanged(const std::string& event_name, 33 void DoNothingOnEventListenersChanged(const std::string& event_name,
29 binding::EventListenersChanged change, 34 binding::EventListenersChanged change,
30 const base::DictionaryValue* value, 35 const base::DictionaryValue* value,
31 bool was_manual, 36 bool was_manual,
32 v8::Local<v8::Context> context) {} 37 v8::Local<v8::Context> context) {}
33 38
34 class APIEventHandlerTest : public APIBindingTest { 39 class APIEventHandlerTest : public APIBindingTest {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } // namespace 75 } // namespace
71 76
72 // Tests adding, removing, and querying event listeners by calling the 77 // Tests adding, removing, and querying event listeners by calling the
73 // associated methods on the JS object. 78 // associated methods on the JS object.
74 TEST_F(APIEventHandlerTest, AddingRemovingAndQueryingEventListeners) { 79 TEST_F(APIEventHandlerTest, AddingRemovingAndQueryingEventListeners) {
75 const char kEventName[] = "alpha"; 80 const char kEventName[] = "alpha";
76 v8::HandleScope handle_scope(isolate()); 81 v8::HandleScope handle_scope(isolate());
77 v8::Local<v8::Context> context = MainContext(); 82 v8::Local<v8::Context> context = MainContext();
78 83
79 v8::Local<v8::Object> event = handler()->CreateEventInstance( 84 v8::Local<v8::Object> event = handler()->CreateEventInstance(
80 kEventName, false, binding::kNoListenerMax, true, context); 85 kEventName, false, true, binding::kNoListenerMax, true, context);
81 ASSERT_FALSE(event.IsEmpty()); 86 ASSERT_FALSE(event.IsEmpty());
82 87
83 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); 88 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context));
84 89
85 const char kListenerFunction[] = "(function() {})"; 90 const char kListenerFunction[] = "(function() {})";
86 v8::Local<v8::Function> listener_function = 91 v8::Local<v8::Function> listener_function =
87 FunctionFromString(context, kListenerFunction); 92 FunctionFromString(context, kListenerFunction);
88 ASSERT_FALSE(listener_function.IsEmpty()); 93 ASSERT_FALSE(listener_function.IsEmpty());
89 94
90 const char kAddListenerFunction[] =
91 "(function(event, listener) { event.addListener(listener); })";
92 v8::Local<v8::Function> add_listener_function = 95 v8::Local<v8::Function> add_listener_function =
93 FunctionFromString(context, kAddListenerFunction); 96 FunctionFromString(context, kAddListenerFunction);
94 97
95 { 98 {
96 v8::Local<v8::Value> argv[] = {event, listener_function}; 99 v8::Local<v8::Value> argv[] = {event, listener_function};
97 RunFunction(add_listener_function, context, arraysize(argv), argv); 100 RunFunction(add_listener_function, context, arraysize(argv), argv);
98 } 101 }
99 // There should only be one listener on the event. 102 // There should only be one listener on the event.
100 EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName, context)); 103 EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kEventName, context));
101 104
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
140 { 143 {
141 v8::Local<v8::Value> argv[] = {event}; 144 v8::Local<v8::Value> argv[] = {event};
142 v8::Local<v8::Value> result = 145 v8::Local<v8::Value> result =
143 RunFunction(has_listeners_function, context, arraysize(argv), argv); 146 RunFunction(has_listeners_function, context, arraysize(argv), argv);
144 bool has_listeners = false; 147 bool has_listeners = false;
145 EXPECT_TRUE( 148 EXPECT_TRUE(
146 gin::Converter<bool>::FromV8(isolate(), result, &has_listeners)); 149 gin::Converter<bool>::FromV8(isolate(), result, &has_listeners));
147 EXPECT_TRUE(has_listeners); 150 EXPECT_TRUE(has_listeners);
148 } 151 }
149 152
150 const char kRemoveListenerFunction[] =
151 "(function(event, listener) { event.removeListener(listener); })";
152 v8::Local<v8::Function> remove_listener_function = 153 v8::Local<v8::Function> remove_listener_function =
153 FunctionFromString(context, kRemoveListenerFunction); 154 FunctionFromString(context, kRemoveListenerFunction);
154 { 155 {
155 v8::Local<v8::Value> argv[] = {event, listener_function}; 156 v8::Local<v8::Value> argv[] = {event, listener_function};
156 RunFunction(remove_listener_function, context, arraysize(argv), argv); 157 RunFunction(remove_listener_function, context, arraysize(argv), argv);
157 } 158 }
158 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); 159 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context));
159 160
160 { 161 {
161 v8::Local<v8::Value> argv[] = {event}; 162 v8::Local<v8::Value> argv[] = {event};
162 v8::Local<v8::Value> result = 163 v8::Local<v8::Value> result =
163 RunFunction(has_listeners_function, context, arraysize(argv), argv); 164 RunFunction(has_listeners_function, context, arraysize(argv), argv);
164 bool has_listeners = false; 165 bool has_listeners = false;
165 EXPECT_TRUE( 166 EXPECT_TRUE(
166 gin::Converter<bool>::FromV8(isolate(), result, &has_listeners)); 167 gin::Converter<bool>::FromV8(isolate(), result, &has_listeners));
167 EXPECT_FALSE(has_listeners); 168 EXPECT_FALSE(has_listeners);
168 } 169 }
169 } 170 }
170 171
171 // Tests listening for and firing different events. 172 // Tests listening for and firing different events.
172 TEST_F(APIEventHandlerTest, FiringEvents) { 173 TEST_F(APIEventHandlerTest, FiringEvents) {
173 const char kAlphaName[] = "alpha"; 174 const char kAlphaName[] = "alpha";
174 const char kBetaName[] = "beta"; 175 const char kBetaName[] = "beta";
175 v8::HandleScope handle_scope(isolate()); 176 v8::HandleScope handle_scope(isolate());
176 v8::Local<v8::Context> context = MainContext(); 177 v8::Local<v8::Context> context = MainContext();
177 178
178 v8::Local<v8::Object> alpha_event = handler()->CreateEventInstance( 179 v8::Local<v8::Object> alpha_event = handler()->CreateEventInstance(
179 kAlphaName, false, binding::kNoListenerMax, true, context); 180 kAlphaName, false, true, binding::kNoListenerMax, true, context);
180 v8::Local<v8::Object> beta_event = handler()->CreateEventInstance( 181 v8::Local<v8::Object> beta_event = handler()->CreateEventInstance(
181 kBetaName, false, binding::kNoListenerMax, true, context); 182 kBetaName, false, true, binding::kNoListenerMax, true, context);
182 ASSERT_FALSE(alpha_event.IsEmpty()); 183 ASSERT_FALSE(alpha_event.IsEmpty());
183 ASSERT_FALSE(beta_event.IsEmpty()); 184 ASSERT_FALSE(beta_event.IsEmpty());
184 185
185 const char kAlphaListenerFunction1[] = 186 const char kAlphaListenerFunction1[] =
186 "(function() {\n" 187 "(function() {\n"
187 " if (!this.alphaCount1) this.alphaCount1 = 0;\n" 188 " if (!this.alphaCount1) this.alphaCount1 = 0;\n"
188 " ++this.alphaCount1;\n" 189 " ++this.alphaCount1;\n"
189 "});\n"; 190 "});\n";
190 v8::Local<v8::Function> alpha_listener1 = 191 v8::Local<v8::Function> alpha_listener1 =
191 FunctionFromString(context, kAlphaListenerFunction1); 192 FunctionFromString(context, kAlphaListenerFunction1);
192 const char kAlphaListenerFunction2[] = 193 const char kAlphaListenerFunction2[] =
193 "(function() {\n" 194 "(function() {\n"
194 " if (!this.alphaCount2) this.alphaCount2 = 0;\n" 195 " if (!this.alphaCount2) this.alphaCount2 = 0;\n"
195 " ++this.alphaCount2;\n" 196 " ++this.alphaCount2;\n"
196 "});\n"; 197 "});\n";
197 v8::Local<v8::Function> alpha_listener2 = 198 v8::Local<v8::Function> alpha_listener2 =
198 FunctionFromString(context, kAlphaListenerFunction2); 199 FunctionFromString(context, kAlphaListenerFunction2);
199 const char kBetaListenerFunction[] = 200 const char kBetaListenerFunction[] =
200 "(function() {\n" 201 "(function() {\n"
201 " if (!this.betaCount) this.betaCount = 0;\n" 202 " if (!this.betaCount) this.betaCount = 0;\n"
202 " ++this.betaCount;\n" 203 " ++this.betaCount;\n"
203 "});\n"; 204 "});\n";
204 v8::Local<v8::Function> beta_listener = 205 v8::Local<v8::Function> beta_listener =
205 FunctionFromString(context, kBetaListenerFunction); 206 FunctionFromString(context, kBetaListenerFunction);
206 ASSERT_FALSE(alpha_listener1.IsEmpty()); 207 ASSERT_FALSE(alpha_listener1.IsEmpty());
207 ASSERT_FALSE(alpha_listener2.IsEmpty()); 208 ASSERT_FALSE(alpha_listener2.IsEmpty());
208 ASSERT_FALSE(beta_listener.IsEmpty()); 209 ASSERT_FALSE(beta_listener.IsEmpty());
209 210
210 { 211 {
211 const char kAddListenerFunction[] =
212 "(function(event, listener) { event.addListener(listener); })";
213 v8::Local<v8::Function> add_listener_function = 212 v8::Local<v8::Function> add_listener_function =
214 FunctionFromString(context, kAddListenerFunction); 213 FunctionFromString(context, kAddListenerFunction);
215 { 214 {
216 v8::Local<v8::Value> argv[] = {alpha_event, alpha_listener1}; 215 v8::Local<v8::Value> argv[] = {alpha_event, alpha_listener1};
217 RunFunction(add_listener_function, context, arraysize(argv), argv); 216 RunFunction(add_listener_function, context, arraysize(argv), argv);
218 } 217 }
219 { 218 {
220 v8::Local<v8::Value> argv[] = {alpha_event, alpha_listener2}; 219 v8::Local<v8::Value> argv[] = {alpha_event, alpha_listener2};
221 RunFunction(add_listener_function, context, arraysize(argv), argv); 220 RunFunction(add_listener_function, context, arraysize(argv), argv);
222 } 221 }
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 EXPECT_EQ(1, get_fired_count("betaCount")); 265 EXPECT_EQ(1, get_fired_count("betaCount"));
267 } 266 }
268 267
269 // Tests firing events with arguments. 268 // Tests firing events with arguments.
270 TEST_F(APIEventHandlerTest, EventArguments) { 269 TEST_F(APIEventHandlerTest, EventArguments) {
271 v8::HandleScope handle_scope(isolate()); 270 v8::HandleScope handle_scope(isolate());
272 v8::Local<v8::Context> context = MainContext(); 271 v8::Local<v8::Context> context = MainContext();
273 272
274 const char kEventName[] = "alpha"; 273 const char kEventName[] = "alpha";
275 v8::Local<v8::Object> event = handler()->CreateEventInstance( 274 v8::Local<v8::Object> event = handler()->CreateEventInstance(
276 kEventName, false, binding::kNoListenerMax, true, context); 275 kEventName, false, true, binding::kNoListenerMax, true, context);
277 ASSERT_FALSE(event.IsEmpty()); 276 ASSERT_FALSE(event.IsEmpty());
278 277
279 const char kListenerFunction[] = 278 const char kListenerFunction[] =
280 "(function() { this.eventArgs = Array.from(arguments); })"; 279 "(function() { this.eventArgs = Array.from(arguments); })";
281 v8::Local<v8::Function> listener_function = 280 v8::Local<v8::Function> listener_function =
282 FunctionFromString(context, kListenerFunction); 281 FunctionFromString(context, kListenerFunction);
283 ASSERT_FALSE(listener_function.IsEmpty()); 282 ASSERT_FALSE(listener_function.IsEmpty());
284 283
285 { 284 {
286 const char kAddListenerFunction[] =
287 "(function(event, listener) { event.addListener(listener); })";
288 v8::Local<v8::Function> add_listener_function = 285 v8::Local<v8::Function> add_listener_function =
289 FunctionFromString(context, kAddListenerFunction); 286 FunctionFromString(context, kAddListenerFunction);
290 v8::Local<v8::Value> argv[] = {event, listener_function}; 287 v8::Local<v8::Value> argv[] = {event, listener_function};
291 RunFunction(add_listener_function, context, arraysize(argv), argv); 288 RunFunction(add_listener_function, context, arraysize(argv), argv);
292 } 289 }
293 290
294 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; 291 const char kArguments[] = "['foo',1,{'prop1':'bar'}]";
295 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); 292 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments);
296 ASSERT_TRUE(event_args); 293 ASSERT_TRUE(event_args);
297 handler()->FireEventInContext(kEventName, context, *event_args, nullptr); 294 handler()->FireEventInContext(kEventName, context, *event_args, nullptr);
(...skipping 15 matching lines...) Expand all
313 310
314 v8::Local<v8::Function> listener_a = FunctionFromString( 311 v8::Local<v8::Function> listener_a = FunctionFromString(
315 context_a, "(function(arg) { this.eventArgs = arg + 'alpha'; })"); 312 context_a, "(function(arg) { this.eventArgs = arg + 'alpha'; })");
316 ASSERT_FALSE(listener_a.IsEmpty()); 313 ASSERT_FALSE(listener_a.IsEmpty());
317 v8::Local<v8::Function> listener_b = FunctionFromString( 314 v8::Local<v8::Function> listener_b = FunctionFromString(
318 context_b, "(function(arg) { this.eventArgs = arg + 'beta'; })"); 315 context_b, "(function(arg) { this.eventArgs = arg + 'beta'; })");
319 ASSERT_FALSE(listener_b.IsEmpty()); 316 ASSERT_FALSE(listener_b.IsEmpty());
320 317
321 // Create two instances of the same event in different contexts. 318 // Create two instances of the same event in different contexts.
322 v8::Local<v8::Object> event_a = handler()->CreateEventInstance( 319 v8::Local<v8::Object> event_a = handler()->CreateEventInstance(
323 kEventName, false, binding::kNoListenerMax, true, context_a); 320 kEventName, false, true, binding::kNoListenerMax, true, context_a);
324 ASSERT_FALSE(event_a.IsEmpty()); 321 ASSERT_FALSE(event_a.IsEmpty());
325 v8::Local<v8::Object> event_b = handler()->CreateEventInstance( 322 v8::Local<v8::Object> event_b = handler()->CreateEventInstance(
326 kEventName, false, binding::kNoListenerMax, true, context_b); 323 kEventName, false, true, binding::kNoListenerMax, true, context_b);
327 ASSERT_FALSE(event_b.IsEmpty()); 324 ASSERT_FALSE(event_b.IsEmpty());
328 325
329 // Add two separate listeners to the event, one in each context. 326 // Add two separate listeners to the event, one in each context.
330 const char kAddListenerFunction[] =
331 "(function(event, listener) { event.addListener(listener); })";
332 { 327 {
333 v8::Local<v8::Function> add_listener_a = 328 v8::Local<v8::Function> add_listener_a =
334 FunctionFromString(context_a, kAddListenerFunction); 329 FunctionFromString(context_a, kAddListenerFunction);
335 v8::Local<v8::Value> argv[] = {event_a, listener_a}; 330 v8::Local<v8::Value> argv[] = {event_a, listener_a};
336 RunFunction(add_listener_a, context_a, arraysize(argv), argv); 331 RunFunction(add_listener_a, context_a, arraysize(argv), argv);
337 } 332 }
338 EXPECT_EQ(1u, 333 EXPECT_EQ(1u,
339 handler()->GetNumEventListenersForTesting(kEventName, context_a)); 334 handler()->GetNumEventListenersForTesting(kEventName, context_a));
340 EXPECT_EQ(0u, 335 EXPECT_EQ(0u,
341 handler()->GetNumEventListenersForTesting(kEventName, context_b)); 336 handler()->GetNumEventListenersForTesting(kEventName, context_b));
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 "eventArgs")); 380 "eventArgs"));
386 } 381 }
387 } 382 }
388 383
389 TEST_F(APIEventHandlerTest, DifferentCallingMethods) { 384 TEST_F(APIEventHandlerTest, DifferentCallingMethods) {
390 v8::HandleScope handle_scope(isolate()); 385 v8::HandleScope handle_scope(isolate());
391 v8::Local<v8::Context> context = MainContext(); 386 v8::Local<v8::Context> context = MainContext();
392 387
393 const char kEventName[] = "alpha"; 388 const char kEventName[] = "alpha";
394 v8::Local<v8::Object> event = handler()->CreateEventInstance( 389 v8::Local<v8::Object> event = handler()->CreateEventInstance(
395 kEventName, false, binding::kNoListenerMax, true, context); 390 kEventName, false, true, binding::kNoListenerMax, true, context);
396 ASSERT_FALSE(event.IsEmpty()); 391 ASSERT_FALSE(event.IsEmpty());
397 392
398 const char kAddListenerOnNull[] = 393 const char kAddListenerOnNull[] =
399 "(function(event) {\n" 394 "(function(event) {\n"
400 " event.addListener.call(null, function() {});\n" 395 " event.addListener.call(null, function() {});\n"
401 "})"; 396 "})";
402 { 397 {
403 v8::Local<v8::Value> args[] = {event}; 398 v8::Local<v8::Value> args[] = {event};
404 // TODO(devlin): This is the generic type error that gin throws. It's not 399 // TODO(devlin): This is the generic type error that gin throws. It's not
405 // very descriptive, nor does it match the web (which would just say e.g. 400 // very descriptive, nor does it match the web (which would just say e.g.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 context, 1, args); 432 context, 1, args);
438 } 433 }
439 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); 434 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context));
440 } 435 }
441 436
442 TEST_F(APIEventHandlerTest, TestDispatchFromJs) { 437 TEST_F(APIEventHandlerTest, TestDispatchFromJs) {
443 v8::HandleScope handle_scope(isolate()); 438 v8::HandleScope handle_scope(isolate());
444 v8::Local<v8::Context> context = MainContext(); 439 v8::Local<v8::Context> context = MainContext();
445 440
446 v8::Local<v8::Object> event = handler()->CreateEventInstance( 441 v8::Local<v8::Object> event = handler()->CreateEventInstance(
447 "alpha", false, binding::kNoListenerMax, true, context); 442 "alpha", false, true, binding::kNoListenerMax, true, context);
448 ASSERT_FALSE(event.IsEmpty()); 443 ASSERT_FALSE(event.IsEmpty());
449 444
450 const char kListenerFunction[] = 445 const char kListenerFunction[] =
451 "(function() {\n" 446 "(function() {\n"
452 " this.eventArgs = Array.from(arguments);\n" 447 " this.eventArgs = Array.from(arguments);\n"
453 "});"; 448 "});";
454 v8::Local<v8::Function> listener = 449 v8::Local<v8::Function> listener =
455 FunctionFromString(context, kListenerFunction); 450 FunctionFromString(context, kListenerFunction);
456 451
457 const char kAddListenerFunction[] =
458 "(function(event, listener) { event.addListener(listener); })";
459 v8::Local<v8::Function> add_listener_function = 452 v8::Local<v8::Function> add_listener_function =
460 FunctionFromString(context, kAddListenerFunction); 453 FunctionFromString(context, kAddListenerFunction);
461 454
462 { 455 {
463 v8::Local<v8::Value> argv[] = {event, listener}; 456 v8::Local<v8::Value> argv[] = {event, listener};
464 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); 457 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv);
465 } 458 }
466 459
467 v8::Local<v8::Function> fire_event_function = 460 v8::Local<v8::Function> fire_event_function =
468 FunctionFromString( 461 FunctionFromString(
469 context, 462 context,
470 "(function(event) { event.dispatch(42, 'foo', {bar: 'baz'}); })"); 463 "(function(event) { event.dispatch(42, 'foo', {bar: 'baz'}); })");
471 { 464 {
472 v8::Local<v8::Value> argv[] = {event}; 465 v8::Local<v8::Value> argv[] = {event};
473 RunFunctionOnGlobal(fire_event_function, context, arraysize(argv), argv); 466 RunFunctionOnGlobal(fire_event_function, context, arraysize(argv), argv);
474 } 467 }
475 468
476 EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]", 469 EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]",
477 GetStringPropertyFromObject( 470 GetStringPropertyFromObject(
478 context->Global(), context, "eventArgs")); 471 context->Global(), context, "eventArgs"));
479 } 472 }
480 473
481 // Test listeners that remove themselves in their handling of the event. 474 // Test listeners that remove themselves in their handling of the event.
482 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) { 475 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) {
483 v8::HandleScope handle_scope(isolate()); 476 v8::HandleScope handle_scope(isolate());
484 v8::Local<v8::Context> context = MainContext(); 477 v8::Local<v8::Context> context = MainContext();
485 478
486 const char kEventName[] = "alpha"; 479 const char kEventName[] = "alpha";
487 v8::Local<v8::Object> event = handler()->CreateEventInstance( 480 v8::Local<v8::Object> event = handler()->CreateEventInstance(
488 kEventName, false, binding::kNoListenerMax, true, context); 481 kEventName, false, true, binding::kNoListenerMax, true, context);
489 ASSERT_FALSE(event.IsEmpty()); 482 ASSERT_FALSE(event.IsEmpty());
490 { 483 {
491 // Cache the event object on the global in order to allow for easy removal. 484 // Cache the event object on the global in order to allow for easy removal.
492 v8::Local<v8::Function> set_event_on_global = 485 v8::Local<v8::Function> set_event_on_global =
493 FunctionFromString( 486 FunctionFromString(
494 context, 487 context,
495 "(function(event) { this.testEvent = event; })"); 488 "(function(event) { this.testEvent = event; })");
496 v8::Local<v8::Value> args[] = {event}; 489 v8::Local<v8::Value> args[] = {event};
497 RunFunctionOnGlobal(set_event_on_global, context, arraysize(args), args); 490 RunFunctionOnGlobal(set_event_on_global, context, arraysize(args), args);
498 EXPECT_EQ(event, 491 EXPECT_EQ(event,
499 GetPropertyFromObject(context->Global(), context, "testEvent")); 492 GetPropertyFromObject(context->Global(), context, "testEvent"));
500 } 493 }
501 494
502 // A listener function that removes itself as a listener. 495 // A listener function that removes itself as a listener.
503 const char kListenerFunction[] = 496 const char kListenerFunction[] =
504 "(function() {\n" 497 "(function() {\n"
505 " return function listener() {\n" 498 " return function listener() {\n"
506 " this.testEvent.removeListener(listener);\n" 499 " this.testEvent.removeListener(listener);\n"
507 " };\n" 500 " };\n"
508 "})();"; 501 "})();";
509 502
510 // Create and add a bunch of listeners. 503 // Create and add a bunch of listeners.
511 std::vector<v8::Local<v8::Function>> listeners; 504 std::vector<v8::Local<v8::Function>> listeners;
512 const size_t kNumListeners = 20u; 505 const size_t kNumListeners = 20u;
513 listeners.reserve(kNumListeners); 506 listeners.reserve(kNumListeners);
514 for (size_t i = 0; i < kNumListeners; ++i) 507 for (size_t i = 0; i < kNumListeners; ++i)
515 listeners.push_back(FunctionFromString(context, kListenerFunction)); 508 listeners.push_back(FunctionFromString(context, kListenerFunction));
516 509
517 const char kAddListenerFunction[] =
518 "(function(event, listener) { event.addListener(listener); })";
519 v8::Local<v8::Function> add_listener_function = 510 v8::Local<v8::Function> add_listener_function =
520 FunctionFromString(context, kAddListenerFunction); 511 FunctionFromString(context, kAddListenerFunction);
521 512
522 for (const auto& listener : listeners) { 513 for (const auto& listener : listeners) {
523 v8::Local<v8::Value> argv[] = {event, listener}; 514 v8::Local<v8::Value> argv[] = {event, listener};
524 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); 515 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv);
525 } 516 }
526 517
527 // Fire the event. All listeners should be removed (and we shouldn't crash). 518 // Fire the event. All listeners should be removed (and we shouldn't crash).
528 EXPECT_EQ(kNumListeners, 519 EXPECT_EQ(kNumListeners,
(...skipping 25 matching lines...) Expand all
554 SetHandler(base::MakeUnique<APIEventHandler>( 545 SetHandler(base::MakeUnique<APIEventHandler>(
555 base::Bind(run_js_and_expect_error), 546 base::Bind(run_js_and_expect_error),
556 base::Bind(&RunFunctionOnGlobalAndReturnHandle), 547 base::Bind(&RunFunctionOnGlobalAndReturnHandle),
557 base::Bind(&DoNothingOnEventListenersChanged))); 548 base::Bind(&DoNothingOnEventListenersChanged)));
558 549
559 v8::HandleScope handle_scope(isolate()); 550 v8::HandleScope handle_scope(isolate());
560 v8::Local<v8::Context> context = MainContext(); 551 v8::Local<v8::Context> context = MainContext();
561 552
562 const char kEventName[] = "alpha"; 553 const char kEventName[] = "alpha";
563 v8::Local<v8::Object> event = handler()->CreateEventInstance( 554 v8::Local<v8::Object> event = handler()->CreateEventInstance(
564 kEventName, false, binding::kNoListenerMax, true, context); 555 kEventName, false, true, binding::kNoListenerMax, true, context);
565 ASSERT_FALSE(event.IsEmpty()); 556 ASSERT_FALSE(event.IsEmpty());
566 557
567 bool did_throw = false; 558 bool did_throw = false;
568 auto message_listener = [](v8::Local<v8::Message> message, 559 auto message_listener = [](v8::Local<v8::Message> message,
569 v8::Local<v8::Value> data) { 560 v8::Local<v8::Value> data) {
570 ASSERT_FALSE(data.IsEmpty()); 561 ASSERT_FALSE(data.IsEmpty());
571 ASSERT_TRUE(data->IsExternal()); 562 ASSERT_TRUE(data->IsExternal());
572 bool* did_throw = static_cast<bool*>(data.As<v8::External>()->Value()); 563 bool* did_throw = static_cast<bool*>(data.As<v8::External>()->Value());
573 *did_throw = true; 564 *did_throw = true;
574 EXPECT_EQ("Uncaught Error: Event handler error", 565 EXPECT_EQ("Uncaught Error: Event handler error",
(...skipping 12 matching lines...) Expand all
587 // exception first so that we don't rely on event listener ordering. 578 // exception first so that we don't rely on event listener ordering.
588 const char kListenerFunction[] = 579 const char kListenerFunction[] =
589 "(function() {\n" 580 "(function() {\n"
590 " if (!this.didThrow) {\n" 581 " if (!this.didThrow) {\n"
591 " this.didThrow = true;\n" 582 " this.didThrow = true;\n"
592 " throw new Error('Event handler error');\n" 583 " throw new Error('Event handler error');\n"
593 " }\n" 584 " }\n"
594 " this.eventArgs = Array.from(arguments);\n" 585 " this.eventArgs = Array.from(arguments);\n"
595 "});"; 586 "});";
596 587
597 const char kAddListenerFunction[] =
598 "(function(event, listener) { event.addListener(listener); })";
599 v8::Local<v8::Function> add_listener_function = 588 v8::Local<v8::Function> add_listener_function =
600 FunctionFromString(context, kAddListenerFunction); 589 FunctionFromString(context, kAddListenerFunction);
601 590
602 for (int i = 0; i < 2; ++i) { 591 for (int i = 0; i < 2; ++i) {
603 v8::Local<v8::Function> listener = 592 v8::Local<v8::Function> listener =
604 FunctionFromString(context, kListenerFunction); 593 FunctionFromString(context, kListenerFunction);
605 v8::Local<v8::Value> argv[] = {event, listener}; 594 v8::Local<v8::Value> argv[] = {event, listener};
606 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); 595 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv);
607 } 596 }
608 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); 597 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context));
(...skipping 19 matching lines...) Expand all
628 base::Bind(&RunFunctionOnGlobalAndReturnHandle), change_handler.Get())); 617 base::Bind(&RunFunctionOnGlobalAndReturnHandle), change_handler.Get()));
629 618
630 v8::HandleScope handle_scope(isolate()); 619 v8::HandleScope handle_scope(isolate());
631 620
632 v8::Local<v8::Context> context_a = MainContext(); 621 v8::Local<v8::Context> context_a = MainContext();
633 v8::Local<v8::Context> context_b = AddContext(); 622 v8::Local<v8::Context> context_b = AddContext();
634 623
635 const char kEventName1[] = "onFoo"; 624 const char kEventName1[] = "onFoo";
636 const char kEventName2[] = "onBar"; 625 const char kEventName2[] = "onBar";
637 v8::Local<v8::Object> event1_a = handler()->CreateEventInstance( 626 v8::Local<v8::Object> event1_a = handler()->CreateEventInstance(
638 kEventName1, false, binding::kNoListenerMax, true, context_a); 627 kEventName1, false, true, binding::kNoListenerMax, true, context_a);
639 ASSERT_FALSE(event1_a.IsEmpty()); 628 ASSERT_FALSE(event1_a.IsEmpty());
640 v8::Local<v8::Object> event2_a = handler()->CreateEventInstance( 629 v8::Local<v8::Object> event2_a = handler()->CreateEventInstance(
641 kEventName2, false, binding::kNoListenerMax, true, context_a); 630 kEventName2, false, true, binding::kNoListenerMax, true, context_a);
642 ASSERT_FALSE(event2_a.IsEmpty()); 631 ASSERT_FALSE(event2_a.IsEmpty());
643 v8::Local<v8::Object> event1_b = handler()->CreateEventInstance( 632 v8::Local<v8::Object> event1_b = handler()->CreateEventInstance(
644 kEventName1, false, binding::kNoListenerMax, true, context_b); 633 kEventName1, false, true, binding::kNoListenerMax, true, context_b);
645 ASSERT_FALSE(event1_b.IsEmpty()); 634 ASSERT_FALSE(event1_b.IsEmpty());
646 635
647 const char kAddListenerFunction[] =
648 "(function(event, listener) { event.addListener(listener); })";
649 const char kRemoveListenerFunction[] =
650 "(function(event, listener) { event.removeListener(listener); })";
651
652 // Add a listener to the first event. The APIEventHandler should notify 636 // Add a listener to the first event. The APIEventHandler should notify
653 // since it's a change in state (no listeners -> listeners). 637 // since it's a change in state (no listeners -> listeners).
654 v8::Local<v8::Function> add_listener = 638 v8::Local<v8::Function> add_listener =
655 FunctionFromString(context_a, kAddListenerFunction); 639 FunctionFromString(context_a, kAddListenerFunction);
656 v8::Local<v8::Function> listener1 = 640 v8::Local<v8::Function> listener1 =
657 FunctionFromString(context_a, "(function() {})"); 641 FunctionFromString(context_a, "(function() {})");
658 { 642 {
659 EXPECT_CALL(change_handler, 643 EXPECT_CALL(change_handler,
660 Run(kEventName1, binding::EventListenersChanged::HAS_LISTENERS, 644 Run(kEventName1, binding::EventListenersChanged::HAS_LISTENERS,
661 nullptr, true, context_a)) 645 nullptr, true, context_a))
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 ::testing::Mock::VerifyAndClearExpectations(&change_handler); 740 ::testing::Mock::VerifyAndClearExpectations(&change_handler);
757 } 741 }
758 742
759 // Test registering an argument massager for a given event. 743 // Test registering an argument massager for a given event.
760 TEST_F(APIEventHandlerTest, TestArgumentMassagers) { 744 TEST_F(APIEventHandlerTest, TestArgumentMassagers) {
761 v8::HandleScope handle_scope(isolate()); 745 v8::HandleScope handle_scope(isolate());
762 v8::Local<v8::Context> context = MainContext(); 746 v8::Local<v8::Context> context = MainContext();
763 747
764 const char kEventName[] = "alpha"; 748 const char kEventName[] = "alpha";
765 v8::Local<v8::Object> event = handler()->CreateEventInstance( 749 v8::Local<v8::Object> event = handler()->CreateEventInstance(
766 kEventName, false, binding::kNoListenerMax, true, context); 750 kEventName, false, true, binding::kNoListenerMax, true, context);
767 ASSERT_FALSE(event.IsEmpty()); 751 ASSERT_FALSE(event.IsEmpty());
768 752
769 const char kArgumentMassager[] = 753 const char kArgumentMassager[] =
770 "(function(originalArgs, dispatch) {\n" 754 "(function(originalArgs, dispatch) {\n"
771 " this.originalArgs = originalArgs;\n" 755 " this.originalArgs = originalArgs;\n"
772 " dispatch(['primary', 'secondary']);\n" 756 " dispatch(['primary', 'secondary']);\n"
773 "});"; 757 "});";
774 v8::Local<v8::Function> massager = 758 v8::Local<v8::Function> massager =
775 FunctionFromString(context, kArgumentMassager); 759 FunctionFromString(context, kArgumentMassager);
776 handler()->RegisterArgumentMassager(context, "alpha", massager); 760 handler()->RegisterArgumentMassager(context, "alpha", massager);
777 761
778 const char kListenerFunction[] = 762 const char kListenerFunction[] =
779 "(function() { this.eventArgs = Array.from(arguments); })"; 763 "(function() { this.eventArgs = Array.from(arguments); })";
780 v8::Local<v8::Function> listener_function = 764 v8::Local<v8::Function> listener_function =
781 FunctionFromString(context, kListenerFunction); 765 FunctionFromString(context, kListenerFunction);
782 ASSERT_FALSE(listener_function.IsEmpty()); 766 ASSERT_FALSE(listener_function.IsEmpty());
783 767
784 { 768 {
785 const char kAddListenerFunction[] =
786 "(function(event, listener) { event.addListener(listener); })";
787 v8::Local<v8::Function> add_listener_function = 769 v8::Local<v8::Function> add_listener_function =
788 FunctionFromString(context, kAddListenerFunction); 770 FunctionFromString(context, kAddListenerFunction);
789 v8::Local<v8::Value> argv[] = {event, listener_function}; 771 v8::Local<v8::Value> argv[] = {event, listener_function};
790 RunFunction(add_listener_function, context, arraysize(argv), argv); 772 RunFunction(add_listener_function, context, arraysize(argv), argv);
791 } 773 }
792 774
793 const char kArguments[] = "['first','second']"; 775 const char kArguments[] = "['first','second']";
794 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); 776 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments);
795 ASSERT_TRUE(event_args); 777 ASSERT_TRUE(event_args);
796 handler()->FireEventInContext(kEventName, context, *event_args, nullptr); 778 handler()->FireEventInContext(kEventName, context, *event_args, nullptr);
797 779
798 EXPECT_EQ( 780 EXPECT_EQ(
799 "[\"first\",\"second\"]", 781 "[\"first\",\"second\"]",
800 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); 782 GetStringPropertyFromObject(context->Global(), context, "originalArgs"));
801 EXPECT_EQ( 783 EXPECT_EQ(
802 "[\"primary\",\"secondary\"]", 784 "[\"primary\",\"secondary\"]",
803 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); 785 GetStringPropertyFromObject(context->Global(), context, "eventArgs"));
804 } 786 }
805 787
806 // Test registering an argument massager for a given event and dispatching 788 // Test registering an argument massager for a given event and dispatching
807 // asynchronously. 789 // asynchronously.
808 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) { 790 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) {
809 v8::HandleScope handle_scope(isolate()); 791 v8::HandleScope handle_scope(isolate());
810 v8::Local<v8::Context> context = MainContext(); 792 v8::Local<v8::Context> context = MainContext();
811 793
812 const char kEventName[] = "alpha"; 794 const char kEventName[] = "alpha";
813 v8::Local<v8::Object> event = handler()->CreateEventInstance( 795 v8::Local<v8::Object> event = handler()->CreateEventInstance(
814 kEventName, false, binding::kNoListenerMax, true, context); 796 kEventName, false, true, binding::kNoListenerMax, true, context);
815 ASSERT_FALSE(event.IsEmpty()); 797 ASSERT_FALSE(event.IsEmpty());
816 798
817 const char kArgumentMassager[] = 799 const char kArgumentMassager[] =
818 "(function(originalArgs, dispatch) {\n" 800 "(function(originalArgs, dispatch) {\n"
819 " this.originalArgs = originalArgs;\n" 801 " this.originalArgs = originalArgs;\n"
820 " this.dispatch = dispatch;\n" 802 " this.dispatch = dispatch;\n"
821 "});"; 803 "});";
822 v8::Local<v8::Function> massager = 804 v8::Local<v8::Function> massager =
823 FunctionFromString(context, kArgumentMassager); 805 FunctionFromString(context, kArgumentMassager);
824 handler()->RegisterArgumentMassager(context, "alpha", massager); 806 handler()->RegisterArgumentMassager(context, "alpha", massager);
825 807
826 const char kListenerFunction[] = 808 const char kListenerFunction[] =
827 "(function() { this.eventArgs = Array.from(arguments); })"; 809 "(function() { this.eventArgs = Array.from(arguments); })";
828 v8::Local<v8::Function> listener_function = 810 v8::Local<v8::Function> listener_function =
829 FunctionFromString(context, kListenerFunction); 811 FunctionFromString(context, kListenerFunction);
830 ASSERT_FALSE(listener_function.IsEmpty()); 812 ASSERT_FALSE(listener_function.IsEmpty());
831 813
832 { 814 {
833 const char kAddListenerFunction[] =
834 "(function(event, listener) { event.addListener(listener); })";
835 v8::Local<v8::Function> add_listener_function = 815 v8::Local<v8::Function> add_listener_function =
836 FunctionFromString(context, kAddListenerFunction); 816 FunctionFromString(context, kAddListenerFunction);
837 v8::Local<v8::Value> argv[] = {event, listener_function}; 817 v8::Local<v8::Value> argv[] = {event, listener_function};
838 RunFunction(add_listener_function, context, arraysize(argv), argv); 818 RunFunction(add_listener_function, context, arraysize(argv), argv);
839 } 819 }
840 820
841 const char kArguments[] = "['first','second']"; 821 const char kArguments[] = "['first','second']";
842 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); 822 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments);
843 ASSERT_TRUE(event_args); 823 ASSERT_TRUE(event_args);
844 handler()->FireEventInContext(kEventName, context, *event_args, nullptr); 824 handler()->FireEventInContext(kEventName, context, *event_args, nullptr);
(...skipping 22 matching lines...) Expand all
867 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); 847 GetStringPropertyFromObject(context->Global(), context, "eventArgs"));
868 } 848 }
869 849
870 // Test registering an argument massager and never dispatching. 850 // Test registering an argument massager and never dispatching.
871 TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) { 851 TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) {
872 v8::HandleScope handle_scope(isolate()); 852 v8::HandleScope handle_scope(isolate());
873 v8::Local<v8::Context> context = MainContext(); 853 v8::Local<v8::Context> context = MainContext();
874 854
875 const char kEventName[] = "alpha"; 855 const char kEventName[] = "alpha";
876 v8::Local<v8::Object> event = handler()->CreateEventInstance( 856 v8::Local<v8::Object> event = handler()->CreateEventInstance(
877 kEventName, false, binding::kNoListenerMax, true, context); 857 kEventName, false, true, binding::kNoListenerMax, true, context);
878 ASSERT_FALSE(event.IsEmpty()); 858 ASSERT_FALSE(event.IsEmpty());
879 859
880 // A massager that never dispatches. 860 // A massager that never dispatches.
881 const char kArgumentMassager[] = "(function(originalArgs, dispatch) {})"; 861 const char kArgumentMassager[] = "(function(originalArgs, dispatch) {})";
882 v8::Local<v8::Function> massager = 862 v8::Local<v8::Function> massager =
883 FunctionFromString(context, kArgumentMassager); 863 FunctionFromString(context, kArgumentMassager);
884 handler()->RegisterArgumentMassager(context, "alpha", massager); 864 handler()->RegisterArgumentMassager(context, "alpha", massager);
885 865
886 const char kListenerFunction[] = "(function() {})"; 866 const char kListenerFunction[] = "(function() {})";
887 v8::Local<v8::Function> listener_function = 867 v8::Local<v8::Function> listener_function =
888 FunctionFromString(context, kListenerFunction); 868 FunctionFromString(context, kListenerFunction);
889 ASSERT_FALSE(listener_function.IsEmpty()); 869 ASSERT_FALSE(listener_function.IsEmpty());
890 870
891 const char kAddListenerFunction[] =
892 "(function(event, listener) { event.addListener(listener); })";
893 v8::Local<v8::Function> add_listener_function = 871 v8::Local<v8::Function> add_listener_function =
894 FunctionFromString(context, kAddListenerFunction); 872 FunctionFromString(context, kAddListenerFunction);
895 v8::Local<v8::Value> argv[] = {event, listener_function}; 873 v8::Local<v8::Value> argv[] = {event, listener_function};
896 RunFunction(add_listener_function, context, arraysize(argv), argv); 874 RunFunction(add_listener_function, context, arraysize(argv), argv);
897 875
898 handler()->FireEventInContext(kEventName, context, base::ListValue(), 876 handler()->FireEventInContext(kEventName, context, base::ListValue(),
899 nullptr); 877 nullptr);
900 878
901 // Nothing should blow up. (We tested in the previous test that the event 879 // Nothing should blow up. (We tested in the previous test that the event
902 // isn't notified without calling dispatch, so all there is to test here is 880 // isn't notified without calling dispatch, so all there is to test here is
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
984 [](const std::string& event_name, binding::EventListenersChanged changed, 962 [](const std::string& event_name, binding::EventListenersChanged changed,
985 const base::DictionaryValue* filter, bool was_manual, 963 const base::DictionaryValue* filter, bool was_manual,
986 v8::Local<v8::Context> context) { ADD_FAILURE(); }; 964 v8::Local<v8::Context> context) { ADD_FAILURE(); };
987 965
988 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), 966 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
989 base::Bind(&RunFunctionOnGlobalAndReturnHandle), 967 base::Bind(&RunFunctionOnGlobalAndReturnHandle),
990 base::Bind(fail_on_notified)); 968 base::Bind(fail_on_notified));
991 969
992 const char kEventName[] = "alpha"; 970 const char kEventName[] = "alpha";
993 v8::Local<v8::Object> event = handler.CreateEventInstance( 971 v8::Local<v8::Object> event = handler.CreateEventInstance(
994 kEventName, false, binding::kNoListenerMax, false, context); 972 kEventName, false, true, binding::kNoListenerMax, false, context);
995 973
996 const char kListener[] = 974 const char kListener[] =
997 "(function() {\n" 975 "(function() {\n"
998 " this.eventArgs = Array.from(arguments);\n" 976 " this.eventArgs = Array.from(arguments);\n"
999 "});"; 977 "});";
1000 v8::Local<v8::Function> listener = FunctionFromString(context, kListener); 978 v8::Local<v8::Function> listener = FunctionFromString(context, kListener);
1001 979
1002 { 980 {
1003 const char kAddListener[] = 981 const char kAddListener[] =
1004 "(function(event, listener) { event.addListener(listener); })"; 982 "(function(event, listener) { event.addListener(listener); })";
(...skipping 14 matching lines...) Expand all
1019 const char kRemoveListener[] = 997 const char kRemoveListener[] =
1020 "(function(event, listener) { event.removeListener(listener); })"; 998 "(function(event, listener) { event.removeListener(listener); })";
1021 v8::Local<v8::Value> args[] = {event, listener}; 999 v8::Local<v8::Value> args[] = {event, listener};
1022 RunFunction(FunctionFromString(context, kRemoveListener), context, 1000 RunFunction(FunctionFromString(context, kRemoveListener), context,
1023 arraysize(args), args); 1001 arraysize(args), args);
1024 } 1002 }
1025 1003
1026 EXPECT_EQ(0u, handler.GetNumEventListenersForTesting(kEventName, context)); 1004 EXPECT_EQ(0u, handler.GetNumEventListenersForTesting(kEventName, context));
1027 } 1005 }
1028 1006
1007 // Test callback notifications for events that don't support lazy listeners.
1008 TEST_F(APIEventHandlerTest, TestEventsWithoutLazyListeners) {
1009 MockEventChangeHandler change_handler;
1010 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult),
1011 base::Bind(&RunFunctionOnGlobalAndReturnHandle),
1012 change_handler.Get());
1013
1014 v8::HandleScope handle_scope(isolate());
1015 v8::Local<v8::Context> context = MainContext();
1016
1017 const char kLazyListenersSupported[] = "supportsLazyListeners";
1018 const char kLazyListenersNotSupported[] = "noLazyListeners";
1019 v8::Local<v8::Object> lazy_listeners_supported =
1020 handler.CreateEventInstance(kLazyListenersSupported, false, true,
1021 binding::kNoListenerMax, true, context);
1022 v8::Local<v8::Object> lazy_listeners_not_supported =
1023 handler.CreateEventInstance(kLazyListenersNotSupported, false, false,
1024 binding::kNoListenerMax, true, context);
1025 ASSERT_FALSE(lazy_listeners_not_supported.IsEmpty());
1026
1027 v8::Local<v8::Function> add_listener =
1028 FunctionFromString(context, kAddListenerFunction);
1029 v8::Local<v8::Function> listener =
1030 FunctionFromString(context, "(function() {})");
1031 {
1032 EXPECT_CALL(change_handler,
1033 Run(kLazyListenersSupported,
1034 binding::EventListenersChanged::HAS_LISTENERS, nullptr,
1035 true, context))
1036 .Times(1);
1037 v8::Local<v8::Value> argv[] = {lazy_listeners_supported, listener};
1038 RunFunction(add_listener, context, arraysize(argv), argv);
1039 ::testing::Mock::VerifyAndClearExpectations(&change_handler);
1040 }
1041
1042 {
1043 EXPECT_CALL(change_handler,
1044 Run(kLazyListenersNotSupported,
1045 binding::EventListenersChanged::HAS_LISTENERS, nullptr,
1046 false, context))
1047 .Times(1);
1048 v8::Local<v8::Value> argv[] = {lazy_listeners_not_supported, listener};
1049 RunFunction(add_listener, context, arraysize(argv), argv);
1050 ::testing::Mock::VerifyAndClearExpectations(&change_handler);
1051 }
1052
1053 v8::Local<v8::Function> remove_listener =
1054 FunctionFromString(context, kRemoveListenerFunction);
1055 {
1056 EXPECT_CALL(change_handler,
1057 Run(kLazyListenersSupported,
1058 binding::EventListenersChanged::NO_LISTENERS, nullptr, true,
1059 context))
1060 .Times(1);
1061 v8::Local<v8::Value> argv[] = {lazy_listeners_supported, listener};
1062 RunFunction(remove_listener, context, arraysize(argv), argv);
1063 ::testing::Mock::VerifyAndClearExpectations(&change_handler);
1064 }
1065
1066 {
1067 EXPECT_CALL(change_handler,
1068 Run(kLazyListenersNotSupported,
1069 binding::EventListenersChanged::NO_LISTENERS, nullptr,
1070 false, context))
1071 .Times(1);
1072 v8::Local<v8::Value> argv[] = {lazy_listeners_not_supported, listener};
1073 RunFunction(remove_listener, context, arraysize(argv), argv);
1074 ::testing::Mock::VerifyAndClearExpectations(&change_handler);
1075 }
1076
1077 DisposeContext(context);
1078 }
1079
1029 } // namespace extensions 1080 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698