Skip to content

Commit adcb2b6

Browse files
authored
Merge pull request #332 from RateGravity/named-conditions
Allow Named Conditions
2 parents 5f54101 + b31b902 commit adcb2b6

File tree

5 files changed

+69
-41
lines changed

5 files changed

+69
-41
lines changed

examples/02-nested-boolean-logic.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ async function start () {
3131
fact: 'personalFoulCount',
3232
operator: 'greaterThanInclusive',
3333
value: 5
34-
}]
34+
}],
35+
name: "short foul limit"
3536
}, {
3637
all: [{
3738
fact: 'gameDuration',
@@ -43,7 +44,8 @@ async function start () {
4344
operator: 'lessThan',
4445
value: 6
4546
}
46-
}]
47+
}],
48+
name: "long foul limit"
4749
}]
4850
},
4951
event: { // define the event to fire when the conditions evaluate truthy

src/condition.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ export default class Condition {
4444
if (this.priority) {
4545
props.priority = this.priority
4646
}
47+
if (this.name) {
48+
props.name = this.name
49+
}
4750
const oper = Condition.booleanOperator(this)
4851
if (oper) {
4952
if (Array.isArray(this[oper])) {

test/condition.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ function condition () {
1212
return {
1313
all: [{
1414
id: '6ed20017-375f-40c9-a1d2-6d7e0f4733c5',
15+
name: "team participation in form",
1516
fact: 'team_participation',
1617
operator: 'equal',
1718
value: 50,
@@ -29,6 +30,7 @@ describe('Condition', () => {
2930
expect(subject).to.have.property('operator')
3031
expect(subject).to.have.property('value')
3132
expect(subject).to.have.property('path')
33+
expect(subject).to.have.property('name');
3234
})
3335

3436
it('boolean conditions have properties', () => {

test/engine-event.test.js

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -25,15 +25,19 @@ describe('Engine: event', () => {
2525
*/
2626
function simpleSetup () {
2727
const conditions = {
28-
any: [{
29-
fact: 'age',
30-
operator: 'greaterThanInclusive',
31-
value: 21
32-
}, {
33-
fact: 'qualified',
34-
operator: 'equal',
35-
value: true
36-
}]
28+
any: [
29+
{
30+
name: 'over 21',
31+
fact: 'age',
32+
operator: 'greaterThanInclusive',
33+
value: 21
34+
},
35+
{
36+
fact: 'qualified',
37+
operator: 'equal',
38+
value: true
39+
}
40+
]
3741
}
3842
engine = engineFactory()
3943
const ruleOptions = { conditions, event, priority: 100 }
@@ -50,25 +54,32 @@ describe('Engine: event', () => {
5054
*/
5155
function advancedSetup () {
5256
const conditions = {
53-
any: [{
54-
fact: 'age',
55-
operator: 'greaterThanInclusive',
56-
value: 21
57-
}, {
58-
fact: 'qualified',
59-
operator: 'equal',
60-
value: true
61-
}, {
62-
all: [{
63-
fact: 'zipCode',
64-
operator: 'in',
65-
value: [80211, 80403]
66-
}, {
67-
fact: 'gender',
68-
operator: 'notEqual',
69-
value: 'female'
70-
}]
71-
}]
57+
any: [
58+
{
59+
fact: 'age',
60+
operator: 'greaterThanInclusive',
61+
value: 21
62+
},
63+
{
64+
fact: 'qualified',
65+
operator: 'equal',
66+
value: true
67+
},
68+
{
69+
all: [
70+
{
71+
fact: 'zipCode',
72+
operator: 'in',
73+
value: [80211, 80403]
74+
},
75+
{
76+
fact: 'gender',
77+
operator: 'notEqual',
78+
value: 'female'
79+
}
80+
]
81+
}
82+
]
7283
}
7384
engine = engineFactory()
7485
const ruleOptions = { conditions, event, priority: 100 }
@@ -91,6 +102,7 @@ describe('Engine: event', () => {
91102
expect(ruleResult.result).to.be.true()
92103
expect(ruleResult.conditions.any[0].result).to.be.true()
93104
expect(ruleResult.conditions.any[0].factResult).to.equal(21)
105+
expect(ruleResult.conditions.any[0].name).to.equal('over 21')
94106
expect(ruleResult.conditions.any[1].result).to.be.false()
95107
expect(ruleResult.conditions.any[1].factResult).to.equal(false)
96108
}
@@ -177,11 +189,13 @@ describe('Engine: event', () => {
177189
params: drinkOrderParams
178190
}
179191
const drinkOrderConditions = {
180-
any: [{
181-
fact: 'canOrderDrinks',
182-
operator: 'equal',
183-
value: true
184-
}]
192+
any: [
193+
{
194+
fact: 'canOrderDrinks',
195+
operator: 'equal',
196+
value: true
197+
}
198+
]
185199
}
186200
const drinkOrderRule = factories.rule({
187201
conditions: drinkOrderConditions,
@@ -193,7 +207,10 @@ describe('Engine: event', () => {
193207
engine.on('success', function (event, almanac, ruleResult) {
194208
switch (event.type) {
195209
case 'setDrinkingFlag':
196-
almanac.addRuntimeFact('canOrderDrinks', event.params.canOrderDrinks)
210+
almanac.addRuntimeFact(
211+
'canOrderDrinks',
212+
event.params.canOrderDrinks
213+
)
197214
break
198215
case 'offerDrink':
199216
expect(event.params).to.eql(drinkOrderParams)
@@ -257,7 +274,9 @@ describe('Engine: event', () => {
257274
expect(ruleResult.conditions.any[1].factResult).to.equal(false)
258275
expect(ruleResult.conditions.any[2].result).to.be.false()
259276
expect(ruleResult.conditions.any[2].all[0].result).to.be.false()
260-
expect(ruleResult.conditions.any[2].all[0].factResult).to.equal(ZIP_CODE)
277+
expect(ruleResult.conditions.any[2].all[0].factResult).to.equal(
278+
ZIP_CODE
279+
)
261280
expect(ruleResult.conditions.any[2].all[1].result).to.be.false()
262281
expect(ruleResult.conditions.any[2].all[1].factResult).to.equal(GENDER)
263282
}
@@ -375,7 +394,8 @@ describe('Engine: event', () => {
375394
rule.on('success', successSpy)
376395
await engine.run()
377396
const ruleResult = successSpy.getCall(0).args[2]
378-
const expected = '{"conditions":{"priority":1,"any":[{"operator":"greaterThanInclusive","value":21,"fact":"age","factResult":21,"result":true},{"operator":"equal","value":true,"fact":"qualified","factResult":false,"result":false}]},"event":{"type":"setDrinkingFlag","params":{"canOrderDrinks":true}},"priority":100,"result":true}'
397+
const expected =
398+
'{"conditions":{"priority":1,"any":[{"name":"over 21","operator":"greaterThanInclusive","value":21,"fact":"age","factResult":21,"result":true},{"operator":"equal","value":true,"fact":"qualified","factResult":false,"result":false}]},"event":{"type":"setDrinkingFlag","params":{"canOrderDrinks":true}},"priority":100,"result":true}'
379399
expect(JSON.stringify(ruleResult)).to.equal(expected)
380400
})
381401
})

types/index.d.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,11 @@ interface ConditionProperties {
152152
path?: string;
153153
priority?: number;
154154
params?: Record<string, any>;
155+
name?: string;
155156
}
156157

157158
type NestedCondition = ConditionProperties | TopLevelCondition;
158-
type AllConditions = { all: NestedCondition[] };
159-
type AnyConditions = { any: NestedCondition[] };
160-
type NotConditions = { not: NestedCondition };
159+
type AllConditions = { all: NestedCondition[]; name?: string; priority?: number; };
160+
type AnyConditions = { any: NestedCondition[]; name?: string; priority?: number; };
161+
type NotConditions = { not: NestedCondition; name?: string; priority?: number; };
161162
export type TopLevelCondition = AllConditions | AnyConditions | NotConditions;

0 commit comments

Comments
 (0)