From 4e30ef98b7157b4d92b36854d51490ba9d353c05 Mon Sep 17 00:00:00 2001 From: Alexandre Hajjar Date: Tue, 22 Sep 2020 20:11:31 +0200 Subject: [PATCH] Cycles: move hasCycle function into publicodes (useful for unit tests) --- mon-entreprise/package.json | 3 +-- mon-entreprise/test/cycles.test.js | 16 ++-------------- publicodes/package.json | 3 +++ publicodes/source/cyclesLib.ts | 25 +++++++++++++++++++++++-- publicodes/source/index.ts | 2 +- 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/mon-entreprise/package.json b/mon-entreprise/package.json index dce36e533..840aa1240 100644 --- a/mon-entreprise/package.json +++ b/mon-entreprise/package.json @@ -21,8 +21,7 @@ "i18next-parser": "^1.0.6", "monaco-editor-webpack-plugin": "^1.9.0", "workbox-webpack-plugin": "^3.6.0", - "worker-loader": "^2.0.0", - "@dagrejs/graphlib": "^2.1.4" + "worker-loader": "^2.0.0" }, "dependencies": { "@babel/runtime": "^7.3.4", diff --git a/mon-entreprise/test/cycles.test.js b/mon-entreprise/test/cycles.test.js index ae5e7abf5..b563df9d7 100644 --- a/mon-entreprise/test/cycles.test.js +++ b/mon-entreprise/test/cycles.test.js @@ -1,23 +1,11 @@ import graphlib from '@dagrejs/graphlib' import { expect } from 'chai' -import { buildRulesDependencies, parseRules } from 'publicodes' +import { hasCycles } from 'publicodes' import rules from '../source/rules' describe('DottedNames graph', () => { it("shouldn't have cycles", () => { - // debugger - let parsedRules = parseRules(rules) - let ruleDependencies = buildRulesDependencies(parsedRules) - - // console.log(ruleDependencies) - let g = new graphlib.Graph() - - ruleDependencies.forEach(([ruleDottedName, dependenciesDottedNames]) => { - dependenciesDottedNames.forEach(depDottedName => { - g.setEdge(ruleDottedName, depDottedName) - }) - }) - const cycles = graphlib.alg.findCycles(g) + let cycles = hasCycles(rules) expect( cycles, diff --git a/publicodes/package.json b/publicodes/package.json index 6c985423d..c926fd8df 100644 --- a/publicodes/package.json +++ b/publicodes/package.json @@ -18,6 +18,9 @@ "dist/images" ], "private": false, + "devDependencies": { + "@dagrejs/graphlib": "^2.1.4" + }, "dependencies": { "classnames": "^2.2.6", "i18next": "^19.4.4", diff --git a/publicodes/source/cyclesLib.ts b/publicodes/source/cyclesLib.ts index c0aaa798a..4c94aa32b 100644 --- a/publicodes/source/cyclesLib.ts +++ b/publicodes/source/cyclesLib.ts @@ -4,8 +4,10 @@ */ import * as R from 'ramda' +import graphlib from '@dagrejs/graphlib' import { ArrondiExplanation } from './mecanisms/arrondi' -import { ParsedRule, ParsedRules } from './types' +import parseRules from './parseRules' +import { ParsedRule, ParsedRules, Rules } from './types' type OnOff = 'oui' | 'non' export function isOnOff(a: string): a is OnOff { @@ -966,7 +968,7 @@ function ruleDepsOfRuleNode( ) } -export function buildRulesDependencies( +function buildRulesDependencies( parsedRules: ParsedRules ): Array<[Names, RuleDependencies]> { // This stringPairs thing is necessary because `toPairs` is strictly considering that @@ -984,3 +986,22 @@ export function buildRulesDependencies( RuleDependencies ] => [dottedName, ruleDepsOfRuleNode(ruleNode)]) } + +type GraphNodeRepr = string +type GraphCycles = Array> + +// [XXX] Rename with cyclicDependencies and split this file in 3 parts +export function hasCycles( + rawRules: Rules | string +): GraphCycles { + const parsedRules = parseRules(rawRules) + const ruleDependencies = buildRulesDependencies(parsedRules) + const g = new graphlib.Graph() + + ruleDependencies.forEach(([ruleDottedName, dependencies]) => { + dependencies.forEach(([depDottedName, depType]) => { + g.setEdge(ruleDottedName, depDottedName, { type: depType }) + }) + }) + return graphlib.alg.findCycles(g) +} diff --git a/publicodes/source/index.ts b/publicodes/source/index.ts index 325762d5c..7e7e429b2 100644 --- a/publicodes/source/index.ts +++ b/publicodes/source/index.ts @@ -36,7 +36,7 @@ export type EvaluationOptions = Partial<{ export * from './components' export { formatValue } from './format' export { default as translateRules } from './translateRules' -export { buildRulesDependencies } from './cyclesLib' +export { hasCycles } from './cyclesLib' export * from './types' export { parseRules }