From f66989ad4abbf414fe5a38b5167533bb6ef75ea0 Mon Sep 17 00:00:00 2001 From: Laurent Bossavit Date: Fri, 28 Jul 2017 14:24:29 +0200 Subject: [PATCH] =?UTF-8?q?:gear:=20Impl=C3=A9mente=20les=20variations?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- source/engine/mecanisms.js | 82 +++++++++++++++++++++++++++++++++++++- test/traverse.test.js | 14 +++++++ 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/source/engine/mecanisms.js b/source/engine/mecanisms.js index be7071337..418212a2a 100644 --- a/source/engine/mecanisms.js +++ b/source/engine/mecanisms.js @@ -11,7 +11,7 @@ let transformPercentage = s => +s.replace('%', '') / 100 : +s -export let decompose = (recurse, k, v) => { +let decompose = (recurse, k, v) => { let subProps = R.dissoc('composantes')(v), explanation = v.composantes.map(c => @@ -67,6 +67,82 @@ export let decompose = (recurse, k, v) => { } } +let devariate = (recurse, k, v) => { + let + subProps = R.dissoc('variations')(v), + explanation = v.variations.map(c => + ({ + ... recurse( + R.objOf(k, + { + ... subProps, + ... R.dissoc('si')(c) + }) + ), + condition: recurse(c.si) + }) + ) + + let evaluate = (situationGate, parsedRules, node) => { + let evaluateOne = child => { + let condition = evaluateNode(situationGate, parsedRules, child.condition) + return { + ...evaluateNode(situationGate, parsedRules, child), + condition + } + } + + let explanation = R.map(evaluateOne, node.explanation), + choice = R.find(node => node.condition.nodeValue, explanation), + nodeValue = choice ? choice.nodeValue : null + + let collectMissing = node => { + let choice = R.find(node => node.condition.nodeValue, node.explanation) + return choice ? collectNodeMissing(choice) : R.chain(collectNodeMissing,node.explanation) + } + + return rewriteNode(node,nodeValue,explanation,collectMissing) + } + + // TODO - find an appropriate representation + let jsx = (nodeValue, explanation) => + + { explanation.map((c, i) => + [
  • +
      + {R.toPairs(c.condition).map(([k,v]) => +
    • + {k}: + {v} +
    • + )} +
    +
    + {makeJsx(c)} +
    +
  • , + i < (explanation.length - 1) &&
  • + ]) + } + + } + /> + + return { + explanation, + evaluate, + jsx, + category: 'mecanism', + name: 'variations', + type: 'numeric' + } +} + export let mecanismOneOf = (recurse, k, v) => { if (!R.is(Array,v)) throw 'should be array' @@ -366,7 +442,9 @@ export let mecanismScale = (recurse,k,v) => { // A étendre (avec une propriété type ?) quand les règles en contiendront d'autres. if (v.composantes) { //mécanisme de composantes. Voir known-mecanisms.md/composantes return decompose(recurse,k,v) - + } + if (v.variations) { //mécanisme de composantes. Voir known-mecanisms.md/composantes + return devariate(recurse,k,v) } if (v['multiplicateur des tranches'] == null) diff --git a/test/traverse.test.js b/test/traverse.test.js index 18fe585af..97e5009ef 100644 --- a/test/traverse.test.js +++ b/test/traverse.test.js @@ -161,6 +161,20 @@ describe('analyseSituation with mecanisms', function() { expect(analyseSituation(rules,"startHere")(stateSelector)).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 = rawRules.map(enrichRule) + expect(analyseSituation(rules,"startHere")(stateSelector)).to.have.property('nodeValue',100+1800+80) + }); + it('should handle max', function() { let rawRules = [ {nom: "startHere", formule: {"le maximum de": [3200, 60, 9]}}],