1f763c9e3SSzymon Dompke #include "dbus_environment.hpp" 2f763c9e3SSzymon Dompke #include "helpers.hpp" 3f763c9e3SSzymon Dompke #include "mocks/sensor_mock.hpp" 4f763c9e3SSzymon Dompke #include "mocks/trigger_action_mock.hpp" 5f763c9e3SSzymon Dompke #include "on_change_threshold.hpp" 6f763c9e3SSzymon Dompke #include "utils/conv_container.hpp" 7f763c9e3SSzymon Dompke 8f763c9e3SSzymon Dompke #include <gmock/gmock.h> 9f763c9e3SSzymon Dompke 10f763c9e3SSzymon Dompke using namespace testing; 11f763c9e3SSzymon Dompke using namespace std::chrono_literals; 12f763c9e3SSzymon Dompke 13f763c9e3SSzymon Dompke class TestOnChangeThreshold : public Test 14f763c9e3SSzymon Dompke { 15f763c9e3SSzymon Dompke public: 16f763c9e3SSzymon Dompke std::vector<std::shared_ptr<SensorMock>> sensorMocks = { 17f763c9e3SSzymon Dompke std::make_shared<NiceMock<SensorMock>>(), 18f763c9e3SSzymon Dompke std::make_shared<NiceMock<SensorMock>>()}; 19f763c9e3SSzymon Dompke std::vector<std::string> sensorNames = {"Sensor1", "Sensor2"}; 20f763c9e3SSzymon Dompke std::unique_ptr<TriggerActionMock> actionMockPtr = 21f763c9e3SSzymon Dompke std::make_unique<StrictMock<TriggerActionMock>>(); 22f763c9e3SSzymon Dompke TriggerActionMock& actionMock = *actionMockPtr; 23f763c9e3SSzymon Dompke std::shared_ptr<OnChangeThreshold> sut; 24f763c9e3SSzymon Dompke 25f763c9e3SSzymon Dompke void SetUp() override 26f763c9e3SSzymon Dompke { 27f763c9e3SSzymon Dompke std::vector<std::unique_ptr<interfaces::TriggerAction>> actions; 28f763c9e3SSzymon Dompke actions.push_back(std::move(actionMockPtr)); 29f763c9e3SSzymon Dompke 30f763c9e3SSzymon Dompke sut = std::make_shared<OnChangeThreshold>( 31f763c9e3SSzymon Dompke utils::convContainer<std::shared_ptr<interfaces::Sensor>>( 32f763c9e3SSzymon Dompke sensorMocks), 33f763c9e3SSzymon Dompke sensorNames, std::move(actions)); 34f763c9e3SSzymon Dompke } 35f763c9e3SSzymon Dompke }; 36f763c9e3SSzymon Dompke 37f763c9e3SSzymon Dompke TEST_F(TestOnChangeThreshold, initializeThresholdExpectAllSensorsAreRegistered) 38f763c9e3SSzymon Dompke { 39f763c9e3SSzymon Dompke for (auto& sensor : sensorMocks) 40f763c9e3SSzymon Dompke { 41f763c9e3SSzymon Dompke EXPECT_CALL(*sensor, 42f763c9e3SSzymon Dompke registerForUpdates(Truly([sut = sut.get()](const auto& x) { 43f763c9e3SSzymon Dompke return x.lock().get() == sut; 44f763c9e3SSzymon Dompke }))); 45f763c9e3SSzymon Dompke } 46f763c9e3SSzymon Dompke 47f763c9e3SSzymon Dompke sut->initialize(); 48f763c9e3SSzymon Dompke } 49f763c9e3SSzymon Dompke 50f763c9e3SSzymon Dompke TEST_F(TestOnChangeThreshold, thresholdIsNotInitializeExpectNoActionCommit) 51f763c9e3SSzymon Dompke { 52f763c9e3SSzymon Dompke EXPECT_CALL(actionMock, commit(_, _, _)).Times(0); 53f763c9e3SSzymon Dompke } 54f763c9e3SSzymon Dompke 55f763c9e3SSzymon Dompke struct OnChangeParams 56f763c9e3SSzymon Dompke { 57*51f0fd50SKrzysztof Grobelny using UpdateParams = std::tuple<size_t, Milliseconds, double>; 58*51f0fd50SKrzysztof Grobelny using ExpectedParams = std::tuple<size_t, Milliseconds, double>; 59f763c9e3SSzymon Dompke 60f763c9e3SSzymon Dompke OnChangeParams& Updates(std::vector<UpdateParams> val) 61f763c9e3SSzymon Dompke { 62f763c9e3SSzymon Dompke updates = std::move(val); 63f763c9e3SSzymon Dompke return *this; 64f763c9e3SSzymon Dompke } 65f763c9e3SSzymon Dompke 66f763c9e3SSzymon Dompke OnChangeParams& Expected(std::vector<ExpectedParams> val) 67f763c9e3SSzymon Dompke { 68f763c9e3SSzymon Dompke expected = std::move(val); 69f763c9e3SSzymon Dompke return *this; 70f763c9e3SSzymon Dompke } 71f763c9e3SSzymon Dompke 72f763c9e3SSzymon Dompke friend void PrintTo(const OnChangeParams& o, std::ostream* os) 73f763c9e3SSzymon Dompke { 74f763c9e3SSzymon Dompke *os << "{ Updates: "; 75f763c9e3SSzymon Dompke for (const auto& [index, timestamp, value] : o.updates) 76f763c9e3SSzymon Dompke { 77*51f0fd50SKrzysztof Grobelny *os << "{ SensorIndex: " << index 78*51f0fd50SKrzysztof Grobelny << ", Timestamp: " << timestamp.count() << ", Value: " << value 79*51f0fd50SKrzysztof Grobelny << " }, "; 80f763c9e3SSzymon Dompke } 81f763c9e3SSzymon Dompke *os << "Expected: "; 82f763c9e3SSzymon Dompke for (const auto& [index, timestamp, value] : o.expected) 83f763c9e3SSzymon Dompke { 84*51f0fd50SKrzysztof Grobelny *os << "{ SensorIndex: " << index 85*51f0fd50SKrzysztof Grobelny << ", Timestamp: " << timestamp.count() << ", Value: " << value 86*51f0fd50SKrzysztof Grobelny << " }, "; 87f763c9e3SSzymon Dompke } 88f763c9e3SSzymon Dompke *os << " }"; 89f763c9e3SSzymon Dompke } 90f763c9e3SSzymon Dompke 91f763c9e3SSzymon Dompke std::vector<UpdateParams> updates; 92f763c9e3SSzymon Dompke std::vector<ExpectedParams> expected; 93f763c9e3SSzymon Dompke }; 94f763c9e3SSzymon Dompke 95f763c9e3SSzymon Dompke class TestOnChangeThresholdUpdates : 96f763c9e3SSzymon Dompke public TestOnChangeThreshold, 97f763c9e3SSzymon Dompke public WithParamInterface<OnChangeParams> 98f763c9e3SSzymon Dompke {}; 99f763c9e3SSzymon Dompke 100f763c9e3SSzymon Dompke INSTANTIATE_TEST_SUITE_P( 101f763c9e3SSzymon Dompke _, TestOnChangeThresholdUpdates, 102f763c9e3SSzymon Dompke Values( 103*51f0fd50SKrzysztof Grobelny OnChangeParams().Updates({{0, 1ms, 80.0}}).Expected({{0, 1ms, 80.0}}), 104f763c9e3SSzymon Dompke OnChangeParams() 105*51f0fd50SKrzysztof Grobelny .Updates({{0, 1ms, 80.0}, {1, 2ms, 81.0}}) 106*51f0fd50SKrzysztof Grobelny .Expected({{0, 1ms, 80.0}, {1, 2ms, 81.0}}), 107f763c9e3SSzymon Dompke OnChangeParams() 108*51f0fd50SKrzysztof Grobelny .Updates({{0, 1ms, 80.0}, {0, 2ms, 90.0}}) 109*51f0fd50SKrzysztof Grobelny .Expected({{0, 1ms, 80.0}, {0, 2ms, 90.0}}), 110f763c9e3SSzymon Dompke OnChangeParams() 111*51f0fd50SKrzysztof Grobelny .Updates({{0, 1ms, 80.0}, {1, 2ms, 90.0}, {0, 3ms, 90.0}}) 112*51f0fd50SKrzysztof Grobelny .Expected({{0, 1ms, 80.0}, {1, 2ms, 90.0}, {0, 3ms, 90.0}}), 113f763c9e3SSzymon Dompke OnChangeParams() 114*51f0fd50SKrzysztof Grobelny .Updates({{0, 1ms, 80.0}, 115*51f0fd50SKrzysztof Grobelny {1, 2ms, 80.0}, 116*51f0fd50SKrzysztof Grobelny {1, 3ms, 90.0}, 117*51f0fd50SKrzysztof Grobelny {0, 4ms, 90.0}}) 118*51f0fd50SKrzysztof Grobelny .Expected({{0, 1ms, 80.0}, 119*51f0fd50SKrzysztof Grobelny {1, 2ms, 80.0}, 120*51f0fd50SKrzysztof Grobelny {1, 3ms, 90.0}, 121*51f0fd50SKrzysztof Grobelny {0, 4ms, 90.0}}))); 122f763c9e3SSzymon Dompke 123f763c9e3SSzymon Dompke TEST_P(TestOnChangeThresholdUpdates, senorsIsUpdatedMultipleTimes) 124f763c9e3SSzymon Dompke { 125f763c9e3SSzymon Dompke InSequence seq; 126f763c9e3SSzymon Dompke for (const auto& [index, timestamp, value] : GetParam().expected) 127f763c9e3SSzymon Dompke { 128f763c9e3SSzymon Dompke EXPECT_CALL(actionMock, commit(sensorNames[index], timestamp, value)); 129f763c9e3SSzymon Dompke } 130f763c9e3SSzymon Dompke 131f763c9e3SSzymon Dompke sut->initialize(); 132f763c9e3SSzymon Dompke for (const auto& [index, timestamp, value] : GetParam().updates) 133f763c9e3SSzymon Dompke { 134f763c9e3SSzymon Dompke sut->sensorUpdated(*sensorMocks[index], timestamp, value); 135f763c9e3SSzymon Dompke } 136f763c9e3SSzymon Dompke } 137