import {expect} from 'chai' import {rules as realRules, enrichRule} from '../source/engine/rules' import {analyse, parseAll, getTargets} from '../source/engine/traverse' let stateSelector = (state, name) => null describe('analyse', function() { it('should directly return simple numerical values', function() { let rule = {name: "startHere", formule: 3269} let rules = parseAll([rule]) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',3269) }); it('should compute expressions combining constants', function() { let rule = {name: "startHere", formule: "32 + 69"} let rules = parseAll([rule]) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',101) }); }); describe('analyse on raw rules', function() { it('should handle direct referencing of a variable', function() { let rawRules = [ {nom: "startHere", formule: "dix", espace: "top"}, {nom: "dix", formule: 10, espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',10) }); it('should handle expressions referencing other rules', function() { let rawRules = [ {nom: "startHere", formule: "3259 + dix", espace: "top"}, {nom: "dix", formule: 10, espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',3269) }); it('should handle applicability conditions', function() { let rawRules = [ {nom: "startHere", formule: "3259 + dix", espace: "top"}, {nom: "dix", formule: 10, espace: "top", "non applicable si" : "vrai"}, {nom: "vrai", formule: "2 > 1", espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',3259) }); it('should handle comparisons', function() { let rawRules = [ {nom: "startHere", formule: "3259 > dix", espace: "top"}, {nom: "dix", formule: 10, espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',true) }); /* TODO: make this pass it('should handle applicability conditions', function() { let rawRules = [ {nom: "startHere", formule: "3259 + dix", espace: "top"}, {nom: "dix", formule: 10, espace: "top", "non applicable si" : "vrai"}, {nom: "vrai", formule: "1", espace: "top"}], rules = rawRules.map(enrichRule) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',3259) }); */ }); describe('analyse with mecanisms', function() { it('should handle n-way "or"', function() { let rawRules = [ {nom: "startHere", formule: {"une de ces conditions": ["1 > 2", "1 > 0", "0 > 2"]}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',true) }); it('should handle n-way "and"', function() { let rawRules = [ {nom: "startHere", formule: {"toutes ces conditions": ["1 > 2", "1 > 0", "0 > 2"]}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',false) }); it('should handle switch statements', function() { let rawRules = [ {nom: "startHere", formule: {"aiguillage numérique": { "1 > dix":"1000%", "3 < dix":"1100%", "3 > dix":"1200%" }}, espace: "top"}, {nom: "dix", formule: 10, espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',11) }); it('should handle percentages', function() { let rawRules = [ {nom: "startHere", formule: "35%", espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',0.35) }); it('should handle sums', function() { let rawRules = [ {nom: "startHere", formule: {"somme": [3200, "dix", 9]}}, {nom: "dix", formule: 10}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',3219) }); it('should handle multiplications', function() { let rawRules = [ {nom: "startHere", formule: {"multiplication": {assiette:3259, plafond:3200, facteur:1, taux:1.5}}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',4800) }); it('should handle components in multiplication', function() { let rawRules = [ {nom: "startHere", formule: {"multiplication": {assiette:3200, composantes: [{taux:0.7}, {taux:0.8}] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',4800) }); it('should apply a ceiling to the sum of components', function() { let rawRules = [ {nom: "startHere", formule: {"multiplication": {assiette:3259, plafond:3200, composantes: [{taux:0.7}, {taux:0.8}] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',4800) }); it('should handle progressive scales', function() { let rawRules = [ {nom: "startHere", formule: {"barème": { assiette:2008, "multiplicateur des tranches":1000, "tranches":[{"en-dessous de":1, taux: 0.1},{de:1, "à": 2, taux: 1.2}, ,{"au-dessus de":2, taux: 10}] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',100+1200+80) }); it('should handle progressive scales with components', function() { let rawRules = [ {nom: "startHere", formule: {"barème": { assiette:2008, "multiplicateur des tranches":1000, composantes: [ {"tranches":[{"en-dessous de":1, taux: 0.05},{de:1, "à": 2, taux: 0.4}, ,{"au-dessus de":2, taux: 5}]}, {"tranches":[{"en-dessous de":1, taux: 0.05},{de:1, "à": 2, taux: 0.8}, ,{"au-dessus de":2, taux: 5}]} ] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',100+1200+80) }); it('should handle progressive scales with variations', function() { let rawRules = [ {nom: "startHere", formule: {"barème": { assiette:2008, "multiplicateur des tranches":1000, "variations":[ {si: "3 > 4", "tranches":[{"en-dessous de":1, taux: 0.1},{de:1, "à": 2, taux: 1.2}, ,{"au-dessus de":2, taux: 10}]}, {si: "3 > 2", "tranches":[{"en-dessous de":1, taux: 0.1},{de:1, "à": 2, taux: 1.8}, ,{"au-dessus de":2, taux: 10}]}, ] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',100+1800+80) }); it('should handle max', function() { let rawRules = [ {nom: "startHere", formule: {"le maximum de": [3200, 60, 9]}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',3200) }); it('should handle complements', function() { let rawRules = [ {nom: "startHere", formule: {complément: {cible: "dix", montant: 93}}, espace: "top"}, {nom: "dix", formule: 17, espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',93-17) }); it('should handle components in complements', function() { let rawRules = [ {nom: "startHere", formule: {complément: {cible: "dix", composantes: [{montant: 93},{montant: 93}] }}, espace: "top"}, {nom: "dix", formule: 17, espace: "top"}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',2*(93-17)) }); it('should handle filtering on components', function() { let rawRules = [ {nom: "startHere", espace: "top", formule: "composed (salarié)"}, {nom: "composed", espace: "top", formule: {"barème": { assiette:2008, "multiplicateur des tranches":1000, composantes: [ {tranches:[{"en-dessous de":1, taux: 0.05},{de:1, "à": 2, taux: 0.4}, ,{"au-dessus de":2, taux: 5}], attributs: {"dû par":"salarié"} }, {tranches:[{"en-dessous de":1, taux: 0.05},{de:1, "à": 2, taux: 0.8}, ,{"au-dessus de":2, taux: 5}], attributs: {"dû par":"employeur"} } ] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',50+400+40) }); it('should compute consistent values', function() { let rawRules = [ {nom: "startHere", espace: "top", formule: "composed (salarié) + composed (employeur)"}, {nom: "orHere", espace: "top", formule: "composed"}, {nom: "composed", espace: "top", formule: {"barème": { assiette:2008, "multiplicateur des tranches":1000, composantes: [ {tranches:[{"en-dessous de":1, taux: 0.05},{de:1, "à": 2, taux: 0.4}, ,{"au-dessus de":2, taux: 5}], attributs: {"dû par":"salarié"} }, {tranches:[{"en-dessous de":1, taux: 0.05},{de:1, "à": 2, taux: 0.8}, ,{"au-dessus de":2, taux: 5}], attributs: {"dû par":"employeur"} } ] }}}], rules = parseAll(rawRules.map(enrichRule)) expect(analyse(rules,"orHere")(stateSelector).targets[0]).to.have.property('nodeValue',100+1200+80) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',100+1200+80) }); it('should handle selection', function() { let stateSelector = (name) => ({"top . code postal":"2"})[name] let data = {taux_versement_transport: [{codePostal:1, aot: {taux: {"2019":"1.0"}}}, {codePostal:2, smt: {taux: {"2019":"2.0"}}}]} let rawRules = [ { espace: "top", nom: "startHere", formule: {"sélection": { données: "startHere", cherche: "code postal", dans: "codePostal", renvoie: "smt" }}, données: 'taux_versement_transport'}, {espace: "top", nom: "code postal", format: "nombre"}], rules = parseAll(rawRules.map(rule => enrichRule(rule,data))) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue',0.02) }); it('should handle failed selections', function() { let stateSelector = (name) => ({"top . code postal":"3"})[name] let data = {taux_versement_transport: [{codePostal:1, aot: {taux: {"2019":"1.0"}}}, {codePostal:2, smt: {taux: {"2019":"2.0"}}}]} let rawRules = [ { espace: "top", nom: "startHere", formule: {"sélection": { données: "startHere", cherche: "code postal", dans: "codePostal", renvoie: "smt" }}, données: 'taux_versement_transport'}, {espace: "top", nom: "code postal", format: "nombre"}], rules = parseAll(rawRules.map(rule => enrichRule(rule,data))) expect(analyse(rules,"startHere")(stateSelector).targets[0]).to.have.property('nodeValue', 0) }); });