From 960fda08e69f00cebcff1e71250c2a1f3765c808 Mon Sep 17 00:00:00 2001 From: Alexandre Hajjar Date: Thu, 8 Oct 2020 11:21:50 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=93=9D=20Remplace=20&=20applicable:=20spl?= =?UTF-8?q?it=20getApplicableReplacements=20&=20tests?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Split and document `getApplicableReplacements` * More remplace tests * `isDisabledBy` is mandatory in `ParsedRule` --- publicodes/source/parseReference.ts | 47 ++++++++++++++-------- publicodes/source/types/index.ts | 2 +- publicodes/test/mécanismes/remplace.yaml | 50 ++++++++++++++++++++++++ 3 files changed, 81 insertions(+), 18 deletions(-) diff --git a/publicodes/source/parseReference.ts b/publicodes/source/parseReference.ts index b1a1117b3..77700aefa 100644 --- a/publicodes/source/parseReference.ts +++ b/publicodes/source/parseReference.ts @@ -9,6 +9,32 @@ import { disambiguateRuleReference } from './ruleUtils' import { EvaluatedNode, ParsedRule } from './types' import { areUnitConvertible, serializeUnit } from './units' +/** + * Statically filter out replacements from `replaceBy`. + * Note: whitelist and blacklist filtering are applicable to the replacement + * itself or any parent namespace. + */ +export const getApplicableReplacedBy = (contextRuleName, replacedBy) => + replacedBy + .sort( + (replacement1, replacement2) => + +!!replacement2.whiteListedNames - +!!replacement1.whiteListedNames + ) + .filter( + ({ whiteListedNames }) => + !whiteListedNames || + whiteListedNames.some(name => contextRuleName.startsWith(name)) + ) + .filter( + ({ blackListedNames }) => + !blackListedNames || + blackListedNames.every(name => !contextRuleName.startsWith(name)) + ) + .filter(({ referenceNode }) => contextRuleName !== referenceNode.dottedName) + +/** + * Filter-out and apply all possible replacements at runtime. + */ const getApplicableReplacements = ( filter, contextRuleName, @@ -21,23 +47,10 @@ const getApplicableReplacements = ( if (contextRuleName.startsWith('[evaluation]')) { return [[], []] } - const applicableReplacements = rule.replacedBy - .sort( - (replacement1, replacement2) => - +!!replacement2.whiteListedNames - +!!replacement1.whiteListedNames - ) - // Remove remplacement not in whitelist - .filter( - ({ whiteListedNames }) => - !whiteListedNames || - whiteListedNames.some(name => contextRuleName.startsWith(name)) - ) - .filter( - ({ blackListedNames }) => - !blackListedNames || - blackListedNames.every(name => !contextRuleName.startsWith(name)) - ) - .filter(({ referenceNode }) => contextRuleName !== referenceNode.dottedName) + const applicableReplacements = getApplicableReplacedBy( + contextRuleName, + rule.replacedBy + ) // Remove remplacement defined in a not applicable node .filter(({ referenceNode }) => { const referenceRule = rules[referenceNode.dottedName] diff --git a/publicodes/source/types/index.ts b/publicodes/source/types/index.ts index 48b8cfb47..645b8e968 100644 --- a/publicodes/source/types/index.ts +++ b/publicodes/source/types/index.ts @@ -39,7 +39,7 @@ export type ParsedRule = Rule & { formule?: any evaluate?: () => EvaluatedRule explanation?: any - isDisabledBy?: Array + isDisabledBy: Array replacedBy: Array<{ whiteListedNames: Array blackListedNames: Array diff --git a/publicodes/test/mécanismes/remplace.yaml b/publicodes/test/mécanismes/remplace.yaml index 16a405534..b50c3d0eb 100644 --- a/publicodes/test/mécanismes/remplace.yaml +++ b/publicodes/test/mécanismes/remplace.yaml @@ -181,3 +181,53 @@ remplacement non applicable car branche desactivée: formule: z exemples: - valeur attendue: 1 + +# Remplacement non effectué dans la formule du remplacement +espace . valeur: + formule: 20 +espace . remplacement: + remplace: valeur + formule: valeur + 10 +test remplacement non effectué dans la formule du remplacement: + formule: espace . valeur + exemples: + - valeur attendue: 30 + + +frais de repas: + formule: 5 €/repas + +convention hôtels cafés restaurants: + formule: oui + +convention hôtels cafés restaurants . frais de repas: + remplace: frais de repas + formule: 6 €/repas + +frais de repas non remplacé: + formule: frais de repas + exemples: + - valeur attendue: 5 + +# Note: this would produce an infinite loop +# frais de repas remplacé: +# formule: convention hôtels cafés restaurants . frais de repas +# exemples: +# - nom: par défaut +# valeur attendue: 5 + + +frais de repas2: + formule: 5 €/repas + +convention hôtels cafés restaurants2: + formule: oui + +convention hôtels cafés restaurants2 . remplaçeur: + remplace: frais de repas2 + formule: 6 €/repas + +frais de repas2 remplacé: + formule: frais de repas2 + exemples: + - valeur attendue: 6