* Evaluates the rule, starting with the root boolean operator and recursing down * All evaluation is done within the context of an almanac * @return {Promise(RuleResult)} rule evaluation result
(almanac)
| 194 | * @return {Promise(RuleResult)} rule evaluation result |
| 195 | */ |
| 196 | evaluate (almanac) { |
| 197 | const ruleResult = new RuleResult( |
| 198 | this.conditions, |
| 199 | this.ruleEvent, |
| 200 | this.priority, |
| 201 | this.name |
| 202 | ) |
| 203 | |
| 204 | /** |
| 205 | * Evaluates the rule conditions |
| 206 | * @param {Condition} condition - condition to evaluate |
| 207 | * @return {Promise(true|false)} - resolves with the result of the condition evaluation |
| 208 | */ |
| 209 | const evaluateCondition = (condition) => { |
| 210 | if (condition.isConditionReference()) { |
| 211 | return realize(condition) |
| 212 | } else if (condition.isBooleanOperator()) { |
| 213 | const subConditions = condition[condition.operator] |
| 214 | let comparisonPromise |
| 215 | if (condition.operator === 'all') { |
| 216 | comparisonPromise = all(subConditions) |
| 217 | } else if (condition.operator === 'any') { |
| 218 | comparisonPromise = any(subConditions) |
| 219 | } else { |
| 220 | comparisonPromise = not(subConditions) |
| 221 | } |
| 222 | // for booleans, rule passing is determined by the all/any/not result |
| 223 | return comparisonPromise.then((comparisonValue) => { |
| 224 | const passes = comparisonValue === true |
| 225 | condition.result = passes |
| 226 | return passes |
| 227 | }) |
| 228 | } else { |
| 229 | return condition |
| 230 | .evaluate(almanac, this.engine.operators) |
| 231 | .then((evaluationResult) => { |
| 232 | const passes = evaluationResult.result |
| 233 | condition.factResult = evaluationResult.leftHandSideValue |
| 234 | condition.result = passes |
| 235 | return passes |
| 236 | }) |
| 237 | } |
| 238 | } |
| 239 | |
| 240 | /** |
| 241 | * Evalutes an array of conditions, using an 'every' or 'some' array operation |
| 242 | * @param {Condition[]} conditions |
| 243 | * @param {string(every|some)} array method to call for determining result |
| 244 | * @return {Promise(boolean)} whether conditions evaluated truthy or falsey based on condition evaluation + method |
| 245 | */ |
| 246 | const evaluateConditions = (conditions, method) => { |
| 247 | if (!Array.isArray(conditions)) conditions = [conditions] |
| 248 | |
| 249 | return Promise.all( |
| 250 | conditions.map((condition) => evaluateCondition(condition)) |
| 251 | ).then((conditionResults) => { |
| 252 | debug('rule::evaluateConditions results', conditionResults) |
| 253 | return method.call(conditionResults, (result) => result === true) |
no outgoing calls
no test coverage detected