fix stateevaluator bug where it would not properly use the OR operator
This commit is contained in:
parent
84854868ea
commit
0f46245230
@ -99,28 +99,44 @@ void StateEvaluator::setOperatorType(Types::StateOperator operatorType)
|
||||
/*! Returns true, if all child evaluator conditions are true depending on the \l {Types::StateOperator}{StateOperator}.*/
|
||||
bool StateEvaluator::evaluate() const
|
||||
{
|
||||
qCDebug(dcRuleEngineDebug()) << "Evaluating StateEvaluator." << this << "Operator type" << m_operatorType << "Valid descriptor:" << m_stateDescriptor.isValid() << "Childs:" << m_childEvaluators.count();
|
||||
bool descriptorMatching = true;
|
||||
if (m_stateDescriptor.isValid()) {
|
||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(m_stateDescriptor.deviceId());
|
||||
if (!device) {
|
||||
qCWarning(dcRuleEngine) << "Device not existing!";
|
||||
return false;
|
||||
}
|
||||
if (!device->hasState(m_stateDescriptor.stateTypeId())) {
|
||||
qCWarning(dcRuleEngine) << "Device found, but it does not appear to have such a state!";
|
||||
return false;
|
||||
}
|
||||
if (m_stateDescriptor != device->state(m_stateDescriptor.stateTypeId())) {
|
||||
// state not matching
|
||||
return false;
|
||||
descriptorMatching = false;
|
||||
} else {
|
||||
DeviceClass deviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId());
|
||||
if (!device->hasState(m_stateDescriptor.stateTypeId())) {
|
||||
qCWarning(dcRuleEngine) << "Device found, but it does not appear to have such a state!";
|
||||
descriptorMatching = false;
|
||||
}
|
||||
if (m_stateDescriptor != device->state(m_stateDescriptor.stateTypeId())) {
|
||||
// state not matching
|
||||
qCDebug(dcRuleEngineDebug()) << "State" << device->name() << deviceClass.stateTypes().findById(m_stateDescriptor.stateTypeId()).name() << "not matching:" << m_stateDescriptor.stateValue() << "!=" << device->stateValue(m_stateDescriptor.stateTypeId());
|
||||
descriptorMatching = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (m_operatorType == Types::StateOperatorOr) {
|
||||
if (m_stateDescriptor.isValid() && descriptorMatching) {
|
||||
qCDebug(dcRuleEngineDebug()) << "Descriptor is matching. Operator is OR => Evaluation result: true";
|
||||
return true;
|
||||
}
|
||||
foreach (const StateEvaluator &stateEvaluator, m_childEvaluators) {
|
||||
if (stateEvaluator.evaluate()) {
|
||||
qCDebug(dcRuleEngineDebug()) << "Child evaluator evaluated to true. Operator is OR => Evaluation result: true";
|
||||
return true;
|
||||
}
|
||||
}
|
||||
qCDebug(dcRuleEngineDebug()) << "No child evaluator evaluated to true => Evaluation result: false";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!descriptorMatching) {
|
||||
qCDebug(dcRuleEngineDebug()) << "Operator is AND => Evaluation result: false";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -300,7 +300,7 @@ void DeviceClass::setBasicTags(const QList<DeviceClass::BasicTag> &basicTags)
|
||||
|
||||
/*! Returns the statesTypes of this DeviceClass. \{Device}{Devices} created
|
||||
from this \l{DeviceClass} must have their states matching to this template. */
|
||||
QList<StateType> DeviceClass::stateTypes() const
|
||||
StateTypes DeviceClass::stateTypes() const
|
||||
{
|
||||
return m_stateTypes;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ public:
|
||||
QList<BasicTag> basicTags() const;
|
||||
void setBasicTags(const QList<BasicTag> &basicTags);
|
||||
|
||||
QList<StateType> stateTypes() const;
|
||||
StateTypes stateTypes() const;
|
||||
StateType getStateType(const StateTypeId &stateTypeId);
|
||||
void setStateTypes(const QList<StateType> &stateTypes);
|
||||
bool hasStateType(const StateTypeId &stateTypeId);
|
||||
|
||||
@ -63,10 +63,6 @@ DECLARE_TYPE_ID(PairingTransaction)
|
||||
class LIBNYMEA_EXPORT Types
|
||||
{
|
||||
Q_GADGET
|
||||
Q_ENUMS(InputType)
|
||||
Q_ENUMS(Unit)
|
||||
Q_ENUMS(StateOperator)
|
||||
Q_ENUMS(ValueOperator)
|
||||
|
||||
public:
|
||||
enum InputType {
|
||||
@ -81,6 +77,7 @@ public:
|
||||
InputTypeUrl,
|
||||
InputTypeMacAddress
|
||||
};
|
||||
Q_ENUM(InputType)
|
||||
|
||||
enum Unit {
|
||||
UnitNone,
|
||||
@ -134,6 +131,7 @@ public:
|
||||
UnitVoltAmpereReactive,
|
||||
UnitAmpereHour
|
||||
};
|
||||
Q_ENUM(Unit)
|
||||
|
||||
enum ValueOperator {
|
||||
ValueOperatorEquals,
|
||||
@ -143,10 +141,13 @@ public:
|
||||
ValueOperatorLessOrEqual,
|
||||
ValueOperatorGreaterOrEqual
|
||||
};
|
||||
Q_ENUM(ValueOperator)
|
||||
|
||||
enum StateOperator {
|
||||
StateOperatorAnd,
|
||||
StateOperatorOr
|
||||
};
|
||||
Q_ENUM(StateOperator)
|
||||
|
||||
};
|
||||
|
||||
|
||||
@ -86,6 +86,9 @@ private slots:
|
||||
void testStateEvaluator2_data();
|
||||
void testStateEvaluator2();
|
||||
|
||||
void testStateEvaluator3_data();
|
||||
void testStateEvaluator3();
|
||||
|
||||
void testChildEvaluator_data();
|
||||
void testChildEvaluator();
|
||||
|
||||
@ -1647,6 +1650,34 @@ void TestRules::testStateEvaluator2()
|
||||
QVERIFY2(mainEvaluator.evaluate() == shouldMatch, shouldMatch ? "State should match" : "State shouldn't match");
|
||||
}
|
||||
|
||||
void TestRules::testStateEvaluator3_data()
|
||||
{
|
||||
testStateEvaluator2_data();
|
||||
}
|
||||
|
||||
void TestRules::testStateEvaluator3()
|
||||
{
|
||||
QFETCH(int, intValue);
|
||||
QFETCH(Types::ValueOperator, intOperator);
|
||||
QFETCH(bool, boolValue);
|
||||
QFETCH(Types::ValueOperator, boolOperator);
|
||||
QFETCH(Types::StateOperator, stateOperator);
|
||||
QFETCH(bool, shouldMatch);
|
||||
|
||||
StateDescriptor descriptor1(mockIntStateId, m_mockDeviceId, intValue, intOperator);
|
||||
StateEvaluator childEvaluator(descriptor1);
|
||||
|
||||
QList<StateEvaluator> childEvaluators;
|
||||
childEvaluators.append(childEvaluator);
|
||||
|
||||
StateDescriptor descriptor2(mockBoolStateId, m_mockDeviceId, boolValue, boolOperator);
|
||||
StateEvaluator mainEvaluator(descriptor2);
|
||||
mainEvaluator.setChildEvaluators(childEvaluators);
|
||||
mainEvaluator.setOperatorType(stateOperator);
|
||||
|
||||
QVERIFY2(mainEvaluator.evaluate() == shouldMatch, shouldMatch ? "State should match" : "State shouldn't match");
|
||||
}
|
||||
|
||||
void TestRules::testChildEvaluator_data()
|
||||
{
|
||||
cleanup();
|
||||
|
||||
Reference in New Issue
Block a user