test/source/base: Clean up duplicated code
diff --git a/test/source/base.cpp b/test/source/base.cpp
index a649166..0ca093b 100644
--- a/test/source/base.cpp
+++ b/test/source/base.cpp
@@ -25,6 +25,8 @@
 using testing::SaveArg;
 using testing::SetArgPointee;
 
+using UniqueEvent = std::unique_ptr<Event, std::function<void(Event*)>>;
+
 class BaseImpl : public Base
 {
   public:
@@ -41,20 +43,65 @@
 {
   protected:
     testing::StrictMock<test::SdEventMock> mock;
-    sd_event_source* expected_source = reinterpret_cast<sd_event_source*>(1234);
-    sd_event* expected_event = reinterpret_cast<sd_event*>(2345);
-    std::unique_ptr<Event> event;
+    sd_event_source* const expected_source =
+        reinterpret_cast<sd_event_source*>(1234);
+    sd_event* const expected_event = reinterpret_cast<sd_event*>(2345);
+    UniqueEvent event = make_event(expected_event);
 
-    virtual void SetUp()
+    UniqueEvent make_event(sd_event* event)
     {
-        event =
-            std::make_unique<Event>(expected_event, std::false_type(), &mock);
+        auto deleter = [this, event](Event* e) {
+            EXPECT_CALL(this->mock, sd_event_unref(event))
+                .WillOnce(Return(nullptr));
+            delete e;
+        };
+        return UniqueEvent(new Event(event, std::false_type(), &mock), deleter);
     }
-    virtual void TearDown()
+
+    // Using a unique_ptr to make sure we don't get any superfluous moves or
+    // copies.
+    std::unique_ptr<BaseImpl> make_base(const Event& event,
+                                        sd_event_source* source)
     {
-        EXPECT_CALL(mock, sd_event_unref(expected_event))
+        EXPECT_CALL(mock, sd_event_ref(event.get()))
+            .WillOnce(Return(event.get()));
+        auto ret = std::make_unique<BaseImpl>(event, source, std::false_type());
+        EXPECT_EQ(source, ret->get());
+        EXPECT_NE(&event, &ret->get_event());
+        EXPECT_EQ(event.get(), ret->get_event().get());
+        EXPECT_FALSE(ret->get_prepare());
+        return ret;
+    }
+
+    void set_prepare_placeholder(Base& base)
+    {
+        EXPECT_CALL(mock, sd_event_source_set_prepare(base.get(), testing::_))
+            .WillOnce(Return(0));
+        base.set_prepare([](Base&) {});
+        EXPECT_TRUE(base.get_prepare());
+    }
+
+    void empty_base(BaseImpl&& other)
+    {
+        BaseImpl mover(std::move(other));
+        EXPECT_EQ(nullptr, other.get());
+        EXPECT_EQ(nullptr, other.get_event().get());
+        EXPECT_FALSE(other.get_prepare());
+
+        expect_base_destruct(mover.get_event(), mover.get());
+    }
+
+    void expect_base_destruct(const Event& event, sd_event_source* source)
+    {
+        {
+            testing::InSequence seq;
+            EXPECT_CALL(mock, sd_event_source_set_enabled(source, SD_EVENT_OFF))
+                .WillOnce(Return(0));
+            EXPECT_CALL(mock, sd_event_source_unref(source))
+                .WillOnce(Return(nullptr));
+        }
+        EXPECT_CALL(mock, sd_event_unref(event.get()))
             .WillOnce(Return(nullptr));
-        event.reset();
     }
 };
 
@@ -70,15 +117,7 @@
     EXPECT_EQ(expected_event, source.get_event().get());
     EXPECT_FALSE(source.get_prepare());
 
-    {
-        testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-            .WillOnce(Return(nullptr));
-    }
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
+    expect_base_destruct(*event, expected_source);
 }
 
 TEST_F(BaseTest, NewBaseNoRef)
@@ -91,220 +130,99 @@
     EXPECT_EQ(expected_event, source.get_event().get());
     EXPECT_FALSE(source.get_prepare());
 
-    {
-        testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-            .WillOnce(Return(nullptr));
-    }
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
-}
-
-TEST_F(BaseTest, NoSource)
-{
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(Return(expected_event));
-    BaseImpl source(*event, nullptr, std::false_type());
-    EXPECT_EQ(nullptr, source.get());
-    EXPECT_NE(event.get(), &source.get_event());
-    EXPECT_EQ(expected_event, source.get_event().get());
-    EXPECT_FALSE(source.get_prepare());
-
-    EXPECT_CALL(mock, sd_event_source_unref(nullptr)).WillOnce(Return(nullptr));
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
+    expect_base_destruct(*event, expected_source);
 }
 
 TEST_F(BaseTest, MoveConstruct)
 {
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(Return(expected_event));
-    BaseImpl source(*event, expected_source, std::false_type());
-    EXPECT_EQ(expected_source, source.get());
-    EXPECT_EQ(expected_event, source.get_event().get());
-    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
-        .WillOnce(Return(0));
-    source.set_prepare([](Base&) {});
-    EXPECT_TRUE(source.get_prepare());
+    std::unique_ptr<BaseImpl> source1 = make_base(*event, expected_source);
+    set_prepare_placeholder(*source1);
 
-    BaseImpl source2(std::move(source));
-    EXPECT_EQ(nullptr, source.get());
-    EXPECT_EQ(nullptr, source.get_event().get());
-    EXPECT_FALSE(source.get_prepare());
+    BaseImpl source2(std::move(*source1));
+    EXPECT_EQ(nullptr, source1->get());
+    EXPECT_EQ(nullptr, source1->get_event().get());
+    EXPECT_FALSE(source1->get_prepare());
     EXPECT_EQ(expected_source, source2.get());
     EXPECT_EQ(expected_event, source2.get_event().get());
     EXPECT_TRUE(source2.get_prepare());
 
-    {
-        testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-            .WillOnce(Return(nullptr));
-    }
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
+    expect_base_destruct(*event, expected_source);
 }
 
 TEST_F(BaseTest, MoveAssignSelf)
 {
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(Return(expected_event));
-    BaseImpl source(*event, expected_source, std::false_type());
-    EXPECT_EQ(expected_source, source.get());
-    EXPECT_EQ(expected_event, source.get_event().get());
-    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
-        .WillOnce(Return(0));
-    source.set_prepare([](Base&) {});
-    EXPECT_TRUE(source.get_prepare());
+    std::unique_ptr<BaseImpl> source1 = make_base(*event, expected_source);
+    set_prepare_placeholder(*source1);
 
-    source = std::move(source);
-    EXPECT_EQ(expected_source, source.get());
-    EXPECT_EQ(expected_event, source.get_event().get());
-    EXPECT_TRUE(source.get_prepare());
+    *source1 = std::move(*source1);
+    EXPECT_EQ(expected_source, source1->get());
+    EXPECT_EQ(expected_event, source1->get_event().get());
+    EXPECT_TRUE(source1->get_prepare());
 
-    {
-        testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-            .WillOnce(Return(nullptr));
-    }
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
+    expect_base_destruct(*event, expected_source);
 }
 
 TEST_F(BaseTest, MoveAssignEmpty)
 {
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(Return(expected_event));
-    BaseImpl source(*event, expected_source, std::false_type());
-    EXPECT_EQ(expected_source, source.get());
-    EXPECT_EQ(expected_event, source.get_event().get());
-    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
-        .WillOnce(Return(0));
-    source.set_prepare([](Base&) {});
-    EXPECT_TRUE(source.get_prepare());
+    std::unique_ptr<BaseImpl> source1 = make_base(*event, expected_source);
+    set_prepare_placeholder(*source1);
 
-    sd_event* const expected_event2 = reinterpret_cast<sd_event*>(1);
-    Event event2(expected_event2, std::false_type(), &mock);
-    EXPECT_CALL(mock, sd_event_ref(expected_event2))
-        .WillOnce(Return(expected_event2));
-    BaseImpl source2(event2, nullptr, std::false_type());
-    EXPECT_EQ(nullptr, source2.get());
-    EXPECT_EQ(expected_event2, source2.get_event().get());
-    EXPECT_FALSE(source2.get_prepare());
-
-    EXPECT_CALL(mock, sd_event_unref(expected_event2))
-        .WillOnce(Return(nullptr));
-    EXPECT_CALL(mock, sd_event_source_unref(nullptr)).WillOnce(Return(nullptr));
-    source2 = std::move(source);
-    EXPECT_EQ(nullptr, source.get());
-    EXPECT_EQ(nullptr, source.get_event().get());
-    EXPECT_FALSE(source.get_prepare());
-    EXPECT_EQ(expected_source, source2.get());
-    EXPECT_EQ(expected_event, source2.get_event().get());
-    EXPECT_TRUE(source2.get_prepare());
+    std::unique_ptr<BaseImpl> source2 = make_base(*event, expected_source);
+    empty_base(std::move(*source2));
 
     {
         testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-            .WillOnce(Return(nullptr));
+        *source2 = std::move(*source1);
     }
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
-    EXPECT_CALL(mock, sd_event_unref(expected_event2))
-        .WillOnce(Return(nullptr));
+    EXPECT_EQ(nullptr, source1->get());
+    EXPECT_EQ(nullptr, source1->get_event().get());
+    EXPECT_FALSE(source1->get_prepare());
+    EXPECT_EQ(expected_source, source2->get());
+    EXPECT_EQ(expected_event, source2->get_event().get());
+    EXPECT_TRUE(source2->get_prepare());
+
+    // Make sure source1 is deleted to ensure it isn't holding a reference
+    source1.reset();
+    expect_base_destruct(*event, expected_source);
 }
 
 TEST_F(BaseTest, MoveAssignExisting)
 {
-    EXPECT_CALL(mock, sd_event_ref(expected_event))
-        .WillOnce(Return(expected_event));
-    BaseImpl source(*event, expected_source, std::false_type());
-    EXPECT_EQ(expected_source, source.get());
-    EXPECT_EQ(expected_event, source.get_event().get());
-    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source, testing::_))
-        .WillOnce(Return(0));
-    source.set_prepare([](Base&) {});
-    EXPECT_TRUE(source.get_prepare());
-
-    sd_event* const expected_event2 = reinterpret_cast<sd_event*>(1);
     sd_event_source* const expected_source2 =
-        reinterpret_cast<sd_event_source*>(2);
-    Event event2(expected_event2, std::false_type(), &mock);
-    EXPECT_CALL(mock, sd_event_ref(expected_event2))
-        .WillOnce(Return(expected_event2));
-    BaseImpl source2(event2, expected_source2, std::false_type());
-    EXPECT_EQ(expected_source2, source2.get());
-    EXPECT_EQ(expected_event2, source2.get_event().get());
-    EXPECT_CALL(mock, sd_event_source_set_prepare(expected_source2, testing::_))
-        .WillOnce(Return(0));
-    source2.set_prepare([](Base&) {});
-    EXPECT_TRUE(source2.get_prepare());
+        reinterpret_cast<sd_event_source*>(3456);
+    sd_event* const expected_event2 = reinterpret_cast<sd_event*>(4567);
+
+    std::unique_ptr<BaseImpl> source1 = make_base(*event, expected_source);
+    set_prepare_placeholder(*source1);
+
+    UniqueEvent event2 = make_event(expected_event2);
+    std::unique_ptr<BaseImpl> source2 = make_base(*event2, expected_source2);
 
     {
-        testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source2, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source2))
-            .WillOnce(Return(nullptr));
+        expect_base_destruct(*event2, expected_source2);
+        *source2 = std::move(*source1);
     }
-    EXPECT_CALL(mock, sd_event_unref(expected_event2))
-        .WillOnce(Return(nullptr));
-    source2 = std::move(source);
-    EXPECT_EQ(nullptr, source.get());
-    EXPECT_EQ(nullptr, source.get_event().get());
-    EXPECT_FALSE(source.get_prepare());
-    EXPECT_EQ(expected_source, source2.get());
-    EXPECT_EQ(expected_event, source2.get_event().get());
-    EXPECT_TRUE(source2.get_prepare());
+    EXPECT_EQ(nullptr, source1->get());
+    EXPECT_EQ(nullptr, source1->get_event().get());
+    EXPECT_FALSE(source1->get_prepare());
+    EXPECT_EQ(expected_source, source2->get());
+    EXPECT_EQ(expected_event, source2->get_event().get());
+    EXPECT_TRUE(source2->get_prepare());
 
-    {
-        testing::InSequence seq;
-        EXPECT_CALL(mock,
-                    sd_event_source_set_enabled(expected_source, SD_EVENT_OFF))
-            .WillOnce(Return(0));
-        EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-            .WillOnce(Return(nullptr));
-    }
-    EXPECT_CALL(mock, sd_event_unref(expected_event)).WillOnce(Return(nullptr));
-    EXPECT_CALL(mock, sd_event_unref(expected_event2))
-        .WillOnce(Return(nullptr));
+    // Make sure source1 is deleted to ensure it isn't holding a reference
+    source1.reset();
+    expect_base_destruct(*event, expected_source);
 }
 
 class BaseMethodTest : public BaseTest
 {
   protected:
-    std::unique_ptr<BaseImpl> base;
+    std::unique_ptr<BaseImpl> base = make_base(*event, expected_source);
 
-    void SetUp() override
+    void TearDown()
     {
-        BaseTest::SetUp();
-        EXPECT_CALL(mock, sd_event_ref(expected_event))
-            .WillOnce(Return(expected_event));
-        base = std::make_unique<BaseImpl>(*event, expected_source,
-                                          std::false_type());
-    }
-
-    void TearDown() override
-    {
-        {
-            testing::InSequence seq;
-            EXPECT_CALL(mock, sd_event_source_set_enabled(expected_source,
-                                                          SD_EVENT_OFF))
-                .WillOnce(Return(0));
-            EXPECT_CALL(mock, sd_event_source_unref(expected_source))
-                .WillOnce(Return(nullptr));
-        }
-        EXPECT_CALL(mock, sd_event_unref(expected_event))
-            .WillOnce(Return(nullptr));
+        expect_base_destruct(base->get_event(), base->get());
         base.reset();
-        BaseTest::TearDown();
     }
 };