OLD | NEW |
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/api_event_handler.h" | 5 #include "extensions/renderer/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/test/mock_callback.h" | 10 #include "base/test/mock_callback.h" |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
122 | 122 |
123 { | 123 { |
124 v8::Local<v8::Value> argv[] = {event}; | 124 v8::Local<v8::Value> argv[] = {event}; |
125 v8::Local<v8::Value> result = | 125 v8::Local<v8::Value> result = |
126 RunFunction(has_listeners_function, context, arraysize(argv), argv); | 126 RunFunction(has_listeners_function, context, arraysize(argv), argv); |
127 bool has_listeners = false; | 127 bool has_listeners = false; |
128 EXPECT_TRUE( | 128 EXPECT_TRUE( |
129 gin::Converter<bool>::FromV8(isolate(), result, &has_listeners)); | 129 gin::Converter<bool>::FromV8(isolate(), result, &has_listeners)); |
130 EXPECT_FALSE(has_listeners); | 130 EXPECT_FALSE(has_listeners); |
131 } | 131 } |
| 132 |
| 133 handler.InvalidateContext(context); |
132 } | 134 } |
133 | 135 |
134 // Tests listening for and firing different events. | 136 // Tests listening for and firing different events. |
135 TEST_F(APIEventHandlerTest, FiringEvents) { | 137 TEST_F(APIEventHandlerTest, FiringEvents) { |
136 const char kAlphaName[] = "alpha"; | 138 const char kAlphaName[] = "alpha"; |
137 const char kBetaName[] = "beta"; | 139 const char kBetaName[] = "beta"; |
138 v8::HandleScope handle_scope(isolate()); | 140 v8::HandleScope handle_scope(isolate()); |
139 v8::Local<v8::Context> context = ContextLocal(); | 141 v8::Local<v8::Context> context = ContextLocal(); |
140 | 142 |
141 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 143 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 | 222 |
221 handler.FireEventInContext(kAlphaName, context, base::ListValue()); | 223 handler.FireEventInContext(kAlphaName, context, base::ListValue()); |
222 EXPECT_EQ(2, get_fired_count("alphaCount1")); | 224 EXPECT_EQ(2, get_fired_count("alphaCount1")); |
223 EXPECT_EQ(2, get_fired_count("alphaCount2")); | 225 EXPECT_EQ(2, get_fired_count("alphaCount2")); |
224 EXPECT_EQ(0, get_fired_count("betaCount")); | 226 EXPECT_EQ(0, get_fired_count("betaCount")); |
225 | 227 |
226 handler.FireEventInContext(kBetaName, context, base::ListValue()); | 228 handler.FireEventInContext(kBetaName, context, base::ListValue()); |
227 EXPECT_EQ(2, get_fired_count("alphaCount1")); | 229 EXPECT_EQ(2, get_fired_count("alphaCount1")); |
228 EXPECT_EQ(2, get_fired_count("alphaCount2")); | 230 EXPECT_EQ(2, get_fired_count("alphaCount2")); |
229 EXPECT_EQ(1, get_fired_count("betaCount")); | 231 EXPECT_EQ(1, get_fired_count("betaCount")); |
| 232 |
| 233 handler.InvalidateContext(context); |
230 } | 234 } |
231 | 235 |
232 // Tests firing events with arguments. | 236 // Tests firing events with arguments. |
233 TEST_F(APIEventHandlerTest, EventArguments) { | 237 TEST_F(APIEventHandlerTest, EventArguments) { |
234 v8::HandleScope handle_scope(isolate()); | 238 v8::HandleScope handle_scope(isolate()); |
235 v8::Local<v8::Context> context = ContextLocal(); | 239 v8::Local<v8::Context> context = ContextLocal(); |
236 | 240 |
237 const char kEventName[] = "alpha"; | 241 const char kEventName[] = "alpha"; |
238 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 242 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
239 base::Bind(&DoNothingOnEventListenersChanged)); | 243 base::Bind(&DoNothingOnEventListenersChanged)); |
(...skipping 17 matching lines...) Expand all Loading... |
257 } | 261 } |
258 | 262 |
259 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; | 263 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; |
260 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | 264 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); |
261 ASSERT_TRUE(event_args); | 265 ASSERT_TRUE(event_args); |
262 handler.FireEventInContext(kEventName, context, *event_args); | 266 handler.FireEventInContext(kEventName, context, *event_args); |
263 | 267 |
264 EXPECT_EQ( | 268 EXPECT_EQ( |
265 ReplaceSingleQuotes(kArguments), | 269 ReplaceSingleQuotes(kArguments), |
266 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | 270 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); |
| 271 |
| 272 handler.InvalidateContext(context); |
267 } | 273 } |
268 | 274 |
269 // Test dispatching events to multiple contexts. | 275 // Test dispatching events to multiple contexts. |
270 TEST_F(APIEventHandlerTest, MultipleContexts) { | 276 TEST_F(APIEventHandlerTest, MultipleContexts) { |
271 v8::HandleScope handle_scope(isolate()); | 277 v8::HandleScope handle_scope(isolate()); |
272 | 278 |
273 v8::Local<v8::Context> context_a = ContextLocal(); | 279 v8::Local<v8::Context> context_a = ContextLocal(); |
274 v8::Local<v8::Context> context_b = v8::Context::New(isolate()); | 280 v8::Local<v8::Context> context_b = v8::Context::New(isolate()); |
275 gin::ContextHolder holder_b(isolate()); | 281 gin::ContextHolder holder_b(isolate()); |
276 holder_b.SetContext(context_b); | 282 holder_b.SetContext(context_b); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 { | 348 { |
343 EXPECT_EQ("\"result_a:alpha\"", | 349 EXPECT_EQ("\"result_a:alpha\"", |
344 GetStringPropertyFromObject(context_a->Global(), context_a, | 350 GetStringPropertyFromObject(context_a->Global(), context_a, |
345 "eventArgs")); | 351 "eventArgs")); |
346 } | 352 } |
347 { | 353 { |
348 EXPECT_EQ("\"result_b:beta\"", | 354 EXPECT_EQ("\"result_b:beta\"", |
349 GetStringPropertyFromObject(context_b->Global(), context_b, | 355 GetStringPropertyFromObject(context_b->Global(), context_b, |
350 "eventArgs")); | 356 "eventArgs")); |
351 } | 357 } |
| 358 |
| 359 handler.InvalidateContext(context_a); |
| 360 handler.InvalidateContext(context_b); |
352 } | 361 } |
353 | 362 |
354 TEST_F(APIEventHandlerTest, DifferentCallingMethods) { | 363 TEST_F(APIEventHandlerTest, DifferentCallingMethods) { |
355 v8::HandleScope handle_scope(isolate()); | 364 v8::HandleScope handle_scope(isolate()); |
356 v8::Local<v8::Context> context = ContextLocal(); | 365 v8::Local<v8::Context> context = ContextLocal(); |
357 | 366 |
358 const char kEventName[] = "alpha"; | 367 const char kEventName[] = "alpha"; |
359 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 368 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
360 base::Bind(&DoNothingOnEventListenersChanged)); | 369 base::Bind(&DoNothingOnEventListenersChanged)); |
361 v8::Local<v8::Object> event = | 370 v8::Local<v8::Object> event = |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
397 " event.addListener(function listener() {\n" | 406 " event.addListener(function listener() {\n" |
398 " event.hasListener(listener);\n" | 407 " event.hasListener(listener);\n" |
399 " });\n" | 408 " });\n" |
400 "})"; | 409 "})"; |
401 { | 410 { |
402 v8::Local<v8::Value> args[] = {event}; | 411 v8::Local<v8::Value> args[] = {event}; |
403 RunFunction(FunctionFromString(context, kAddListenerOnEventWithCapture), | 412 RunFunction(FunctionFromString(context, kAddListenerOnEventWithCapture), |
404 context, 1, args); | 413 context, 1, args); |
405 } | 414 } |
406 EXPECT_EQ(2u, handler.GetNumEventListenersForTesting(kEventName, context)); | 415 EXPECT_EQ(2u, handler.GetNumEventListenersForTesting(kEventName, context)); |
| 416 |
| 417 handler.InvalidateContext(context); |
407 } | 418 } |
408 | 419 |
409 TEST_F(APIEventHandlerTest, TestDispatchFromJs) { | 420 TEST_F(APIEventHandlerTest, TestDispatchFromJs) { |
410 v8::HandleScope handle_scope(isolate()); | 421 v8::HandleScope handle_scope(isolate()); |
411 v8::Local<v8::Context> context = ContextLocal(); | 422 v8::Local<v8::Context> context = ContextLocal(); |
412 | 423 |
413 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 424 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
414 base::Bind(&DoNothingOnEventListenersChanged)); | 425 base::Bind(&DoNothingOnEventListenersChanged)); |
415 v8::Local<v8::Object> event = handler.CreateEventInstance("alpha", context); | 426 v8::Local<v8::Object> event = handler.CreateEventInstance("alpha", context); |
416 ASSERT_FALSE(event.IsEmpty()); | 427 ASSERT_FALSE(event.IsEmpty()); |
(...skipping 20 matching lines...) Expand all Loading... |
437 context, | 448 context, |
438 "(function(event) { event.dispatch(42, 'foo', {bar: 'baz'}); })"); | 449 "(function(event) { event.dispatch(42, 'foo', {bar: 'baz'}); })"); |
439 { | 450 { |
440 v8::Local<v8::Value> argv[] = {event}; | 451 v8::Local<v8::Value> argv[] = {event}; |
441 RunFunctionOnGlobal(fire_event_function, context, arraysize(argv), argv); | 452 RunFunctionOnGlobal(fire_event_function, context, arraysize(argv), argv); |
442 } | 453 } |
443 | 454 |
444 EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]", | 455 EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]", |
445 GetStringPropertyFromObject( | 456 GetStringPropertyFromObject( |
446 context->Global(), context, "eventArgs")); | 457 context->Global(), context, "eventArgs")); |
| 458 |
| 459 handler.InvalidateContext(context); |
447 } | 460 } |
448 | 461 |
449 // Test listeners that remove themselves in their handling of the event. | 462 // Test listeners that remove themselves in their handling of the event. |
450 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) { | 463 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) { |
451 v8::HandleScope handle_scope(isolate()); | 464 v8::HandleScope handle_scope(isolate()); |
452 v8::Local<v8::Context> context = ContextLocal(); | 465 v8::Local<v8::Context> context = ContextLocal(); |
453 | 466 |
454 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 467 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
455 base::Bind(&DoNothingOnEventListenersChanged)); | 468 base::Bind(&DoNothingOnEventListenersChanged)); |
456 const char kEventName[] = "alpha"; | 469 const char kEventName[] = "alpha"; |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
493 v8::Local<v8::Value> argv[] = {event, listener}; | 506 v8::Local<v8::Value> argv[] = {event, listener}; |
494 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); | 507 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); |
495 } | 508 } |
496 | 509 |
497 // Fire the event. All listeners should be removed (and we shouldn't crash). | 510 // Fire the event. All listeners should be removed (and we shouldn't crash). |
498 EXPECT_EQ(kNumListeners, | 511 EXPECT_EQ(kNumListeners, |
499 handler.GetNumEventListenersForTesting(kEventName, context)); | 512 handler.GetNumEventListenersForTesting(kEventName, context)); |
500 handler.FireEventInContext(kEventName, context, base::ListValue()); | 513 handler.FireEventInContext(kEventName, context, base::ListValue()); |
501 EXPECT_EQ(0u, handler.GetNumEventListenersForTesting(kEventName, context)); | 514 EXPECT_EQ(0u, handler.GetNumEventListenersForTesting(kEventName, context)); |
502 | 515 |
| 516 handler.InvalidateContext(context); |
503 // TODO(devlin): Another possible test: register listener a and listener b, | 517 // TODO(devlin): Another possible test: register listener a and listener b, |
504 // where a removes b and b removes a. Theoretically, only one should be | 518 // where a removes b and b removes a. Theoretically, only one should be |
505 // notified. Investigate what we currently do in JS-style bindings. | 519 // notified. Investigate what we currently do in JS-style bindings. |
506 } | 520 } |
507 | 521 |
508 // Test an event listener throwing an exception. | 522 // Test an event listener throwing an exception. |
509 TEST_F(APIEventHandlerTest, TestEventListenersThrowingExceptions) { | 523 TEST_F(APIEventHandlerTest, TestEventListenersThrowingExceptions) { |
510 // The default test util methods (RunFunction*) assume no errors will ever | 524 // The default test util methods (RunFunction*) assume no errors will ever |
511 // be encountered. Instead, use an implementation that allows errors. | 525 // be encountered. Instead, use an implementation that allows errors. |
512 auto run_js_and_expect_error = [](v8::Local<v8::Function> function, | 526 auto run_js_and_expect_error = [](v8::Local<v8::Function> function, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
577 ASSERT_TRUE(event_args); | 591 ASSERT_TRUE(event_args); |
578 handler.FireEventInContext(kEventName, context, *event_args); | 592 handler.FireEventInContext(kEventName, context, *event_args); |
579 | 593 |
580 // An exception should have been thrown by the first listener and the second | 594 // An exception should have been thrown by the first listener and the second |
581 // listener should have recorded the event arguments. | 595 // listener should have recorded the event arguments. |
582 EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context, | 596 EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context, |
583 "didThrow")); | 597 "didThrow")); |
584 EXPECT_EQ("[42]", GetStringPropertyFromObject(context->Global(), context, | 598 EXPECT_EQ("[42]", GetStringPropertyFromObject(context->Global(), context, |
585 "eventArgs")); | 599 "eventArgs")); |
586 EXPECT_TRUE(did_throw); | 600 EXPECT_TRUE(did_throw); |
| 601 |
| 602 handler.InvalidateContext(context); |
587 } | 603 } |
588 | 604 |
589 // Tests being notified as listeners are added or removed from events. | 605 // Tests being notified as listeners are added or removed from events. |
590 TEST_F(APIEventHandlerTest, CallbackNotifications) { | 606 TEST_F(APIEventHandlerTest, CallbackNotifications) { |
591 v8::HandleScope handle_scope(isolate()); | 607 v8::HandleScope handle_scope(isolate()); |
592 | 608 |
593 v8::Local<v8::Context> context_a = ContextLocal(); | 609 v8::Local<v8::Context> context_a = ContextLocal(); |
594 v8::Local<v8::Context> context_b = v8::Context::New(isolate()); | 610 v8::Local<v8::Context> context_b = v8::Context::New(isolate()); |
595 gin::ContextHolder holder_b(isolate()); | 611 gin::ContextHolder holder_b(isolate()); |
596 holder_b.SetContext(context_b); | 612 holder_b.SetContext(context_b); |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
699 v8::Local<v8::Function> add_listener = | 715 v8::Local<v8::Function> add_listener = |
700 FunctionFromString(context_b, kAddListenerFunction); | 716 FunctionFromString(context_b, kAddListenerFunction); |
701 v8::Local<v8::Function> listener = | 717 v8::Local<v8::Function> listener = |
702 FunctionFromString(context_b, "(function() {})"); | 718 FunctionFromString(context_b, "(function() {})"); |
703 v8::Local<v8::Value> argv[] = {event1_b, listener}; | 719 v8::Local<v8::Value> argv[] = {event1_b, listener}; |
704 RunFunction(add_listener, context_b, arraysize(argv), argv); | 720 RunFunction(add_listener, context_b, arraysize(argv), argv); |
705 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 721 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
706 } | 722 } |
707 EXPECT_EQ(1u, | 723 EXPECT_EQ(1u, |
708 handler.GetNumEventListenersForTesting(kEventName1, context_b)); | 724 handler.GetNumEventListenersForTesting(kEventName1, context_b)); |
| 725 |
| 726 // When the contexts are invalidated, we should receive listener removed |
| 727 // notifications. |
| 728 EXPECT_CALL( |
| 729 change_handler, |
| 730 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, context_a)) |
| 731 .Times(1); |
| 732 EXPECT_CALL( |
| 733 change_handler, |
| 734 Run(kEventName2, binding::EventListenersChanged::NO_LISTENERS, context_a)) |
| 735 .Times(1); |
| 736 handler.InvalidateContext(context_a); |
| 737 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 738 |
| 739 EXPECT_CALL( |
| 740 change_handler, |
| 741 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, context_b)) |
| 742 .Times(1); |
| 743 handler.InvalidateContext(context_b); |
| 744 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
709 } | 745 } |
710 | 746 |
711 // Test registering an argument massager for a given event. | 747 // Test registering an argument massager for a given event. |
712 TEST_F(APIEventHandlerTest, TestArgumentMassagers) { | 748 TEST_F(APIEventHandlerTest, TestArgumentMassagers) { |
713 v8::HandleScope handle_scope(isolate()); | 749 v8::HandleScope handle_scope(isolate()); |
714 v8::Local<v8::Context> context = ContextLocal(); | 750 v8::Local<v8::Context> context = ContextLocal(); |
715 | 751 |
716 const char kEventName[] = "alpha"; | 752 const char kEventName[] = "alpha"; |
717 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 753 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
718 base::Bind(&DoNothingOnEventListenersChanged)); | 754 base::Bind(&DoNothingOnEventListenersChanged)); |
(...skipping 29 matching lines...) Expand all Loading... |
748 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | 784 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); |
749 ASSERT_TRUE(event_args); | 785 ASSERT_TRUE(event_args); |
750 handler.FireEventInContext(kEventName, context, *event_args); | 786 handler.FireEventInContext(kEventName, context, *event_args); |
751 | 787 |
752 EXPECT_EQ( | 788 EXPECT_EQ( |
753 "[\"first\",\"second\"]", | 789 "[\"first\",\"second\"]", |
754 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); | 790 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); |
755 EXPECT_EQ( | 791 EXPECT_EQ( |
756 "[\"primary\",\"secondary\"]", | 792 "[\"primary\",\"secondary\"]", |
757 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | 793 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); |
| 794 |
| 795 handler.InvalidateContext(context); |
758 } | 796 } |
759 | 797 |
760 // Test registering an argument massager for a given event and dispatching | 798 // Test registering an argument massager for a given event and dispatching |
761 // asynchronously. | 799 // asynchronously. |
762 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) { | 800 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) { |
763 v8::HandleScope handle_scope(isolate()); | 801 v8::HandleScope handle_scope(isolate()); |
764 v8::Local<v8::Context> context = ContextLocal(); | 802 v8::Local<v8::Context> context = ContextLocal(); |
765 | 803 |
766 const char kEventName[] = "alpha"; | 804 const char kEventName[] = "alpha"; |
767 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 805 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
814 ASSERT_TRUE(dispatch_value->IsFunction()); | 852 ASSERT_TRUE(dispatch_value->IsFunction()); |
815 v8::Local<v8::Value> dispatch_args[] = { | 853 v8::Local<v8::Value> dispatch_args[] = { |
816 V8ValueFromScriptSource(context, "['primary', 'secondary']"), | 854 V8ValueFromScriptSource(context, "['primary', 'secondary']"), |
817 }; | 855 }; |
818 RunFunction(dispatch_value.As<v8::Function>(), context, | 856 RunFunction(dispatch_value.As<v8::Function>(), context, |
819 arraysize(dispatch_args), dispatch_args); | 857 arraysize(dispatch_args), dispatch_args); |
820 | 858 |
821 EXPECT_EQ( | 859 EXPECT_EQ( |
822 "[\"primary\",\"secondary\"]", | 860 "[\"primary\",\"secondary\"]", |
823 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | 861 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); |
| 862 |
| 863 handler.InvalidateContext(context); |
824 } | 864 } |
825 | 865 |
826 // Test registering an argument massager and never dispatching. | 866 // Test registering an argument massager and never dispatching. |
827 TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) { | 867 TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) { |
828 v8::HandleScope handle_scope(isolate()); | 868 v8::HandleScope handle_scope(isolate()); |
829 v8::Local<v8::Context> context = ContextLocal(); | 869 v8::Local<v8::Context> context = ContextLocal(); |
830 | 870 |
831 const char kEventName[] = "alpha"; | 871 const char kEventName[] = "alpha"; |
832 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | 872 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), |
833 base::Bind(&DoNothingOnEventListenersChanged)); | 873 base::Bind(&DoNothingOnEventListenersChanged)); |
(...skipping 17 matching lines...) Expand all Loading... |
851 v8::Local<v8::Function> add_listener_function = | 891 v8::Local<v8::Function> add_listener_function = |
852 FunctionFromString(context, kAddListenerFunction); | 892 FunctionFromString(context, kAddListenerFunction); |
853 v8::Local<v8::Value> argv[] = {event, listener_function}; | 893 v8::Local<v8::Value> argv[] = {event, listener_function}; |
854 RunFunction(add_listener_function, context, arraysize(argv), argv); | 894 RunFunction(add_listener_function, context, arraysize(argv), argv); |
855 | 895 |
856 handler.FireEventInContext(kEventName, context, base::ListValue()); | 896 handler.FireEventInContext(kEventName, context, base::ListValue()); |
857 | 897 |
858 // Nothing should blow up. (We tested in the previous test that the event | 898 // Nothing should blow up. (We tested in the previous test that the event |
859 // isn't notified without calling dispatch, so all there is to test here is | 899 // isn't notified without calling dispatch, so all there is to test here is |
860 // that we don't crash.) | 900 // that we don't crash.) |
| 901 |
| 902 handler.InvalidateContext(context); |
861 } | 903 } |
862 | 904 |
863 } // namespace extensions | 905 } // namespace extensions |
OLD | NEW |