Skip to content

Commit 25f9f7f

Browse files
committed
Move Almanac Initialization
Move the Almanac Initialization into the engine class. This will allow it to take user supplied Almanacs correctly.
1 parent 597daa3 commit 25f9f7f

File tree

4 files changed

+41
-53
lines changed

4 files changed

+41
-53
lines changed

src/almanac.js

+2-14
Original file line numberDiff line numberDiff line change
@@ -17,25 +17,13 @@ function defaultPathResolver (value, path) {
1717
* A new almanac is used for every engine run()
1818
*/
1919
export default class Almanac {
20-
constructor (factMap, runtimeFacts = {}, options = {}) {
21-
this.factMap = new Map(factMap)
20+
constructor (options = {}) {
21+
this.factMap = new Map()
2222
this.factResultsCache = new Map() // { cacheKey: Promise<factValu> }
2323
this.allowUndefinedFacts = Boolean(options.allowUndefinedFacts)
2424
this.pathResolver = options.pathResolver || defaultPathResolver
2525
this.events = { success: [], failure: [] }
2626
this.ruleResults = []
27-
28-
for (const factId in runtimeFacts) {
29-
let fact
30-
if (runtimeFacts[factId] instanceof Fact) {
31-
fact = runtimeFacts[factId]
32-
} else {
33-
fact = new Fact(factId, runtimeFacts[factId])
34-
}
35-
36-
this._addConstantFact(fact)
37-
debug(`almanac::constructor initialized runtime fact:${fact.id} with ${fact.value}<${typeof fact.value}>`)
38-
}
3927
}
4028

4129
/**

src/engine.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,21 @@ class Engine extends EventEmitter {
268268
allowUndefinedFacts: this.allowUndefinedFacts,
269269
pathResolver: this.pathResolver
270270
}
271-
const almanac = new Almanac(this.facts, runtimeFacts, almanacOptions)
271+
const almanac = new Almanac(almanacOptions)
272+
this.facts.forEach(fact => {
273+
almanac.addFact(fact)
274+
})
275+
for (const factId in runtimeFacts) {
276+
let fact
277+
if (runtimeFacts[factId] instanceof Fact) {
278+
fact = runtimeFacts[factId]
279+
} else {
280+
fact = new Fact(factId, runtimeFacts[factId])
281+
}
282+
283+
almanac.addFact(fact)
284+
debug(`engine::run initialized runtime fact:${fact.id} with ${fact.value}<${typeof fact.value}>`)
285+
}
272286
const orderedSets = this.prioritizeRules()
273287
let cursor = Promise.resolve()
274288
// for each rule set, evaluate in parallel,

test/almanac.test.js

+12-29
Original file line numberDiff line numberDiff line change
@@ -23,24 +23,12 @@ describe('Almanac', () => {
2323
})
2424

2525
it('adds runtime facts', () => {
26-
almanac = new Almanac(new Map(), { modelId: 'XYZ' })
26+
almanac = new Almanac()
27+
almanac.addFact('modelId', 'XYZ')
2728
expect(almanac.factMap.get('modelId').value).to.equal('XYZ')
2829
})
2930
})
3031

31-
describe('constructor', () => {
32-
it('supports runtime facts as key => values', () => {
33-
almanac = new Almanac(new Map(), { fact1: 3 })
34-
return expect(almanac.factValue('fact1')).to.eventually.equal(3)
35-
})
36-
37-
it('supports runtime fact instances', () => {
38-
const fact = new Fact('fact1', 3)
39-
almanac = new Almanac(new Map(), { fact1: fact })
40-
return expect(almanac.factValue('fact1')).to.eventually.equal(fact.value)
41-
})
42-
})
43-
4432
describe('addFact', () => {
4533
it('supports runtime facts as key => values', () => {
4634
almanac = new Almanac()
@@ -94,9 +82,8 @@ describe('Almanac', () => {
9482
if (params.userId) return params.userId
9583
return 'unknown'
9684
})
97-
const factMap = new Map()
98-
factMap.set(fact.id, fact)
99-
almanac = new Almanac(factMap)
85+
almanac = new Almanac()
86+
almanac.addFact(fact)
10087
})
10188

10289
it('allows parameters to be passed to the fact', async () => {
@@ -131,10 +118,9 @@ describe('Almanac', () => {
131118

132119
describe('_getFact', _ => {
133120
it('retrieves the fact object', () => {
134-
const facts = new Map()
135121
const fact = new Fact('id', 1)
136-
facts.set(fact.id, fact)
137-
almanac = new Almanac(facts)
122+
almanac = new Almanac()
123+
almanac.addFact(fact)
138124
expect(almanac._getFact('id')).to.equal(fact)
139125
})
140126
})
@@ -149,9 +135,8 @@ describe('Almanac', () => {
149135

150136
function setup (f = new Fact('id', 1)) {
151137
fact = f
152-
const facts = new Map()
153-
facts.set(fact.id, fact)
154-
almanac = new Almanac(facts)
138+
almanac = new Almanac()
139+
almanac.addFact(fact)
155140
}
156141
let fact
157142
const FACT_VALUE = 2
@@ -179,9 +164,8 @@ describe('Almanac', () => {
179164
name: 'Thomas'
180165
}]
181166
})
182-
const factMap = new Map()
183-
factMap.set(fact.id, fact)
184-
almanac = new Almanac(factMap)
167+
almanac = new Almanac()
168+
almanac.addFact(fact)
185169
const result = await almanac.factValue('foo', null, '$..name')
186170
expect(result).to.deep.equal(['George', 'Thomas'])
187171
})
@@ -192,9 +176,8 @@ describe('Almanac', () => {
192176
factSpy()
193177
return 'unknown'
194178
}, factOptions)
195-
const factMap = new Map()
196-
factMap.set(fact.id, fact)
197-
almanac = new Almanac(factMap)
179+
almanac = new Almanac()
180+
almanac.addFact(fact)
198181
}
199182

200183
it('evaluates the fact every time when fact caching is off', () => {

test/condition.test.js

+12-9
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,8 @@ describe('Condition', () => {
9191
const properties = Object.assign({}, conditionBase, options)
9292
condition = new Condition(properties)
9393
const fact = new Fact(conditionBase.fact, factValue)
94-
almanac = new Almanac(new Map([[fact.id, fact]]))
94+
almanac = new Almanac()
95+
almanac.addFact(fact)
9596
}
9697

9798
context('validations', () => {
@@ -118,12 +119,14 @@ describe('Condition', () => {
118119
it('evaluates "equal" to check for undefined', async () => {
119120
condition = new Condition({ fact: 'age', operator: 'equal', value: undefined })
120121
let fact = new Fact('age', undefined)
121-
almanac = new Almanac(new Map([[fact.id, fact]]))
122+
almanac = new Almanac()
123+
almanac.addFact(fact)
122124

123125
expect((await condition.evaluate(almanac, operators)).result).to.equal(true)
124126

125127
fact = new Fact('age', 1)
126-
almanac = new Almanac(new Map([[fact.id, fact]]))
128+
almanac = new Almanac()
129+
almanac.addFact(fact)
127130
expect((await condition.evaluate(almanac, operators)).result).to.equal(false)
128131
})
129132

@@ -235,8 +238,8 @@ describe('Condition', () => {
235238
it('extracts the object property values using its "path" property', async () => {
236239
const condition = new Condition({ operator: 'equal', path: '$.[0].id', fact: 'age', value: 50 })
237240
const ageFact = new Fact('age', [{ id: 50 }, { id: 60 }])
238-
const facts = new Map([[ageFact.id, ageFact]])
239-
const almanac = new Almanac(facts)
241+
const almanac = new Almanac()
242+
almanac.addFact(ageFact)
240243
expect((await condition.evaluate(almanac, operators)).result).to.equal(true)
241244

242245
condition.value = 100 // negative case
@@ -245,8 +248,8 @@ describe('Condition', () => {
245248

246249
it('ignores "path" when non-objects are returned by the fact', async () => {
247250
const ageFact = new Fact('age', 50)
248-
const facts = new Map([[ageFact.id, ageFact]])
249-
const almanac = new Almanac(facts)
251+
const almanac = new Almanac()
252+
almanac.addFact(ageFact)
250253

251254
const condition = new Condition({ operator: 'equal', path: '$.[0].id', fact: 'age', value: 50 })
252255
expect((await condition.evaluate(almanac, operators, 50)).result).to.equal(true)
@@ -273,8 +276,8 @@ describe('Condition', () => {
273276
}
274277

275278
const usersFact = new Fact('users', userData)
276-
const facts = new Map([[usersFact.id, usersFact]])
277-
const almanac = new Almanac(facts)
279+
const almanac = new Almanac()
280+
almanac.addFact(usersFact)
278281
expect((await condition.evaluate(almanac, operators)).result).to.equal(true)
279282

280283
condition.value = 'work' // negative case

0 commit comments

Comments
 (0)