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" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "extensions/renderer/api_binding_test.h" | 12 #include "extensions/renderer/api_binding_test.h" |
13 #include "extensions/renderer/api_binding_test_util.h" | 13 #include "extensions/renderer/api_binding_test_util.h" |
14 #include "gin/arguments.h" | |
14 #include "gin/converter.h" | 15 #include "gin/converter.h" |
15 #include "gin/public/context_holder.h" | 16 #include "gin/public/context_holder.h" |
16 #include "testing/gmock/include/gmock/gmock.h" | 17 #include "testing/gmock/include/gmock/gmock.h" |
17 | 18 |
18 namespace extensions { | 19 namespace extensions { |
19 | 20 |
20 namespace { | 21 namespace { |
21 | 22 |
22 using MockEventChangeHandler = ::testing::StrictMock< | 23 using MockEventChangeHandler = ::testing::StrictMock< |
23 base::MockCallback<APIEventHandler::EventListenersChangedMethod>>; | 24 base::MockCallback<APIEventHandler::EventListenersChangedMethod>>; |
(...skipping 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
700 v8::Local<v8::Function> listener = | 701 v8::Local<v8::Function> listener = |
701 FunctionFromString(context_b, "(function() {})"); | 702 FunctionFromString(context_b, "(function() {})"); |
702 v8::Local<v8::Value> argv[] = {event1_b, listener}; | 703 v8::Local<v8::Value> argv[] = {event1_b, listener}; |
703 RunFunction(add_listener, context_b, arraysize(argv), argv); | 704 RunFunction(add_listener, context_b, arraysize(argv), argv); |
704 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 705 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
705 } | 706 } |
706 EXPECT_EQ(1u, | 707 EXPECT_EQ(1u, |
707 handler.GetNumEventListenersForTesting(kEventName1, context_b)); | 708 handler.GetNumEventListenersForTesting(kEventName1, context_b)); |
708 } | 709 } |
709 | 710 |
711 // Test registering an argument massager for a given event. | |
712 TEST_F(APIEventHandlerTest, TestArgumentMassagers) { | |
713 v8::HandleScope handle_scope(isolate()); | |
714 v8::Local<v8::Context> context = ContextLocal(); | |
715 | |
716 const char kEventName[] = "alpha"; | |
717 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | |
718 base::Bind(&DoNothingOnEventListenersChanged)); | |
719 v8::Local<v8::Object> event = | |
720 handler.CreateEventInstance(kEventName, context); | |
721 ASSERT_FALSE(event.IsEmpty()); | |
722 | |
723 const char kArgumentMassager[] = | |
724 "(function(originalArgs, dispatch) {\n" | |
725 " this.originalArgs = originalArgs;\n" | |
726 " dispatch(['primary', 'secondary']);\n" | |
727 "});"; | |
728 v8::Local<v8::Function> massager = | |
729 FunctionFromString(context, kArgumentMassager); | |
730 handler.RegisterArgumentMassager(context, "alpha", massager); | |
731 | |
732 const char kListenerFunction[] = | |
733 "(function() { this.eventArgs = Array.from(arguments); })"; | |
734 v8::Local<v8::Function> listener_function = | |
735 FunctionFromString(context, kListenerFunction); | |
736 ASSERT_FALSE(listener_function.IsEmpty()); | |
737 | |
738 { | |
739 const char kAddListenerFunction[] = | |
740 "(function(event, listener) { event.addListener(listener); })"; | |
741 v8::Local<v8::Function> add_listener_function = | |
742 FunctionFromString(context, kAddListenerFunction); | |
743 v8::Local<v8::Value> argv[] = {event, listener_function}; | |
744 RunFunction(add_listener_function, context, arraysize(argv), argv); | |
745 } | |
746 | |
747 const char kArguments[] = "['first','second']"; | |
748 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | |
749 ASSERT_TRUE(event_args); | |
750 handler.FireEventInContext(kEventName, context, *event_args); | |
751 | |
752 EXPECT_EQ( | |
753 "[\"first\",\"second\"]", | |
754 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); | |
755 EXPECT_EQ( | |
756 "[\"primary\",\"secondary\"]", | |
757 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | |
758 } | |
759 | |
760 // Test registering an argument massager for a given event and dispatching | |
761 // asynchronously. | |
762 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) { | |
763 v8::HandleScope handle_scope(isolate()); | |
764 v8::Local<v8::Context> context = ContextLocal(); | |
765 | |
766 const char kEventName[] = "alpha"; | |
767 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult), | |
768 base::Bind(&DoNothingOnEventListenersChanged)); | |
769 v8::Local<v8::Object> event = | |
770 handler.CreateEventInstance(kEventName, context); | |
771 ASSERT_FALSE(event.IsEmpty()); | |
772 | |
773 const char kArgumentMassager[] = | |
774 "(function(originalArgs, dispatch) {\n" | |
775 " this.originalArgs = originalArgs;\n" | |
776 " this.dispatch = dispatch;\n" | |
777 "});"; | |
778 v8::Local<v8::Function> massager = | |
779 FunctionFromString(context, kArgumentMassager); | |
780 handler.RegisterArgumentMassager(context, "alpha", massager); | |
781 | |
782 const char kListenerFunction[] = | |
783 "(function() { this.eventArgs = Array.from(arguments); })"; | |
784 v8::Local<v8::Function> listener_function = | |
785 FunctionFromString(context, kListenerFunction); | |
786 ASSERT_FALSE(listener_function.IsEmpty()); | |
787 | |
788 { | |
789 const char kAddListenerFunction[] = | |
790 "(function(event, listener) { event.addListener(listener); })"; | |
791 v8::Local<v8::Function> add_listener_function = | |
792 FunctionFromString(context, kAddListenerFunction); | |
793 v8::Local<v8::Value> argv[] = {event, listener_function}; | |
794 RunFunction(add_listener_function, context, arraysize(argv), argv); | |
795 } | |
796 | |
797 const char kArguments[] = "['first','second']"; | |
798 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | |
799 ASSERT_TRUE(event_args); | |
800 handler.FireEventInContext(kEventName, context, *event_args); | |
801 | |
802 // The massager should have been triggered, but since it doesn't call | |
803 // dispatch(), the listener shouldn't have been notified. | |
804 EXPECT_EQ( | |
805 "[\"first\",\"second\"]", | |
806 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); | |
807 EXPECT_EQ("undefined", GetStringPropertyFromObject(context->Global(), context, | |
808 "eventArgs")); | |
809 | |
810 // Dispatch the event. | |
lazyboy
2017/03/03 21:52:18
Can we also add a test case where we don't (re)dis
Devlin
2017/03/04 00:59:13
Sure, done.
| |
811 v8::Local<v8::Value> dispatch_value = | |
812 GetPropertyFromObject(context->Global(), context, "dispatch"); | |
813 ASSERT_FALSE(dispatch_value.IsEmpty()); | |
814 ASSERT_TRUE(dispatch_value->IsFunction()); | |
815 v8::Local<v8::Value> dispatch_args[] = { | |
816 V8ValueFromScriptSource(context, "['primary', 'secondary']"), | |
817 }; | |
818 RunFunction(dispatch_value.As<v8::Function>(), context, | |
819 arraysize(dispatch_args), dispatch_args); | |
820 | |
821 EXPECT_EQ( | |
822 "[\"primary\",\"secondary\"]", | |
823 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | |
824 } | |
825 | |
710 } // namespace extensions | 826 } // namespace extensions |
OLD | NEW |