| #include <gmock/gmock.h> |
| #include <gtest/gtest.h> |
| #include <sdeventplus/internal/sdref.hpp> |
| #include <sdeventplus/test/sdevent.hpp> |
| #include <systemd/sd-event.h> |
| #include <type_traits> |
| #include <utility> |
| |
| namespace sdeventplus |
| { |
| namespace internal |
| { |
| namespace |
| { |
| |
| class SdRefTest : public testing::Test |
| { |
| protected: |
| sd_event* const expected_event = reinterpret_cast<sd_event*>(1234); |
| sd_event* const expected_event2 = reinterpret_cast<sd_event*>(2345); |
| testing::StrictMock<test::SdEventMock> mock; |
| testing::StrictMock<test::SdEventMock> mock2; |
| }; |
| |
| TEST_F(SdRefTest, ConstructRef) |
| { |
| EXPECT_CALL(mock, sd_event_ref(expected_event)) |
| .WillOnce(testing::Return(expected_event)); |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, ConstructNoRef) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, CopyConstruct) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| |
| EXPECT_CALL(mock, sd_event_ref(expected_event)) |
| .WillOnce(testing::Return(expected_event)); |
| SdRef<sd_event> event2(event); |
| EXPECT_EQ(expected_event, event2.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .Times(2) |
| .WillRepeatedly(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, MoveConstruct) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| |
| SdRef<sd_event> event2(std::move(event)); |
| EXPECT_EQ(expected_event, event2.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, CopyAssignOverValid) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock2); |
| EXPECT_EQ(expected_event2, event2.get()); |
| |
| EXPECT_CALL(mock2, sd_event_unref(expected_event2)) |
| .WillOnce(testing::Return(nullptr)); |
| EXPECT_CALL(mock, sd_event_ref(expected_event)) |
| .WillOnce(testing::Return(expected_event)); |
| event2 = event; |
| EXPECT_EQ(expected_event, event2.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .Times(2) |
| .WillRepeatedly(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, CopyAssignOverMoved) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock2); |
| EXPECT_EQ(expected_event2, event2.get()); |
| { |
| SdRef<sd_event> event_mover(std::move(event2)); |
| EXPECT_EQ(expected_event2, event_mover.get()); |
| |
| EXPECT_CALL(mock2, sd_event_unref(expected_event2)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| EXPECT_CALL(mock, sd_event_ref(expected_event)) |
| .WillOnce(testing::Return(expected_event)); |
| event2 = event; |
| EXPECT_EQ(expected_event, event2.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .Times(2) |
| .WillRepeatedly(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, CopySelf) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| |
| event = event; |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, MoveAssignOverValid) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock2); |
| EXPECT_EQ(expected_event2, event2.get()); |
| |
| EXPECT_CALL(mock2, sd_event_unref(expected_event2)) |
| .WillOnce(testing::Return(nullptr)); |
| event2 = std::move(event); |
| EXPECT_EQ(expected_event, event2.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, MoveAssignOverMoved) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| SdRef<sd_event> event2(expected_event2, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock2); |
| EXPECT_EQ(expected_event2, event2.get()); |
| { |
| SdRef<sd_event> event_mover(std::move(event2)); |
| EXPECT_EQ(expected_event2, event_mover.get()); |
| |
| EXPECT_CALL(mock2, sd_event_unref(expected_event2)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| event2 = std::move(event); |
| EXPECT_EQ(expected_event, event2.get()); |
| |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| TEST_F(SdRefTest, MoveSelf) |
| { |
| SdRef<sd_event> event(expected_event, &SdEvent::sd_event_ref, |
| &SdEvent::sd_event_unref, std::false_type(), &mock); |
| EXPECT_EQ(expected_event, event.get()); |
| event = std::move(event); |
| EXPECT_CALL(mock, sd_event_unref(expected_event)) |
| .WillOnce(testing::Return(nullptr)); |
| } |
| |
| } // namespace |
| } // namespace internal |
| } // namespace sdeventplus |