diff --git a/test/strategy.spec.js b/test/strategy.spec.js new file mode 100644 index 0000000..8f3fc9f --- /dev/null +++ b/test/strategy.spec.js @@ -0,0 +1,110 @@ +const Rools = require('..'); +require('./setup'); + +describe('Rules.evaluate() / specificity', () => { + const sequence = []; + const rule1 = { + name: 'rule1', + when: facts => facts.fact1, + then: () => { sequence.push(1); }, + }; + const rule2 = { + name: 'rule2', + when: [ + facts => facts.fact1, + facts => facts.fact2, + ], + then: () => { sequence.push(2); }, + }; + const rule3 = { + name: 'rule3', + when: [ + facts => facts.fact1, + facts => facts.fact2, + facts => facts.fact3, + ], + then: () => { sequence.push(3); }, + }; + const rule4 = { + name: 'rule4', + when: [ + facts => facts.fact1, + facts => facts.fact2, + facts => facts.fact4, + ], + then: () => { sequence.push(4); }, + }; + const facts = { + fact1: true, + fact2: true, + fact3: true, + fact4: true, + }; + + it('should fail if unknown strategy', async () => { + try { + const rools = new Rools(); + await rools.register(rule1, rule2, rule3); + await rools.evaluate(facts, { strategy: 'xx' }); + assert.fail(); + } catch (error) { + // correct + } + }); + + it('should fire rule with highest prio, then higher specificity / strategy "ps" / 1', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register({ ...rule1, priority: 10 }, rule2, rule3); + await rools.evaluate(facts); + expect(sequence).to.be.deep.equal([1, 3, 2]); + }); + + it('should fire rule with highest prio, then higher specificity / strategy "ps" / 2', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register({ ...rule1, priority: 10 }, rule2, rule3); + await rools.evaluate(facts, { strategy: 'ps' }); + expect(sequence).to.be.deep.equal([1, 3, 2]); + }); + + it('should fire rule with highest prio, then higher specificity / strategy "ps" / 3', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register({ ...rule1, priority: 10 }, rule2, rule3); + await rools.evaluate(facts, {}); + expect(sequence).to.be.deep.equal([1, 3, 2]); + }); + + it('should fire rule with higher specificity, then highest prio / strategy "sp" / 1', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register({ ...rule1, priority: 10 }, rule2, rule3); + await rools.evaluate(facts, { strategy: 'sp' }); + expect(sequence).to.be.deep.equal([3, 2, 1]); + }); + + it('should fire rule with higher specificity, then highest prio / strategy "sp" / 2', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register(rule1, { ...rule2, priority: 10 }, rule3); + await rools.evaluate(facts, { strategy: 'sp' }); + expect(sequence).to.be.deep.equal([3, 2, 1]); + }); + + it('should fire rule with higher specificity, then highest prio / strategy "sp" / 3', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register(rule1, rule2, rule3, rule4); + await rools.evaluate(facts, { strategy: 'sp' }); + expect(sequence).to.be.deep.equal([3, 4, 2, 1]); + }); + + it('should fire rule with higher specificity, then highest prio / strategy "sp" / 4', async () => { + sequence.length = 0; // reset + const rools = new Rools(); + await rools.register(rule1, rule2, rule3, { ...rule4, priority: 10 }); + await rools.evaluate(facts, { strategy: 'sp' }); + expect(sequence).to.be.deep.equal([4, 3, 2, 1]); + }); +});