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}.*/
|
/*! Returns true, if all child evaluator conditions are true depending on the \l {Types::StateOperator}{StateOperator}.*/
|
||||||
bool StateEvaluator::evaluate() const
|
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()) {
|
if (m_stateDescriptor.isValid()) {
|
||||||
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(m_stateDescriptor.deviceId());
|
Device *device = NymeaCore::instance()->deviceManager()->findConfiguredDevice(m_stateDescriptor.deviceId());
|
||||||
if (!device) {
|
if (!device) {
|
||||||
qCWarning(dcRuleEngine) << "Device not existing!";
|
qCWarning(dcRuleEngine) << "Device not existing!";
|
||||||
return false;
|
descriptorMatching = false;
|
||||||
}
|
} else {
|
||||||
if (!device->hasState(m_stateDescriptor.stateTypeId())) {
|
DeviceClass deviceClass = NymeaCore::instance()->deviceManager()->findDeviceClass(device->deviceClassId());
|
||||||
qCWarning(dcRuleEngine) << "Device found, but it does not appear to have such a state!";
|
if (!device->hasState(m_stateDescriptor.stateTypeId())) {
|
||||||
return false;
|
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
|
if (m_stateDescriptor != device->state(m_stateDescriptor.stateTypeId())) {
|
||||||
return false;
|
// 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_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) {
|
foreach (const StateEvaluator &stateEvaluator, m_childEvaluators) {
|
||||||
if (stateEvaluator.evaluate()) {
|
if (stateEvaluator.evaluate()) {
|
||||||
|
qCDebug(dcRuleEngineDebug()) << "Child evaluator evaluated to true. Operator is OR => Evaluation result: true";
|
||||||
return 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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -300,7 +300,7 @@ void DeviceClass::setBasicTags(const QList<DeviceClass::BasicTag> &basicTags)
|
|||||||
|
|
||||||
/*! Returns the statesTypes of this DeviceClass. \{Device}{Devices} created
|
/*! Returns the statesTypes of this DeviceClass. \{Device}{Devices} created
|
||||||
from this \l{DeviceClass} must have their states matching to this template. */
|
from this \l{DeviceClass} must have their states matching to this template. */
|
||||||
QList<StateType> DeviceClass::stateTypes() const
|
StateTypes DeviceClass::stateTypes() const
|
||||||
{
|
{
|
||||||
return m_stateTypes;
|
return m_stateTypes;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -147,7 +147,7 @@ public:
|
|||||||
QList<BasicTag> basicTags() const;
|
QList<BasicTag> basicTags() const;
|
||||||
void setBasicTags(const QList<BasicTag> &basicTags);
|
void setBasicTags(const QList<BasicTag> &basicTags);
|
||||||
|
|
||||||
QList<StateType> stateTypes() const;
|
StateTypes stateTypes() const;
|
||||||
StateType getStateType(const StateTypeId &stateTypeId);
|
StateType getStateType(const StateTypeId &stateTypeId);
|
||||||
void setStateTypes(const QList<StateType> &stateTypes);
|
void setStateTypes(const QList<StateType> &stateTypes);
|
||||||
bool hasStateType(const StateTypeId &stateTypeId);
|
bool hasStateType(const StateTypeId &stateTypeId);
|
||||||
|
|||||||
@ -63,10 +63,6 @@ DECLARE_TYPE_ID(PairingTransaction)
|
|||||||
class LIBNYMEA_EXPORT Types
|
class LIBNYMEA_EXPORT Types
|
||||||
{
|
{
|
||||||
Q_GADGET
|
Q_GADGET
|
||||||
Q_ENUMS(InputType)
|
|
||||||
Q_ENUMS(Unit)
|
|
||||||
Q_ENUMS(StateOperator)
|
|
||||||
Q_ENUMS(ValueOperator)
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
enum InputType {
|
enum InputType {
|
||||||
@ -81,6 +77,7 @@ public:
|
|||||||
InputTypeUrl,
|
InputTypeUrl,
|
||||||
InputTypeMacAddress
|
InputTypeMacAddress
|
||||||
};
|
};
|
||||||
|
Q_ENUM(InputType)
|
||||||
|
|
||||||
enum Unit {
|
enum Unit {
|
||||||
UnitNone,
|
UnitNone,
|
||||||
@ -134,6 +131,7 @@ public:
|
|||||||
UnitVoltAmpereReactive,
|
UnitVoltAmpereReactive,
|
||||||
UnitAmpereHour
|
UnitAmpereHour
|
||||||
};
|
};
|
||||||
|
Q_ENUM(Unit)
|
||||||
|
|
||||||
enum ValueOperator {
|
enum ValueOperator {
|
||||||
ValueOperatorEquals,
|
ValueOperatorEquals,
|
||||||
@ -143,10 +141,13 @@ public:
|
|||||||
ValueOperatorLessOrEqual,
|
ValueOperatorLessOrEqual,
|
||||||
ValueOperatorGreaterOrEqual
|
ValueOperatorGreaterOrEqual
|
||||||
};
|
};
|
||||||
|
Q_ENUM(ValueOperator)
|
||||||
|
|
||||||
enum StateOperator {
|
enum StateOperator {
|
||||||
StateOperatorAnd,
|
StateOperatorAnd,
|
||||||
StateOperatorOr
|
StateOperatorOr
|
||||||
};
|
};
|
||||||
|
Q_ENUM(StateOperator)
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -86,6 +86,9 @@ private slots:
|
|||||||
void testStateEvaluator2_data();
|
void testStateEvaluator2_data();
|
||||||
void testStateEvaluator2();
|
void testStateEvaluator2();
|
||||||
|
|
||||||
|
void testStateEvaluator3_data();
|
||||||
|
void testStateEvaluator3();
|
||||||
|
|
||||||
void testChildEvaluator_data();
|
void testChildEvaluator_data();
|
||||||
void testChildEvaluator();
|
void testChildEvaluator();
|
||||||
|
|
||||||
@ -1647,6 +1650,34 @@ void TestRules::testStateEvaluator2()
|
|||||||
QVERIFY2(mainEvaluator.evaluate() == shouldMatch, shouldMatch ? "State should match" : "State shouldn't match");
|
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()
|
void TestRules::testChildEvaluator_data()
|
||||||
{
|
{
|
||||||
cleanup();
|
cleanup();
|
||||||
|
|||||||
Reference in New Issue
Block a user