text: #include <functional>
  
  #include "common/event/dispatcher_impl.h"
  
  #include "test/mocks/common.h"
  
  #include "gmock/gmock.h"
  #include "gtest/gtest.h"
  
  using testing::InSequence;
  
  namespace Event {
  
  class TestDeferredDeletable : public DeferredDeletable {
  public:
    TestDeferredDeletable(std::function<void()> on_destroy) : on_destroy_(on_destroy) {}
    ~TestDeferredDeletable() { on_destroy_(); }
  
  private:
    std::function<void()> on_destroy_;
  };
  
  TEST(DispatcherImplTest, DeferredDelete) {
    InSequence s;
    DispatcherImpl dispatcher;
    ReadyWatcher watcher1;
  
    dispatcher.deferredDelete(
        DeferredDeletablePtr{new TestDeferredDeletable([&]() -> void { watcher1.ready(); })});
  
    // The first one will get deleted inline.
    EXPECT_CALL(watcher1, ready());
    dispatcher.clearDeferredDeleteList();
  
    // This one does a nested deferred delete. We should need two clear calls to actually get
    // rid of it with the vector swapping. We also test that inline clear() call does nothing.
    ReadyWatcher watcher2;
    ReadyWatcher watcher3;
    dispatcher.deferredDelete(DeferredDeletablePtr{new TestDeferredDeletable([&]() -> void {
      watcher2.ready();
      dispatcher.deferredDelete(
          DeferredDeletablePtr{new TestDeferredDeletable([&]() -> void { watcher3.ready(); })});
      dispatcher.clearDeferredDeleteList();
    })});
  
    EXPECT_CALL(watcher2, ready());
    dispatcher.clearDeferredDeleteList();
  
    EXPECT_CALL(watcher3, ready());
    dispatcher.clearDeferredDeleteList();
  }
  
  } // Event
  