| 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/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/renderer/api_binding_test.h" | 14 #include "extensions/renderer/api_binding_test.h" |
| 14 #include "extensions/renderer/api_binding_test_util.h" | 15 #include "extensions/renderer/api_binding_test_util.h" |
| 15 #include "gin/arguments.h" | 16 #include "gin/arguments.h" |
| 16 #include "gin/converter.h" | 17 #include "gin/converter.h" |
| 17 #include "gin/public/context_holder.h" | 18 #include "gin/public/context_holder.h" |
| 18 #include "testing/gmock/include/gmock/gmock.h" | 19 #include "testing/gmock/include/gmock/gmock.h" |
| 19 | 20 |
| 20 namespace extensions { | 21 namespace extensions { |
| 21 | 22 |
| 22 namespace { | 23 namespace { |
| 23 | 24 |
| 24 using MockEventChangeHandler = ::testing::StrictMock< | 25 using MockEventChangeHandler = ::testing::StrictMock< |
| 25 base::MockCallback<APIEventHandler::EventListenersChangedMethod>>; | 26 base::MockCallback<APIEventHandler::EventListenersChangedMethod>>; |
| 26 | 27 |
| 27 void DoNothingOnEventListenersChanged(const std::string& event_name, | 28 void DoNothingOnEventListenersChanged(const std::string& event_name, |
| 28 binding::EventListenersChanged change, | 29 binding::EventListenersChanged change, |
| 30 const base::DictionaryValue* value, |
| 29 v8::Local<v8::Context> context) {} | 31 v8::Local<v8::Context> context) {} |
| 30 | 32 |
| 31 class APIEventHandlerTest : public APIBindingTest { | 33 class APIEventHandlerTest : public APIBindingTest { |
| 32 protected: | 34 protected: |
| 33 APIEventHandlerTest() {} | 35 APIEventHandlerTest() {} |
| 34 ~APIEventHandlerTest() override {} | 36 ~APIEventHandlerTest() override {} |
| 35 | 37 |
| 36 void SetUp() override { | 38 void SetUp() override { |
| 37 APIBindingTest::SetUp(); | 39 APIBindingTest::SetUp(); |
| 38 handler_ = base::MakeUnique<APIEventHandler>( | 40 handler_ = base::MakeUnique<APIEventHandler>( |
| (...skipping 27 matching lines...) Expand all Loading... |
| 66 } // namespace | 68 } // namespace |
| 67 | 69 |
| 68 // Tests adding, removing, and querying event listeners by calling the | 70 // Tests adding, removing, and querying event listeners by calling the |
| 69 // associated methods on the JS object. | 71 // associated methods on the JS object. |
| 70 TEST_F(APIEventHandlerTest, AddingRemovingAndQueryingEventListeners) { | 72 TEST_F(APIEventHandlerTest, AddingRemovingAndQueryingEventListeners) { |
| 71 const char kEventName[] = "alpha"; | 73 const char kEventName[] = "alpha"; |
| 72 v8::HandleScope handle_scope(isolate()); | 74 v8::HandleScope handle_scope(isolate()); |
| 73 v8::Local<v8::Context> context = MainContext(); | 75 v8::Local<v8::Context> context = MainContext(); |
| 74 | 76 |
| 75 v8::Local<v8::Object> event = | 77 v8::Local<v8::Object> event = |
| 76 handler()->CreateEventInstance(kEventName, context); | 78 handler()->CreateEventInstance(kEventName, false, context); |
| 77 ASSERT_FALSE(event.IsEmpty()); | 79 ASSERT_FALSE(event.IsEmpty()); |
| 78 | 80 |
| 79 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); | 81 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); |
| 80 | 82 |
| 81 const char kListenerFunction[] = "(function() {})"; | 83 const char kListenerFunction[] = "(function() {})"; |
| 82 v8::Local<v8::Function> listener_function = | 84 v8::Local<v8::Function> listener_function = |
| 83 FunctionFromString(context, kListenerFunction); | 85 FunctionFromString(context, kListenerFunction); |
| 84 ASSERT_FALSE(listener_function.IsEmpty()); | 86 ASSERT_FALSE(listener_function.IsEmpty()); |
| 85 | 87 |
| 86 const char kAddListenerFunction[] = | 88 const char kAddListenerFunction[] = |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 } | 167 } |
| 166 | 168 |
| 167 // Tests listening for and firing different events. | 169 // Tests listening for and firing different events. |
| 168 TEST_F(APIEventHandlerTest, FiringEvents) { | 170 TEST_F(APIEventHandlerTest, FiringEvents) { |
| 169 const char kAlphaName[] = "alpha"; | 171 const char kAlphaName[] = "alpha"; |
| 170 const char kBetaName[] = "beta"; | 172 const char kBetaName[] = "beta"; |
| 171 v8::HandleScope handle_scope(isolate()); | 173 v8::HandleScope handle_scope(isolate()); |
| 172 v8::Local<v8::Context> context = MainContext(); | 174 v8::Local<v8::Context> context = MainContext(); |
| 173 | 175 |
| 174 v8::Local<v8::Object> alpha_event = | 176 v8::Local<v8::Object> alpha_event = |
| 175 handler()->CreateEventInstance(kAlphaName, context); | 177 handler()->CreateEventInstance(kAlphaName, false, context); |
| 176 v8::Local<v8::Object> beta_event = | 178 v8::Local<v8::Object> beta_event = |
| 177 handler()->CreateEventInstance(kBetaName, context); | 179 handler()->CreateEventInstance(kBetaName, false, context); |
| 178 ASSERT_FALSE(alpha_event.IsEmpty()); | 180 ASSERT_FALSE(alpha_event.IsEmpty()); |
| 179 ASSERT_FALSE(beta_event.IsEmpty()); | 181 ASSERT_FALSE(beta_event.IsEmpty()); |
| 180 | 182 |
| 181 const char kAlphaListenerFunction1[] = | 183 const char kAlphaListenerFunction1[] = |
| 182 "(function() {\n" | 184 "(function() {\n" |
| 183 " if (!this.alphaCount1) this.alphaCount1 = 0;\n" | 185 " if (!this.alphaCount1) this.alphaCount1 = 0;\n" |
| 184 " ++this.alphaCount1;\n" | 186 " ++this.alphaCount1;\n" |
| 185 "});\n"; | 187 "});\n"; |
| 186 v8::Local<v8::Function> alpha_listener1 = | 188 v8::Local<v8::Function> alpha_listener1 = |
| 187 FunctionFromString(context, kAlphaListenerFunction1); | 189 FunctionFromString(context, kAlphaListenerFunction1); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 234 EXPECT_TRUE( | 236 EXPECT_TRUE( |
| 235 gin::Converter<int32_t>::FromV8(context->GetIsolate(), res, &count)) | 237 gin::Converter<int32_t>::FromV8(context->GetIsolate(), res, &count)) |
| 236 << name; | 238 << name; |
| 237 return count; | 239 return count; |
| 238 }; | 240 }; |
| 239 | 241 |
| 240 EXPECT_EQ(0, get_fired_count("alphaCount1")); | 242 EXPECT_EQ(0, get_fired_count("alphaCount1")); |
| 241 EXPECT_EQ(0, get_fired_count("alphaCount2")); | 243 EXPECT_EQ(0, get_fired_count("alphaCount2")); |
| 242 EXPECT_EQ(0, get_fired_count("betaCount")); | 244 EXPECT_EQ(0, get_fired_count("betaCount")); |
| 243 | 245 |
| 244 handler()->FireEventInContext(kAlphaName, context, base::ListValue()); | 246 handler()->FireEventInContext(kAlphaName, context, base::ListValue(), |
| 247 EventFilteringInfo()); |
| 245 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kAlphaName, context)); | 248 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kAlphaName, context)); |
| 246 EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kBetaName, context)); | 249 EXPECT_EQ(1u, handler()->GetNumEventListenersForTesting(kBetaName, context)); |
| 247 | 250 |
| 248 EXPECT_EQ(1, get_fired_count("alphaCount1")); | 251 EXPECT_EQ(1, get_fired_count("alphaCount1")); |
| 249 EXPECT_EQ(1, get_fired_count("alphaCount2")); | 252 EXPECT_EQ(1, get_fired_count("alphaCount2")); |
| 250 EXPECT_EQ(0, get_fired_count("betaCount")); | 253 EXPECT_EQ(0, get_fired_count("betaCount")); |
| 251 | 254 |
| 252 handler()->FireEventInContext(kAlphaName, context, base::ListValue()); | 255 handler()->FireEventInContext(kAlphaName, context, base::ListValue(), |
| 256 EventFilteringInfo()); |
| 253 EXPECT_EQ(2, get_fired_count("alphaCount1")); | 257 EXPECT_EQ(2, get_fired_count("alphaCount1")); |
| 254 EXPECT_EQ(2, get_fired_count("alphaCount2")); | 258 EXPECT_EQ(2, get_fired_count("alphaCount2")); |
| 255 EXPECT_EQ(0, get_fired_count("betaCount")); | 259 EXPECT_EQ(0, get_fired_count("betaCount")); |
| 256 | 260 |
| 257 handler()->FireEventInContext(kBetaName, context, base::ListValue()); | 261 handler()->FireEventInContext(kBetaName, context, base::ListValue(), |
| 262 EventFilteringInfo()); |
| 258 EXPECT_EQ(2, get_fired_count("alphaCount1")); | 263 EXPECT_EQ(2, get_fired_count("alphaCount1")); |
| 259 EXPECT_EQ(2, get_fired_count("alphaCount2")); | 264 EXPECT_EQ(2, get_fired_count("alphaCount2")); |
| 260 EXPECT_EQ(1, get_fired_count("betaCount")); | 265 EXPECT_EQ(1, get_fired_count("betaCount")); |
| 261 } | 266 } |
| 262 | 267 |
| 263 // Tests firing events with arguments. | 268 // Tests firing events with arguments. |
| 264 TEST_F(APIEventHandlerTest, EventArguments) { | 269 TEST_F(APIEventHandlerTest, EventArguments) { |
| 265 v8::HandleScope handle_scope(isolate()); | 270 v8::HandleScope handle_scope(isolate()); |
| 266 v8::Local<v8::Context> context = MainContext(); | 271 v8::Local<v8::Context> context = MainContext(); |
| 267 | 272 |
| 268 const char kEventName[] = "alpha"; | 273 const char kEventName[] = "alpha"; |
| 269 v8::Local<v8::Object> event = | 274 v8::Local<v8::Object> event = |
| 270 handler()->CreateEventInstance(kEventName, context); | 275 handler()->CreateEventInstance(kEventName, false, context); |
| 271 ASSERT_FALSE(event.IsEmpty()); | 276 ASSERT_FALSE(event.IsEmpty()); |
| 272 | 277 |
| 273 const char kListenerFunction[] = | 278 const char kListenerFunction[] = |
| 274 "(function() { this.eventArgs = Array.from(arguments); })"; | 279 "(function() { this.eventArgs = Array.from(arguments); })"; |
| 275 v8::Local<v8::Function> listener_function = | 280 v8::Local<v8::Function> listener_function = |
| 276 FunctionFromString(context, kListenerFunction); | 281 FunctionFromString(context, kListenerFunction); |
| 277 ASSERT_FALSE(listener_function.IsEmpty()); | 282 ASSERT_FALSE(listener_function.IsEmpty()); |
| 278 | 283 |
| 279 { | 284 { |
| 280 const char kAddListenerFunction[] = | 285 const char kAddListenerFunction[] = |
| 281 "(function(event, listener) { event.addListener(listener); })"; | 286 "(function(event, listener) { event.addListener(listener); })"; |
| 282 v8::Local<v8::Function> add_listener_function = | 287 v8::Local<v8::Function> add_listener_function = |
| 283 FunctionFromString(context, kAddListenerFunction); | 288 FunctionFromString(context, kAddListenerFunction); |
| 284 v8::Local<v8::Value> argv[] = {event, listener_function}; | 289 v8::Local<v8::Value> argv[] = {event, listener_function}; |
| 285 RunFunction(add_listener_function, context, arraysize(argv), argv); | 290 RunFunction(add_listener_function, context, arraysize(argv), argv); |
| 286 } | 291 } |
| 287 | 292 |
| 288 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; | 293 const char kArguments[] = "['foo',1,{'prop1':'bar'}]"; |
| 289 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | 294 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); |
| 290 ASSERT_TRUE(event_args); | 295 ASSERT_TRUE(event_args); |
| 291 handler()->FireEventInContext(kEventName, context, *event_args); | 296 handler()->FireEventInContext(kEventName, context, *event_args, |
| 297 EventFilteringInfo()); |
| 292 | 298 |
| 293 EXPECT_EQ( | 299 EXPECT_EQ( |
| 294 ReplaceSingleQuotes(kArguments), | 300 ReplaceSingleQuotes(kArguments), |
| 295 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | 301 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); |
| 296 } | 302 } |
| 297 | 303 |
| 298 // Test dispatching events to multiple contexts. | 304 // Test dispatching events to multiple contexts. |
| 299 TEST_F(APIEventHandlerTest, MultipleContexts) { | 305 TEST_F(APIEventHandlerTest, MultipleContexts) { |
| 300 v8::HandleScope handle_scope(isolate()); | 306 v8::HandleScope handle_scope(isolate()); |
| 301 | 307 |
| 302 v8::Local<v8::Context> context_a = MainContext(); | 308 v8::Local<v8::Context> context_a = MainContext(); |
| 303 v8::Local<v8::Context> context_b = AddContext(); | 309 v8::Local<v8::Context> context_b = AddContext(); |
| 304 | 310 |
| 305 const char kEventName[] = "onFoo"; | 311 const char kEventName[] = "onFoo"; |
| 306 | 312 |
| 307 | 313 |
| 308 v8::Local<v8::Function> listener_a = FunctionFromString( | 314 v8::Local<v8::Function> listener_a = FunctionFromString( |
| 309 context_a, "(function(arg) { this.eventArgs = arg + 'alpha'; })"); | 315 context_a, "(function(arg) { this.eventArgs = arg + 'alpha'; })"); |
| 310 ASSERT_FALSE(listener_a.IsEmpty()); | 316 ASSERT_FALSE(listener_a.IsEmpty()); |
| 311 v8::Local<v8::Function> listener_b = FunctionFromString( | 317 v8::Local<v8::Function> listener_b = FunctionFromString( |
| 312 context_b, "(function(arg) { this.eventArgs = arg + 'beta'; })"); | 318 context_b, "(function(arg) { this.eventArgs = arg + 'beta'; })"); |
| 313 ASSERT_FALSE(listener_b.IsEmpty()); | 319 ASSERT_FALSE(listener_b.IsEmpty()); |
| 314 | 320 |
| 315 // Create two instances of the same event in different contexts. | 321 // Create two instances of the same event in different contexts. |
| 316 v8::Local<v8::Object> event_a = | 322 v8::Local<v8::Object> event_a = |
| 317 handler()->CreateEventInstance(kEventName, context_a); | 323 handler()->CreateEventInstance(kEventName, false, context_a); |
| 318 ASSERT_FALSE(event_a.IsEmpty()); | 324 ASSERT_FALSE(event_a.IsEmpty()); |
| 319 v8::Local<v8::Object> event_b = | 325 v8::Local<v8::Object> event_b = |
| 320 handler()->CreateEventInstance(kEventName, context_b); | 326 handler()->CreateEventInstance(kEventName, false, context_b); |
| 321 ASSERT_FALSE(event_b.IsEmpty()); | 327 ASSERT_FALSE(event_b.IsEmpty()); |
| 322 | 328 |
| 323 // Add two separate listeners to the event, one in each context. | 329 // Add two separate listeners to the event, one in each context. |
| 324 const char kAddListenerFunction[] = | 330 const char kAddListenerFunction[] = |
| 325 "(function(event, listener) { event.addListener(listener); })"; | 331 "(function(event, listener) { event.addListener(listener); })"; |
| 326 { | 332 { |
| 327 v8::Local<v8::Function> add_listener_a = | 333 v8::Local<v8::Function> add_listener_a = |
| 328 FunctionFromString(context_a, kAddListenerFunction); | 334 FunctionFromString(context_a, kAddListenerFunction); |
| 329 v8::Local<v8::Value> argv[] = {event_a, listener_a}; | 335 v8::Local<v8::Value> argv[] = {event_a, listener_a}; |
| 330 RunFunction(add_listener_a, context_a, arraysize(argv), argv); | 336 RunFunction(add_listener_a, context_a, arraysize(argv), argv); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 344 handler()->GetNumEventListenersForTesting(kEventName, context_a)); | 350 handler()->GetNumEventListenersForTesting(kEventName, context_a)); |
| 345 EXPECT_EQ(1u, | 351 EXPECT_EQ(1u, |
| 346 handler()->GetNumEventListenersForTesting(kEventName, context_b)); | 352 handler()->GetNumEventListenersForTesting(kEventName, context_b)); |
| 347 | 353 |
| 348 // Dispatch the event in context_a - the listener in context_b should not be | 354 // Dispatch the event in context_a - the listener in context_b should not be |
| 349 // notified. | 355 // notified. |
| 350 std::unique_ptr<base::ListValue> arguments_a = | 356 std::unique_ptr<base::ListValue> arguments_a = |
| 351 ListValueFromString("['result_a:']"); | 357 ListValueFromString("['result_a:']"); |
| 352 ASSERT_TRUE(arguments_a); | 358 ASSERT_TRUE(arguments_a); |
| 353 | 359 |
| 354 handler()->FireEventInContext(kEventName, context_a, *arguments_a); | 360 handler()->FireEventInContext(kEventName, context_a, *arguments_a, |
| 361 EventFilteringInfo()); |
| 355 { | 362 { |
| 356 EXPECT_EQ("\"result_a:alpha\"", | 363 EXPECT_EQ("\"result_a:alpha\"", |
| 357 GetStringPropertyFromObject(context_a->Global(), context_a, | 364 GetStringPropertyFromObject(context_a->Global(), context_a, |
| 358 "eventArgs")); | 365 "eventArgs")); |
| 359 } | 366 } |
| 360 { | 367 { |
| 361 EXPECT_EQ("undefined", GetStringPropertyFromObject(context_b->Global(), | 368 EXPECT_EQ("undefined", GetStringPropertyFromObject(context_b->Global(), |
| 362 context_b, "eventArgs")); | 369 context_b, "eventArgs")); |
| 363 } | 370 } |
| 364 | 371 |
| 365 // Dispatch the event in context_b - the listener in context_a should not be | 372 // Dispatch the event in context_b - the listener in context_a should not be |
| 366 // notified. | 373 // notified. |
| 367 std::unique_ptr<base::ListValue> arguments_b = | 374 std::unique_ptr<base::ListValue> arguments_b = |
| 368 ListValueFromString("['result_b:']"); | 375 ListValueFromString("['result_b:']"); |
| 369 ASSERT_TRUE(arguments_b); | 376 ASSERT_TRUE(arguments_b); |
| 370 handler()->FireEventInContext(kEventName, context_b, *arguments_b); | 377 handler()->FireEventInContext(kEventName, context_b, *arguments_b, |
| 378 EventFilteringInfo()); |
| 371 { | 379 { |
| 372 EXPECT_EQ("\"result_a:alpha\"", | 380 EXPECT_EQ("\"result_a:alpha\"", |
| 373 GetStringPropertyFromObject(context_a->Global(), context_a, | 381 GetStringPropertyFromObject(context_a->Global(), context_a, |
| 374 "eventArgs")); | 382 "eventArgs")); |
| 375 } | 383 } |
| 376 { | 384 { |
| 377 EXPECT_EQ("\"result_b:beta\"", | 385 EXPECT_EQ("\"result_b:beta\"", |
| 378 GetStringPropertyFromObject(context_b->Global(), context_b, | 386 GetStringPropertyFromObject(context_b->Global(), context_b, |
| 379 "eventArgs")); | 387 "eventArgs")); |
| 380 } | 388 } |
| 381 } | 389 } |
| 382 | 390 |
| 383 TEST_F(APIEventHandlerTest, DifferentCallingMethods) { | 391 TEST_F(APIEventHandlerTest, DifferentCallingMethods) { |
| 384 v8::HandleScope handle_scope(isolate()); | 392 v8::HandleScope handle_scope(isolate()); |
| 385 v8::Local<v8::Context> context = MainContext(); | 393 v8::Local<v8::Context> context = MainContext(); |
| 386 | 394 |
| 387 const char kEventName[] = "alpha"; | 395 const char kEventName[] = "alpha"; |
| 388 v8::Local<v8::Object> event = | 396 v8::Local<v8::Object> event = |
| 389 handler()->CreateEventInstance(kEventName, context); | 397 handler()->CreateEventInstance(kEventName, false, context); |
| 390 ASSERT_FALSE(event.IsEmpty()); | 398 ASSERT_FALSE(event.IsEmpty()); |
| 391 | 399 |
| 392 const char kAddListenerOnNull[] = | 400 const char kAddListenerOnNull[] = |
| 393 "(function(event) {\n" | 401 "(function(event) {\n" |
| 394 " event.addListener.call(null, function() {});\n" | 402 " event.addListener.call(null, function() {});\n" |
| 395 "})"; | 403 "})"; |
| 396 { | 404 { |
| 397 v8::Local<v8::Value> args[] = {event}; | 405 v8::Local<v8::Value> args[] = {event}; |
| 398 // TODO(devlin): This is the generic type error that gin throws. It's not | 406 // TODO(devlin): This is the generic type error that gin throws. It's not |
| 399 // very descriptive, nor does it match the web (which would just say e.g. | 407 // 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 Loading... |
| 431 context, 1, args); | 439 context, 1, args); |
| 432 } | 440 } |
| 433 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); | 441 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); |
| 434 } | 442 } |
| 435 | 443 |
| 436 TEST_F(APIEventHandlerTest, TestDispatchFromJs) { | 444 TEST_F(APIEventHandlerTest, TestDispatchFromJs) { |
| 437 v8::HandleScope handle_scope(isolate()); | 445 v8::HandleScope handle_scope(isolate()); |
| 438 v8::Local<v8::Context> context = MainContext(); | 446 v8::Local<v8::Context> context = MainContext(); |
| 439 | 447 |
| 440 v8::Local<v8::Object> event = | 448 v8::Local<v8::Object> event = |
| 441 handler()->CreateEventInstance("alpha", context); | 449 handler()->CreateEventInstance("alpha", false, context); |
| 442 ASSERT_FALSE(event.IsEmpty()); | 450 ASSERT_FALSE(event.IsEmpty()); |
| 443 | 451 |
| 444 const char kListenerFunction[] = | 452 const char kListenerFunction[] = |
| 445 "(function() {\n" | 453 "(function() {\n" |
| 446 " this.eventArgs = Array.from(arguments);\n" | 454 " this.eventArgs = Array.from(arguments);\n" |
| 447 "});"; | 455 "});"; |
| 448 v8::Local<v8::Function> listener = | 456 v8::Local<v8::Function> listener = |
| 449 FunctionFromString(context, kListenerFunction); | 457 FunctionFromString(context, kListenerFunction); |
| 450 | 458 |
| 451 const char kAddListenerFunction[] = | 459 const char kAddListenerFunction[] = |
| (...skipping 20 matching lines...) Expand all Loading... |
| 472 context->Global(), context, "eventArgs")); | 480 context->Global(), context, "eventArgs")); |
| 473 } | 481 } |
| 474 | 482 |
| 475 // Test listeners that remove themselves in their handling of the event. | 483 // Test listeners that remove themselves in their handling of the event. |
| 476 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) { | 484 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) { |
| 477 v8::HandleScope handle_scope(isolate()); | 485 v8::HandleScope handle_scope(isolate()); |
| 478 v8::Local<v8::Context> context = MainContext(); | 486 v8::Local<v8::Context> context = MainContext(); |
| 479 | 487 |
| 480 const char kEventName[] = "alpha"; | 488 const char kEventName[] = "alpha"; |
| 481 v8::Local<v8::Object> event = | 489 v8::Local<v8::Object> event = |
| 482 handler()->CreateEventInstance(kEventName, context); | 490 handler()->CreateEventInstance(kEventName, false, context); |
| 483 ASSERT_FALSE(event.IsEmpty()); | 491 ASSERT_FALSE(event.IsEmpty()); |
| 484 { | 492 { |
| 485 // Cache the event object on the global in order to allow for easy removal. | 493 // Cache the event object on the global in order to allow for easy removal. |
| 486 v8::Local<v8::Function> set_event_on_global = | 494 v8::Local<v8::Function> set_event_on_global = |
| 487 FunctionFromString( | 495 FunctionFromString( |
| 488 context, | 496 context, |
| 489 "(function(event) { this.testEvent = event; })"); | 497 "(function(event) { this.testEvent = event; })"); |
| 490 v8::Local<v8::Value> args[] = {event}; | 498 v8::Local<v8::Value> args[] = {event}; |
| 491 RunFunctionOnGlobal(set_event_on_global, context, arraysize(args), args); | 499 RunFunctionOnGlobal(set_event_on_global, context, arraysize(args), args); |
| 492 EXPECT_EQ(event, | 500 EXPECT_EQ(event, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 514 FunctionFromString(context, kAddListenerFunction); | 522 FunctionFromString(context, kAddListenerFunction); |
| 515 | 523 |
| 516 for (const auto& listener : listeners) { | 524 for (const auto& listener : listeners) { |
| 517 v8::Local<v8::Value> argv[] = {event, listener}; | 525 v8::Local<v8::Value> argv[] = {event, listener}; |
| 518 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); | 526 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); |
| 519 } | 527 } |
| 520 | 528 |
| 521 // Fire the event. All listeners should be removed (and we shouldn't crash). | 529 // Fire the event. All listeners should be removed (and we shouldn't crash). |
| 522 EXPECT_EQ(kNumListeners, | 530 EXPECT_EQ(kNumListeners, |
| 523 handler()->GetNumEventListenersForTesting(kEventName, context)); | 531 handler()->GetNumEventListenersForTesting(kEventName, context)); |
| 524 handler()->FireEventInContext(kEventName, context, base::ListValue()); | 532 handler()->FireEventInContext(kEventName, context, base::ListValue(), |
| 533 EventFilteringInfo()); |
| 525 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); | 534 EXPECT_EQ(0u, handler()->GetNumEventListenersForTesting(kEventName, context)); |
| 526 | 535 |
| 527 // TODO(devlin): Another possible test: register listener a and listener b, | 536 // TODO(devlin): Another possible test: register listener a and listener b, |
| 528 // where a removes b and b removes a. Theoretically, only one should be | 537 // where a removes b and b removes a. Theoretically, only one should be |
| 529 // notified. Investigate what we currently do in JS-style bindings. | 538 // notified. Investigate what we currently do in JS-style bindings. |
| 530 } | 539 } |
| 531 | 540 |
| 532 // Test an event listener throwing an exception. | 541 // Test an event listener throwing an exception. |
| 533 TEST_F(APIEventHandlerTest, TestEventListenersThrowingExceptions) { | 542 TEST_F(APIEventHandlerTest, TestEventListenersThrowingExceptions) { |
| 534 // The default test util methods (RunFunction*) assume no errors will ever | 543 // The default test util methods (RunFunction*) assume no errors will ever |
| (...skipping 11 matching lines...) Expand all Loading... |
| 546 | 555 |
| 547 SetHandler(base::MakeUnique<APIEventHandler>( | 556 SetHandler(base::MakeUnique<APIEventHandler>( |
| 548 base::Bind(run_js_and_expect_error), | 557 base::Bind(run_js_and_expect_error), |
| 549 base::Bind(&DoNothingOnEventListenersChanged))); | 558 base::Bind(&DoNothingOnEventListenersChanged))); |
| 550 | 559 |
| 551 v8::HandleScope handle_scope(isolate()); | 560 v8::HandleScope handle_scope(isolate()); |
| 552 v8::Local<v8::Context> context = MainContext(); | 561 v8::Local<v8::Context> context = MainContext(); |
| 553 | 562 |
| 554 const char kEventName[] = "alpha"; | 563 const char kEventName[] = "alpha"; |
| 555 v8::Local<v8::Object> event = | 564 v8::Local<v8::Object> event = |
| 556 handler()->CreateEventInstance(kEventName, context); | 565 handler()->CreateEventInstance(kEventName, false, context); |
| 557 ASSERT_FALSE(event.IsEmpty()); | 566 ASSERT_FALSE(event.IsEmpty()); |
| 558 | 567 |
| 559 bool did_throw = false; | 568 bool did_throw = false; |
| 560 auto message_listener = [](v8::Local<v8::Message> message, | 569 auto message_listener = [](v8::Local<v8::Message> message, |
| 561 v8::Local<v8::Value> data) { | 570 v8::Local<v8::Value> data) { |
| 562 ASSERT_FALSE(data.IsEmpty()); | 571 ASSERT_FALSE(data.IsEmpty()); |
| 563 ASSERT_TRUE(data->IsExternal()); | 572 ASSERT_TRUE(data->IsExternal()); |
| 564 bool* did_throw = static_cast<bool*>(data.As<v8::External>()->Value()); | 573 bool* did_throw = static_cast<bool*>(data.As<v8::External>()->Value()); |
| 565 *did_throw = true; | 574 *did_throw = true; |
| 566 EXPECT_EQ("Uncaught Error: Event handler error", | 575 EXPECT_EQ("Uncaught Error: Event handler error", |
| (...skipping 27 matching lines...) Expand all Loading... |
| 594 for (int i = 0; i < 2; ++i) { | 603 for (int i = 0; i < 2; ++i) { |
| 595 v8::Local<v8::Function> listener = | 604 v8::Local<v8::Function> listener = |
| 596 FunctionFromString(context, kListenerFunction); | 605 FunctionFromString(context, kListenerFunction); |
| 597 v8::Local<v8::Value> argv[] = {event, listener}; | 606 v8::Local<v8::Value> argv[] = {event, listener}; |
| 598 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); | 607 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv); |
| 599 } | 608 } |
| 600 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); | 609 EXPECT_EQ(2u, handler()->GetNumEventListenersForTesting(kEventName, context)); |
| 601 | 610 |
| 602 std::unique_ptr<base::ListValue> event_args = ListValueFromString("[42]"); | 611 std::unique_ptr<base::ListValue> event_args = ListValueFromString("[42]"); |
| 603 ASSERT_TRUE(event_args); | 612 ASSERT_TRUE(event_args); |
| 604 handler()->FireEventInContext(kEventName, context, *event_args); | 613 handler()->FireEventInContext(kEventName, context, *event_args, |
| 614 EventFilteringInfo()); |
| 605 | 615 |
| 606 // An exception should have been thrown by the first listener and the second | 616 // An exception should have been thrown by the first listener and the second |
| 607 // listener should have recorded the event arguments. | 617 // listener should have recorded the event arguments. |
| 608 EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context, | 618 EXPECT_EQ("true", GetStringPropertyFromObject(context->Global(), context, |
| 609 "didThrow")); | 619 "didThrow")); |
| 610 EXPECT_EQ("[42]", GetStringPropertyFromObject(context->Global(), context, | 620 EXPECT_EQ("[42]", GetStringPropertyFromObject(context->Global(), context, |
| 611 "eventArgs")); | 621 "eventArgs")); |
| 612 EXPECT_TRUE(did_throw); | 622 EXPECT_TRUE(did_throw); |
| 613 } | 623 } |
| 614 | 624 |
| 615 // Tests being notified as listeners are added or removed from events. | 625 // Tests being notified as listeners are added or removed from events. |
| 616 TEST_F(APIEventHandlerTest, CallbackNotifications) { | 626 TEST_F(APIEventHandlerTest, CallbackNotifications) { |
| 617 MockEventChangeHandler change_handler; | 627 MockEventChangeHandler change_handler; |
| 618 SetHandler(base::MakeUnique<APIEventHandler>( | 628 SetHandler(base::MakeUnique<APIEventHandler>( |
| 619 base::Bind(&RunFunctionOnGlobalAndIgnoreResult), change_handler.Get())); | 629 base::Bind(&RunFunctionOnGlobalAndIgnoreResult), change_handler.Get())); |
| 620 | 630 |
| 621 v8::HandleScope handle_scope(isolate()); | 631 v8::HandleScope handle_scope(isolate()); |
| 622 | 632 |
| 623 v8::Local<v8::Context> context_a = MainContext(); | 633 v8::Local<v8::Context> context_a = MainContext(); |
| 624 v8::Local<v8::Context> context_b = AddContext(); | 634 v8::Local<v8::Context> context_b = AddContext(); |
| 625 | 635 |
| 626 const char kEventName1[] = "onFoo"; | 636 const char kEventName1[] = "onFoo"; |
| 627 const char kEventName2[] = "onBar"; | 637 const char kEventName2[] = "onBar"; |
| 628 v8::Local<v8::Object> event1_a = | 638 v8::Local<v8::Object> event1_a = |
| 629 handler()->CreateEventInstance(kEventName1, context_a); | 639 handler()->CreateEventInstance(kEventName1, false, context_a); |
| 630 ASSERT_FALSE(event1_a.IsEmpty()); | 640 ASSERT_FALSE(event1_a.IsEmpty()); |
| 631 v8::Local<v8::Object> event2_a = | 641 v8::Local<v8::Object> event2_a = |
| 632 handler()->CreateEventInstance(kEventName2, context_a); | 642 handler()->CreateEventInstance(kEventName2, false, context_a); |
| 633 ASSERT_FALSE(event2_a.IsEmpty()); | 643 ASSERT_FALSE(event2_a.IsEmpty()); |
| 634 v8::Local<v8::Object> event1_b = | 644 v8::Local<v8::Object> event1_b = |
| 635 handler()->CreateEventInstance(kEventName1, context_b); | 645 handler()->CreateEventInstance(kEventName1, false, context_b); |
| 636 ASSERT_FALSE(event1_b.IsEmpty()); | 646 ASSERT_FALSE(event1_b.IsEmpty()); |
| 637 | 647 |
| 638 const char kAddListenerFunction[] = | 648 const char kAddListenerFunction[] = |
| 639 "(function(event, listener) { event.addListener(listener); })"; | 649 "(function(event, listener) { event.addListener(listener); })"; |
| 640 const char kRemoveListenerFunction[] = | 650 const char kRemoveListenerFunction[] = |
| 641 "(function(event, listener) { event.removeListener(listener); })"; | 651 "(function(event, listener) { event.removeListener(listener); })"; |
| 642 | 652 |
| 643 // Add a listener to the first event. The APIEventHandler should notify | 653 // Add a listener to the first event. The APIEventHandler should notify |
| 644 // since it's a change in state (no listeners -> listeners). | 654 // since it's a change in state (no listeners -> listeners). |
| 645 v8::Local<v8::Function> add_listener = | 655 v8::Local<v8::Function> add_listener = |
| 646 FunctionFromString(context_a, kAddListenerFunction); | 656 FunctionFromString(context_a, kAddListenerFunction); |
| 647 v8::Local<v8::Function> listener1 = | 657 v8::Local<v8::Function> listener1 = |
| 648 FunctionFromString(context_a, "(function() {})"); | 658 FunctionFromString(context_a, "(function() {})"); |
| 649 { | 659 { |
| 650 EXPECT_CALL(change_handler, | 660 EXPECT_CALL(change_handler, |
| 651 Run(kEventName1, binding::EventListenersChanged::HAS_LISTENERS, | 661 Run(kEventName1, binding::EventListenersChanged::HAS_LISTENERS, |
| 652 context_a)) | 662 nullptr, context_a)) |
| 653 .Times(1); | 663 .Times(1); |
| 654 v8::Local<v8::Value> argv[] = {event1_a, listener1}; | 664 v8::Local<v8::Value> argv[] = {event1_a, listener1}; |
| 655 RunFunction(add_listener, context_a, arraysize(argv), argv); | 665 RunFunction(add_listener, context_a, arraysize(argv), argv); |
| 656 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 666 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 657 } | 667 } |
| 658 EXPECT_EQ(1u, | 668 EXPECT_EQ(1u, |
| 659 handler()->GetNumEventListenersForTesting(kEventName1, context_a)); | 669 handler()->GetNumEventListenersForTesting(kEventName1, context_a)); |
| 660 | 670 |
| 661 // Add a second listener to the same event. We should not be notified, since | 671 // Add a second listener to the same event. We should not be notified, since |
| 662 // the event already had listeners. | 672 // the event already had listeners. |
| (...skipping 16 matching lines...) Expand all Loading... |
| 679 } | 689 } |
| 680 | 690 |
| 681 EXPECT_EQ(1u, | 691 EXPECT_EQ(1u, |
| 682 handler()->GetNumEventListenersForTesting(kEventName1, context_a)); | 692 handler()->GetNumEventListenersForTesting(kEventName1, context_a)); |
| 683 | 693 |
| 684 // Remove the final listener from the event. We should be notified that the | 694 // Remove the final listener from the event. We should be notified that the |
| 685 // event no longer has listeners. | 695 // event no longer has listeners. |
| 686 { | 696 { |
| 687 EXPECT_CALL(change_handler, | 697 EXPECT_CALL(change_handler, |
| 688 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, | 698 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, |
| 689 context_a)) | 699 nullptr, context_a)) |
| 690 .Times(1); | 700 .Times(1); |
| 691 v8::Local<v8::Value> argv[] = {event1_a, listener2}; | 701 v8::Local<v8::Value> argv[] = {event1_a, listener2}; |
| 692 RunFunction(remove_listener, context_a, arraysize(argv), argv); | 702 RunFunction(remove_listener, context_a, arraysize(argv), argv); |
| 693 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 703 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 694 } | 704 } |
| 695 EXPECT_EQ(0u, | 705 EXPECT_EQ(0u, |
| 696 handler()->GetNumEventListenersForTesting(kEventName1, context_a)); | 706 handler()->GetNumEventListenersForTesting(kEventName1, context_a)); |
| 697 | 707 |
| 698 // Add a listener to a separate event to ensure we receive the right | 708 // Add a listener to a separate event to ensure we receive the right |
| 699 // notifications. | 709 // notifications. |
| 700 v8::Local<v8::Function> listener3 = | 710 v8::Local<v8::Function> listener3 = |
| 701 FunctionFromString(context_a, "(function() {})"); | 711 FunctionFromString(context_a, "(function() {})"); |
| 702 { | 712 { |
| 703 EXPECT_CALL(change_handler, | 713 EXPECT_CALL(change_handler, |
| 704 Run(kEventName2, binding::EventListenersChanged::HAS_LISTENERS, | 714 Run(kEventName2, binding::EventListenersChanged::HAS_LISTENERS, |
| 705 context_a)) | 715 nullptr, context_a)) |
| 706 .Times(1); | 716 .Times(1); |
| 707 v8::Local<v8::Value> argv[] = {event2_a, listener3}; | 717 v8::Local<v8::Value> argv[] = {event2_a, listener3}; |
| 708 RunFunction(add_listener, context_a, arraysize(argv), argv); | 718 RunFunction(add_listener, context_a, arraysize(argv), argv); |
| 709 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 719 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 710 } | 720 } |
| 711 EXPECT_EQ(1u, | 721 EXPECT_EQ(1u, |
| 712 handler()->GetNumEventListenersForTesting(kEventName2, context_a)); | 722 handler()->GetNumEventListenersForTesting(kEventName2, context_a)); |
| 713 | 723 |
| 714 { | 724 { |
| 715 EXPECT_CALL(change_handler, | 725 EXPECT_CALL(change_handler, |
| 716 Run(kEventName1, binding::EventListenersChanged::HAS_LISTENERS, | 726 Run(kEventName1, binding::EventListenersChanged::HAS_LISTENERS, |
| 717 context_b)) | 727 nullptr, context_b)) |
| 718 .Times(1); | 728 .Times(1); |
| 719 // And add a listener to an event in a different context to make sure the | 729 // And add a listener to an event in a different context to make sure the |
| 720 // associated context is correct. | 730 // associated context is correct. |
| 721 v8::Local<v8::Function> add_listener = | 731 v8::Local<v8::Function> add_listener = |
| 722 FunctionFromString(context_b, kAddListenerFunction); | 732 FunctionFromString(context_b, kAddListenerFunction); |
| 723 v8::Local<v8::Function> listener = | 733 v8::Local<v8::Function> listener = |
| 724 FunctionFromString(context_b, "(function() {})"); | 734 FunctionFromString(context_b, "(function() {})"); |
| 725 v8::Local<v8::Value> argv[] = {event1_b, listener}; | 735 v8::Local<v8::Value> argv[] = {event1_b, listener}; |
| 726 RunFunction(add_listener, context_b, arraysize(argv), argv); | 736 RunFunction(add_listener, context_b, arraysize(argv), argv); |
| 727 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 737 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 728 } | 738 } |
| 729 EXPECT_EQ(1u, | 739 EXPECT_EQ(1u, |
| 730 handler()->GetNumEventListenersForTesting(kEventName1, context_b)); | 740 handler()->GetNumEventListenersForTesting(kEventName1, context_b)); |
| 731 | 741 |
| 732 // When the contexts are invalidated, we should receive listener removed | 742 // When the contexts are invalidated, we should receive listener removed |
| 733 // notifications. | 743 // notifications. |
| 734 EXPECT_CALL( | 744 EXPECT_CALL(change_handler, |
| 735 change_handler, | 745 Run(kEventName2, binding::EventListenersChanged::NO_LISTENERS, |
| 736 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, context_a)) | 746 nullptr, context_a)) |
| 737 .Times(1); | |
| 738 EXPECT_CALL( | |
| 739 change_handler, | |
| 740 Run(kEventName2, binding::EventListenersChanged::NO_LISTENERS, context_a)) | |
| 741 .Times(1); | 747 .Times(1); |
| 742 DisposeContext(context_a); | 748 DisposeContext(context_a); |
| 743 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 749 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 744 | 750 |
| 745 EXPECT_CALL( | 751 EXPECT_CALL(change_handler, |
| 746 change_handler, | 752 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, |
| 747 Run(kEventName1, binding::EventListenersChanged::NO_LISTENERS, context_b)) | 753 nullptr, context_b)) |
| 748 .Times(1); | 754 .Times(1); |
| 749 DisposeContext(context_b); | 755 DisposeContext(context_b); |
| 750 ::testing::Mock::VerifyAndClearExpectations(&change_handler); | 756 ::testing::Mock::VerifyAndClearExpectations(&change_handler); |
| 751 } | 757 } |
| 752 | 758 |
| 753 // Test registering an argument massager for a given event. | 759 // Test registering an argument massager for a given event. |
| 754 TEST_F(APIEventHandlerTest, TestArgumentMassagers) { | 760 TEST_F(APIEventHandlerTest, TestArgumentMassagers) { |
| 755 v8::HandleScope handle_scope(isolate()); | 761 v8::HandleScope handle_scope(isolate()); |
| 756 v8::Local<v8::Context> context = MainContext(); | 762 v8::Local<v8::Context> context = MainContext(); |
| 757 | 763 |
| 758 const char kEventName[] = "alpha"; | 764 const char kEventName[] = "alpha"; |
| 759 v8::Local<v8::Object> event = | 765 v8::Local<v8::Object> event = |
| 760 handler()->CreateEventInstance(kEventName, context); | 766 handler()->CreateEventInstance(kEventName, false, context); |
| 761 ASSERT_FALSE(event.IsEmpty()); | 767 ASSERT_FALSE(event.IsEmpty()); |
| 762 | 768 |
| 763 const char kArgumentMassager[] = | 769 const char kArgumentMassager[] = |
| 764 "(function(originalArgs, dispatch) {\n" | 770 "(function(originalArgs, dispatch) {\n" |
| 765 " this.originalArgs = originalArgs;\n" | 771 " this.originalArgs = originalArgs;\n" |
| 766 " dispatch(['primary', 'secondary']);\n" | 772 " dispatch(['primary', 'secondary']);\n" |
| 767 "});"; | 773 "});"; |
| 768 v8::Local<v8::Function> massager = | 774 v8::Local<v8::Function> massager = |
| 769 FunctionFromString(context, kArgumentMassager); | 775 FunctionFromString(context, kArgumentMassager); |
| 770 handler()->RegisterArgumentMassager(context, "alpha", massager); | 776 handler()->RegisterArgumentMassager(context, "alpha", massager); |
| 771 | 777 |
| 772 const char kListenerFunction[] = | 778 const char kListenerFunction[] = |
| 773 "(function() { this.eventArgs = Array.from(arguments); })"; | 779 "(function() { this.eventArgs = Array.from(arguments); })"; |
| 774 v8::Local<v8::Function> listener_function = | 780 v8::Local<v8::Function> listener_function = |
| 775 FunctionFromString(context, kListenerFunction); | 781 FunctionFromString(context, kListenerFunction); |
| 776 ASSERT_FALSE(listener_function.IsEmpty()); | 782 ASSERT_FALSE(listener_function.IsEmpty()); |
| 777 | 783 |
| 778 { | 784 { |
| 779 const char kAddListenerFunction[] = | 785 const char kAddListenerFunction[] = |
| 780 "(function(event, listener) { event.addListener(listener); })"; | 786 "(function(event, listener) { event.addListener(listener); })"; |
| 781 v8::Local<v8::Function> add_listener_function = | 787 v8::Local<v8::Function> add_listener_function = |
| 782 FunctionFromString(context, kAddListenerFunction); | 788 FunctionFromString(context, kAddListenerFunction); |
| 783 v8::Local<v8::Value> argv[] = {event, listener_function}; | 789 v8::Local<v8::Value> argv[] = {event, listener_function}; |
| 784 RunFunction(add_listener_function, context, arraysize(argv), argv); | 790 RunFunction(add_listener_function, context, arraysize(argv), argv); |
| 785 } | 791 } |
| 786 | 792 |
| 787 const char kArguments[] = "['first','second']"; | 793 const char kArguments[] = "['first','second']"; |
| 788 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | 794 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); |
| 789 ASSERT_TRUE(event_args); | 795 ASSERT_TRUE(event_args); |
| 790 handler()->FireEventInContext(kEventName, context, *event_args); | 796 handler()->FireEventInContext(kEventName, context, *event_args, |
| 797 EventFilteringInfo()); |
| 791 | 798 |
| 792 EXPECT_EQ( | 799 EXPECT_EQ( |
| 793 "[\"first\",\"second\"]", | 800 "[\"first\",\"second\"]", |
| 794 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); | 801 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); |
| 795 EXPECT_EQ( | 802 EXPECT_EQ( |
| 796 "[\"primary\",\"secondary\"]", | 803 "[\"primary\",\"secondary\"]", |
| 797 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | 804 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); |
| 798 } | 805 } |
| 799 | 806 |
| 800 // Test registering an argument massager for a given event and dispatching | 807 // Test registering an argument massager for a given event and dispatching |
| 801 // asynchronously. | 808 // asynchronously. |
| 802 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) { | 809 TEST_F(APIEventHandlerTest, TestArgumentMassagersAsyncDispatch) { |
| 803 v8::HandleScope handle_scope(isolate()); | 810 v8::HandleScope handle_scope(isolate()); |
| 804 v8::Local<v8::Context> context = MainContext(); | 811 v8::Local<v8::Context> context = MainContext(); |
| 805 | 812 |
| 806 const char kEventName[] = "alpha"; | 813 const char kEventName[] = "alpha"; |
| 807 v8::Local<v8::Object> event = | 814 v8::Local<v8::Object> event = |
| 808 handler()->CreateEventInstance(kEventName, context); | 815 handler()->CreateEventInstance(kEventName, false, context); |
| 809 ASSERT_FALSE(event.IsEmpty()); | 816 ASSERT_FALSE(event.IsEmpty()); |
| 810 | 817 |
| 811 const char kArgumentMassager[] = | 818 const char kArgumentMassager[] = |
| 812 "(function(originalArgs, dispatch) {\n" | 819 "(function(originalArgs, dispatch) {\n" |
| 813 " this.originalArgs = originalArgs;\n" | 820 " this.originalArgs = originalArgs;\n" |
| 814 " this.dispatch = dispatch;\n" | 821 " this.dispatch = dispatch;\n" |
| 815 "});"; | 822 "});"; |
| 816 v8::Local<v8::Function> massager = | 823 v8::Local<v8::Function> massager = |
| 817 FunctionFromString(context, kArgumentMassager); | 824 FunctionFromString(context, kArgumentMassager); |
| 818 handler()->RegisterArgumentMassager(context, "alpha", massager); | 825 handler()->RegisterArgumentMassager(context, "alpha", massager); |
| 819 | 826 |
| 820 const char kListenerFunction[] = | 827 const char kListenerFunction[] = |
| 821 "(function() { this.eventArgs = Array.from(arguments); })"; | 828 "(function() { this.eventArgs = Array.from(arguments); })"; |
| 822 v8::Local<v8::Function> listener_function = | 829 v8::Local<v8::Function> listener_function = |
| 823 FunctionFromString(context, kListenerFunction); | 830 FunctionFromString(context, kListenerFunction); |
| 824 ASSERT_FALSE(listener_function.IsEmpty()); | 831 ASSERT_FALSE(listener_function.IsEmpty()); |
| 825 | 832 |
| 826 { | 833 { |
| 827 const char kAddListenerFunction[] = | 834 const char kAddListenerFunction[] = |
| 828 "(function(event, listener) { event.addListener(listener); })"; | 835 "(function(event, listener) { event.addListener(listener); })"; |
| 829 v8::Local<v8::Function> add_listener_function = | 836 v8::Local<v8::Function> add_listener_function = |
| 830 FunctionFromString(context, kAddListenerFunction); | 837 FunctionFromString(context, kAddListenerFunction); |
| 831 v8::Local<v8::Value> argv[] = {event, listener_function}; | 838 v8::Local<v8::Value> argv[] = {event, listener_function}; |
| 832 RunFunction(add_listener_function, context, arraysize(argv), argv); | 839 RunFunction(add_listener_function, context, arraysize(argv), argv); |
| 833 } | 840 } |
| 834 | 841 |
| 835 const char kArguments[] = "['first','second']"; | 842 const char kArguments[] = "['first','second']"; |
| 836 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); | 843 std::unique_ptr<base::ListValue> event_args = ListValueFromString(kArguments); |
| 837 ASSERT_TRUE(event_args); | 844 ASSERT_TRUE(event_args); |
| 838 handler()->FireEventInContext(kEventName, context, *event_args); | 845 handler()->FireEventInContext(kEventName, context, *event_args, |
| 846 EventFilteringInfo()); |
| 839 | 847 |
| 840 // The massager should have been triggered, but since it doesn't call | 848 // The massager should have been triggered, but since it doesn't call |
| 841 // dispatch(), the listener shouldn't have been notified. | 849 // dispatch(), the listener shouldn't have been notified. |
| 842 EXPECT_EQ( | 850 EXPECT_EQ( |
| 843 "[\"first\",\"second\"]", | 851 "[\"first\",\"second\"]", |
| 844 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); | 852 GetStringPropertyFromObject(context->Global(), context, "originalArgs")); |
| 845 EXPECT_EQ("undefined", GetStringPropertyFromObject(context->Global(), context, | 853 EXPECT_EQ("undefined", GetStringPropertyFromObject(context->Global(), context, |
| 846 "eventArgs")); | 854 "eventArgs")); |
| 847 | 855 |
| 848 // Dispatch the event. | 856 // Dispatch the event. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 861 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); | 869 GetStringPropertyFromObject(context->Global(), context, "eventArgs")); |
| 862 } | 870 } |
| 863 | 871 |
| 864 // Test registering an argument massager and never dispatching. | 872 // Test registering an argument massager and never dispatching. |
| 865 TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) { | 873 TEST_F(APIEventHandlerTest, TestArgumentMassagersNeverDispatch) { |
| 866 v8::HandleScope handle_scope(isolate()); | 874 v8::HandleScope handle_scope(isolate()); |
| 867 v8::Local<v8::Context> context = MainContext(); | 875 v8::Local<v8::Context> context = MainContext(); |
| 868 | 876 |
| 869 const char kEventName[] = "alpha"; | 877 const char kEventName[] = "alpha"; |
| 870 v8::Local<v8::Object> event = | 878 v8::Local<v8::Object> event = |
| 871 handler()->CreateEventInstance(kEventName, context); | 879 handler()->CreateEventInstance(kEventName, false, context); |
| 872 ASSERT_FALSE(event.IsEmpty()); | 880 ASSERT_FALSE(event.IsEmpty()); |
| 873 | 881 |
| 874 // A massager that never dispatches. | 882 // A massager that never dispatches. |
| 875 const char kArgumentMassager[] = "(function(originalArgs, dispatch) {})"; | 883 const char kArgumentMassager[] = "(function(originalArgs, dispatch) {})"; |
| 876 v8::Local<v8::Function> massager = | 884 v8::Local<v8::Function> massager = |
| 877 FunctionFromString(context, kArgumentMassager); | 885 FunctionFromString(context, kArgumentMassager); |
| 878 handler()->RegisterArgumentMassager(context, "alpha", massager); | 886 handler()->RegisterArgumentMassager(context, "alpha", massager); |
| 879 | 887 |
| 880 const char kListenerFunction[] = "(function() {})"; | 888 const char kListenerFunction[] = "(function() {})"; |
| 881 v8::Local<v8::Function> listener_function = | 889 v8::Local<v8::Function> listener_function = |
| 882 FunctionFromString(context, kListenerFunction); | 890 FunctionFromString(context, kListenerFunction); |
| 883 ASSERT_FALSE(listener_function.IsEmpty()); | 891 ASSERT_FALSE(listener_function.IsEmpty()); |
| 884 | 892 |
| 885 const char kAddListenerFunction[] = | 893 const char kAddListenerFunction[] = |
| 886 "(function(event, listener) { event.addListener(listener); })"; | 894 "(function(event, listener) { event.addListener(listener); })"; |
| 887 v8::Local<v8::Function> add_listener_function = | 895 v8::Local<v8::Function> add_listener_function = |
| 888 FunctionFromString(context, kAddListenerFunction); | 896 FunctionFromString(context, kAddListenerFunction); |
| 889 v8::Local<v8::Value> argv[] = {event, listener_function}; | 897 v8::Local<v8::Value> argv[] = {event, listener_function}; |
| 890 RunFunction(add_listener_function, context, arraysize(argv), argv); | 898 RunFunction(add_listener_function, context, arraysize(argv), argv); |
| 891 | 899 |
| 892 handler()->FireEventInContext(kEventName, context, base::ListValue()); | 900 handler()->FireEventInContext(kEventName, context, base::ListValue(), |
| 901 EventFilteringInfo()); |
| 893 | 902 |
| 894 // Nothing should blow up. (We tested in the previous test that the event | 903 // Nothing should blow up. (We tested in the previous test that the event |
| 895 // isn't notified without calling dispatch, so all there is to test here is | 904 // isn't notified without calling dispatch, so all there is to test here is |
| 896 // that we don't crash.) | 905 // that we don't crash.) |
| 897 } | 906 } |
| 898 | 907 |
| 899 // Test creating a custom event, as is done by a few of our custom bindings. | 908 // Test creating a custom event, as is done by a few of our custom bindings. |
| 900 TEST_F(APIEventHandlerTest, TestCreateCustomEvent) { | 909 TEST_F(APIEventHandlerTest, TestCreateCustomEvent) { |
| 901 v8::HandleScope handle_scope(isolate()); | 910 v8::HandleScope handle_scope(isolate()); |
| 902 v8::Local<v8::Context> context = MainContext(); | 911 v8::Local<v8::Context> context = MainContext(); |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 961 " event.addListener(function() {}.bind(null, event));\n" | 970 " event.addListener(function() {}.bind(null, event));\n" |
| 962 "})"; | 971 "})"; |
| 963 v8::Local<v8::Value> add_listener_argv[] = {event}; | 972 v8::Local<v8::Value> add_listener_argv[] = {event}; |
| 964 RunFunction(FunctionFromString(context, kAddListenerFunction), context, | 973 RunFunction(FunctionFromString(context, kAddListenerFunction), context, |
| 965 arraysize(add_listener_argv), add_listener_argv); | 974 arraysize(add_listener_argv), add_listener_argv); |
| 966 | 975 |
| 967 DisposeContext(context); | 976 DisposeContext(context); |
| 968 } | 977 } |
| 969 | 978 |
| 970 } // namespace extensions | 979 } // namespace extensions |
| OLD | NEW |