-
Notifications
You must be signed in to change notification settings - Fork 488
/
Copy pathengine-run.test.js
136 lines (119 loc) · 4.03 KB
/
engine-run.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
'use strict'
import engineFactory from '../src/index'
import Almanac from '../src/almanac'
import sinon from 'sinon'
describe('Engine: run', () => {
let engine, rule, rule2
let sandbox
before(() => {
sandbox = sinon.createSandbox()
})
afterEach(() => {
sandbox.restore()
})
const condition21 = {
any: [{
fact: 'age',
operator: 'greaterThanInclusive',
value: 21
}]
}
const condition75 = {
any: [{
fact: 'age',
operator: 'greaterThanInclusive',
value: 75
}]
}
let eventSpy
beforeEach(() => {
eventSpy = sandbox.spy()
engine = engineFactory()
rule = factories.rule({ conditions: condition21, event: { type: 'generic1' } })
engine.addRule(rule)
rule2 = factories.rule({ conditions: condition75, event: { type: 'generic2' } })
engine.addRule(rule2)
engine.on('success', eventSpy)
})
describe('independent runs', () => {
it('treats each run() independently', async () => {
await Promise.all([50, 10, 12, 30, 14, 15, 25].map((age) => engine.run({ age })))
expect(eventSpy).to.have.been.calledThrice()
})
it('allows runtime facts to override engine facts for a single run()', async () => {
engine.addFact('age', 30)
await engine.run({ age: 85 }) // override 'age' with runtime fact
expect(eventSpy).to.have.been.calledTwice()
sandbox.reset()
await engine.run() // no runtime fact; revert to age: 30
expect(eventSpy).to.have.been.calledOnce()
sandbox.reset()
await engine.run({ age: 2 }) // override 'age' with runtime fact
expect(eventSpy.callCount).to.equal(0)
})
})
describe('returns', () => {
it('activated events', async () => {
const { events, failureEvents } = await engine.run({ age: 30 })
expect(events.length).to.equal(1)
expect(events).to.deep.include(rule.event)
expect(failureEvents.length).to.equal(1)
expect(failureEvents).to.deep.include(rule2.event)
})
it('multiple activated events', () => {
return engine.run({ age: 90 }).then(results => {
expect(results.events.length).to.equal(2)
expect(results.events).to.deep.include(rule.event)
expect(results.events).to.deep.include(rule2.event)
})
})
it('does not include unactived triggers', () => {
return engine.run({ age: 10 }).then(results => {
expect(results.events.length).to.equal(0)
})
})
it('includes the almanac', () => {
return engine.run({ age: 10 }).then(results => {
expect(results.almanac).to.be.an.instanceOf(Almanac)
return results.almanac.factValue('age')
}).then(ageFact => expect(ageFact).to.equal(10))
})
})
describe('facts updated during run', () => {
beforeEach(() => {
engine.on('success', (event, almanac, ruleResult) => {
// Assign unique runtime facts per event
almanac.addRuntimeFact(`runtime-fact-${event.type}`, ruleResult.conditions.any[0].value)
})
})
it('returns an almanac with runtime facts added', () => {
return engine.run({ age: 90 }).then(results => {
return Promise.all([
results.almanac.factValue('runtime-fact-generic1'),
results.almanac.factValue('runtime-fact-generic2')
])
}).then(promiseValues => {
expect(promiseValues[0]).to.equal(21)
expect(promiseValues[1]).to.equal(75)
})
})
})
describe('custom alamanc', () => {
class CapitalAlmanac extends Almanac {
factValue (factId, params, path) {
return super.factValue(factId, params, path).then(value => {
if (typeof value === 'string') {
return value.toUpperCase()
}
return value
})
}
}
it('returns the capitalized value when using the CapitalAlamanc', () => {
return engine.run({ greeting: 'hello', age: 30 }, { almanac: new CapitalAlmanac() }).then((results) => {
const fact = results.almanac.factValue('greeting')
return expect(fact).to.eventually.equal('HELLO')
})
})
})
})