Cycles: move hasCycle function into publicodes (useful for unit tests)
parent
a1bb8bebac
commit
4e30ef98b7
|
@ -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",
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
"dist/images"
|
||||
],
|
||||
"private": false,
|
||||
"devDependencies": {
|
||||
"@dagrejs/graphlib": "^2.1.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"classnames": "^2.2.6",
|
||||
"i18next": "^19.4.4",
|
||||
|
|
|
@ -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<Names extends string>(
|
|||
)
|
||||
}
|
||||
|
||||
export function buildRulesDependencies<Names extends string>(
|
||||
function buildRulesDependencies<Names extends string>(
|
||||
parsedRules: ParsedRules<Names>
|
||||
): Array<[Names, RuleDependencies<Names>]> {
|
||||
// This stringPairs thing is necessary because `toPairs` is strictly considering that
|
||||
|
@ -984,3 +986,22 @@ export function buildRulesDependencies<Names extends string>(
|
|||
RuleDependencies<Names>
|
||||
] => [dottedName, ruleDepsOfRuleNode<Names>(ruleNode)])
|
||||
}
|
||||
|
||||
type GraphNodeRepr = string
|
||||
type GraphCycles = Array<Array<GraphNodeRepr>>
|
||||
|
||||
// [XXX] Rename with cyclicDependencies and split this file in 3 parts
|
||||
export function hasCycles<Names extends string>(
|
||||
rawRules: Rules<Names> | 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)
|
||||
}
|
||||
|
|
|
@ -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 }
|
||||
|
||||
|
|
Loading…
Reference in New Issue