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

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

Issue 2605353003: [Extensions Bindings] Allow event listener unregistration in handling (Closed)
Patch Set: typo Created 3 years, 11 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
« no previous file with comments | « no previous file | extensions/renderer/event_emitter.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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/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/memory/ptr_util.h" 8 #include "base/memory/ptr_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after
440 { 440 {
441 v8::Local<v8::Value> argv[] = {event}; 441 v8::Local<v8::Value> argv[] = {event};
442 RunFunctionOnGlobal(fire_event_function, context, arraysize(argv), argv); 442 RunFunctionOnGlobal(fire_event_function, context, arraysize(argv), argv);
443 } 443 }
444 444
445 EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]", 445 EXPECT_EQ("[42,\"foo\",{\"bar\":\"baz\"}]",
446 GetStringPropertyFromObject( 446 GetStringPropertyFromObject(
447 context->Global(), context, "eventArgs")); 447 context->Global(), context, "eventArgs"));
448 } 448 }
449 449
450 // Test listeners that remove themselves in their handling of the event.
451 TEST_F(APIEventHandlerTest, RemovingListenersWhileHandlingEvent) {
452 v8::HandleScope handle_scope(isolate());
453 v8::Local<v8::Context> context = ContextLocal();
454
455 APIEventHandler handler(base::Bind(&RunFunctionOnGlobalAndIgnoreResult));
456 const char kEventName[] = "alpha";
457 v8::Local<v8::Object> event =
458 handler.CreateEventInstance(kEventName, context);
459 ASSERT_FALSE(event.IsEmpty());
460
461 {
462 // Cache the event object on the global in order to allow for easy removal.
463 v8::Local<v8::Function> set_event_on_global =
464 FunctionFromString(
465 context,
466 "(function(event) { this.testEvent = event; })");
467 v8::Local<v8::Value> args[] = {event};
468 RunFunctionOnGlobal(set_event_on_global, context, arraysize(args), args);
469 EXPECT_EQ(event,
470 GetPropertyFromObject(context->Global(), context, "testEvent"));
471 }
472
473 // A listener function that removes itself as a listener.
474 const char kListenerFunction[] =
475 "(function listener%d() {\n"
jbroman 2017/01/02 20:30:32 nit: You could also do this to avoid the neat to p
Devlin 2017/01/04 18:14:54 I like it, done.
476 " this.testEvent.removeListener(listener%d);\n"
477 "});";
478
479 // Create and add a bunch of listeners.
480 std::vector<v8::Local<v8::Function>> listeners;
481 const int kNumListeners = 20;
482 listeners.reserve(kNumListeners);
483 for (int i = 0; i < kNumListeners; ++i) {
484 listeners.push_back(FunctionFromString(
485 context,
486 base::StringPrintf(kListenerFunction, i, i)));
487 }
488
489 const char kAddListenerFunction[] =
490 "(function(event, listener) { event.addListener(listener); })";
491 v8::Local<v8::Function> add_listener_function =
492 FunctionFromString(context, kAddListenerFunction);
493
494 for (const auto& listener : listeners) {
495 v8::Local<v8::Value> argv[] = {event, listener};
496 RunFunctionOnGlobal(add_listener_function, context, arraysize(argv), argv);
497 }
498
499 // Fire the event. All listeners should be removed (and we shouldn't crash).
500 EXPECT_EQ(20u, handler.GetNumEventListenersForTesting(kEventName, context));
501 handler.FireEventInContext(kEventName, context, base::ListValue());
502 EXPECT_EQ(0u, handler.GetNumEventListenersForTesting(kEventName, context));
503
504 // TODO(devlin): Another possible test: register listener a and listener b,
505 // where a removes b and b removes a. Theoretically, only one should be
506 // notified. Investigate what we currently do in JS-style bindings.
507 }
508
450 } // namespace extensions 509 } // namespace extensions
OLDNEW
« no previous file with comments | « no previous file | extensions/renderer/event_emitter.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698