blob: b4a6fd32cebb56f73cfa8e19b677e5cb4650ad44 [file] [log] [blame]
#include "dbus_environment.hpp"
#include "helpers.hpp"
#include "mocks/clock_mock.hpp"
#include "mocks/sensor_mock.hpp"
#include "mocks/trigger_action_mock.hpp"
#include "on_change_threshold.hpp"
#include "utils/conv_container.hpp"
#include <gmock/gmock.h>
using namespace testing;
using namespace std::chrono_literals;
class TestOnChangeThreshold : public Test
{
public:
std::vector<std::shared_ptr<SensorMock>> sensorMocks = {
std::make_shared<NiceMock<SensorMock>>(),
std::make_shared<NiceMock<SensorMock>>()};
std::vector<std::string> sensorNames = {"Sensor1", "Sensor2"};
std::unique_ptr<TriggerActionMock> actionMockPtr =
std::make_unique<StrictMock<TriggerActionMock>>();
TriggerActionMock& actionMock = *actionMockPtr;
std::shared_ptr<OnChangeThreshold> sut;
std::string triggerId = "MyTrigger";
std::unique_ptr<NiceMock<ClockMock>> clockMockPtr =
std::make_unique<NiceMock<ClockMock>>();
void SetUp() override
{
std::vector<std::unique_ptr<interfaces::TriggerAction>> actions;
actions.push_back(std::move(actionMockPtr));
for (size_t idx = 0; idx < sensorMocks.size(); idx++)
{
ON_CALL(*sensorMocks.at(idx), getName())
.WillByDefault(Return(sensorNames[idx]));
}
sut = std::make_shared<OnChangeThreshold>(
triggerId,
utils::convContainer<std::shared_ptr<interfaces::Sensor>>(
sensorMocks),
std::move(actions), std::move(clockMockPtr));
}
};
TEST_F(TestOnChangeThreshold, initializeThresholdExpectAllSensorsAreRegistered)
{
for (auto& sensor : sensorMocks)
{
EXPECT_CALL(*sensor,
registerForUpdates(Truly([sut = sut.get()](const auto& x) {
return x.lock().get() == sut;
})));
}
sut->initialize();
}
TEST_F(TestOnChangeThreshold, thresholdIsNotInitializeExpectNoActionCommit)
{
EXPECT_CALL(actionMock, commit(_, _, _, _, _)).Times(0);
}
TEST_F(TestOnChangeThreshold, getLabeledParamsReturnsCorrectly)
{
LabeledThresholdParam expected = std::monostate();
EXPECT_EQ(sut->getThresholdParam(), expected);
}
TEST_F(TestOnChangeThreshold, firstReadingDoesNoActionCommit)
{
EXPECT_CALL(actionMock, commit(_, _, _, _, _)).Times(0);
sut->initialize();
sut->sensorUpdated(*sensorMocks.front(), 0ms, 42);
}
struct OnChangeParams
{
using UpdateParams = std::tuple<size_t, double>;
using ExpectedParams = std::tuple<size_t, double>;
OnChangeParams& Updates(std::vector<UpdateParams> val)
{
updates = std::move(val);
return *this;
}
OnChangeParams& Expected(std::vector<ExpectedParams> val)
{
expected = std::move(val);
return *this;
}
friend void PrintTo(const OnChangeParams& o, std::ostream* os)
{
*os << "{ Updates: [ ";
for (const auto& [index, value] : o.updates)
{
*os << "{ SensorIndex: " << index << ", Value: " << value << " }, ";
}
*os << " ] Expected: [ ";
for (const auto& [index, value] : o.expected)
{
*os << "{ SensorIndex: " << index << ", Value: " << value << " }, ";
}
*os << " ] }";
}
std::vector<UpdateParams> updates;
std::vector<ExpectedParams> expected;
};
class TestOnChangeThresholdUpdates :
public TestOnChangeThreshold,
public WithParamInterface<OnChangeParams>
{};
INSTANTIATE_TEST_SUITE_P(
_, TestOnChangeThresholdUpdates,
Values(OnChangeParams().Updates({{0, 80.0}}).Expected({{0, 80.0}}),
OnChangeParams()
.Updates({{0, 80.0}, {1, 81.0}})
.Expected({{0, 80.0}, {1, 81.0}}),
OnChangeParams()
.Updates({{0, 80.0}, {0, 90.0}})
.Expected({{0, 80.0}, {0, 90.0}}),
OnChangeParams()
.Updates({{0, 80.0}, {1, 90.0}, {0, 90.0}})
.Expected({{0, 80.0}, {1, 90.0}, {0, 90.0}}),
OnChangeParams()
.Updates({{0, 80.0}, {1, 80.0}, {1, 90.0}, {0, 90.0}})
.Expected({{0, 80.0}, {1, 80.0}, {1, 90.0}, {0, 90.0}})));
TEST_P(TestOnChangeThresholdUpdates, senorsIsUpdatedMultipleTimes)
{
InSequence seq;
for (const auto& [index, value] : GetParam().expected)
{
EXPECT_CALL(actionMock,
commit(triggerId, Eq(std::nullopt), sensorNames[index], _,
TriggerValue(value)));
}
sut->initialize();
// First reading will be skipped
sut->sensorUpdated(*sensorMocks.front(), 0ms, 42);
for (const auto& [index, value] : GetParam().updates)
{
sut->sensorUpdated(*sensorMocks[index], 42ms, value);
}
}