Skip to content

Commit

Permalink
refactor(optim): start to support basic mecanisms + tests
Browse files Browse the repository at this point in the history
  • Loading branch information
EmileRolley committed Jan 15, 2024
1 parent 83c3e3a commit 3c109e6
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 47 deletions.
147 changes: 105 additions & 42 deletions source/serializeParsedRules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,26 @@ function serializeValue(
}
}
case 'operation': {
if (node?.sourceMap?.mecanismName === 'est défini') {
return serializeMechanism(node)
switch (node?.sourceMap?.mecanismName) {
case 'est défini':
case 'est applicable': {
console.log(`[EST_DEFINI]:`, node)
// The engine parse the mecanism
// 'est défini: <rule>'
// as
// 'est non défini: <rule> = non'
return serializeMechanism(node)
}
default: {
return (
(needParens ? '(' : '') +
`${serializeValue(node.explanation[0], node.sourceMap, true)} ${
node.operationKind
} ${serializeValue(node.explanation[1], node.sourceMap, true)}` +
(needParens ? ')' : '')
)
}
}
return (
(needParens ? '(' : '') +
`${serializeValue(node.explanation[0], node.sourceMap, true)} ${
node.operationKind
} ${serializeValue(node.explanation[1], node.sourceMap, true)}` +
(needParens ? ')' : '')
)
}
case 'unité': {
const unit = serializeUnit(node.unit)
Expand Down Expand Up @@ -78,41 +88,83 @@ function serializeMechanism(node: ASTNode): Record<string, any> {
function serializeASTNode(node: ASTNode): RawRule {
return reduceAST<RawRule>(
(rawRule, node: ASTNode) => {
console.log(`\n----- serializing `, node.nodeKind)
console.log('[NODE_KIND]:', node.nodeKind)
switch (node.nodeKind) {
case 'constant': {
const serializedValue = serializeValue(node)
console.log(`serializing constant`, node)
return serializedValue
case 'reference':
case 'constant':
case 'operation': {
return serializeValue(node)
}
default: {
if (node?.sourceMap) {
switch (node.sourceMap.mecanismName) {
case 'dans la situation': {
if (node.nodeKind === 'condition') {
const serializedNode = serializeASTNode(
node.explanation.alors,
)
if (typeof serializedNode !== 'object') {
return {
valeur: serializedNode,
}
}
return {
...rawRule,
...serializeASTNode(node.explanation.alors),
}
} else {
console.error(
`'dans la situation' expect be resolved to a condition got ${node.nodeKind}`,
)
}

case 'condition': {
const sourceMap = node?.sourceMap
const mecanismName = sourceMap?.mecanismName
switch (mecanismName) {
case 'dans la situation': {
// The engine parse all rules into a root condition:
//
// - si:
// est non défini: <rule> . $SITUATION
// - alors: <rule>
// - sinon: <rule> . $SITUATION
//
if (
sourceMap.args['dans la situation']['title'] === '$SITUATION'
) {
return serializeASTNode(node.explanation.alors)
}
default: {
return { ...rawRule, ...serializeMechanism(node) }
}
case 'applicable si':
case 'non applicable si': {
return {
[mecanismName]: serializeASTNode(sourceMap.args[mecanismName]),

Check failure on line 120 in source/serializeParsedRules.ts

View workflow job for this annotation

GitHub Actions / main

Argument of type 'ASTNode<"unité" | "rule" | "replacementRule" | "reference" | "arrondi" | "barème" | "durée" | "grille" | "est non applicable" | "est non défini" | "inversion" | "operation" | "une possibilité" | ... 8 more ... | "texte"> | ASTNode<...>[]' is not assignable to parameter of type 'ASTNode<"unité" | "rule" | "replacementRule" | "reference" | "arrondi" | "barème" | "durée" | "grille" | "est non applicable" | "est non défini" | "inversion" | "operation" | "une possibilité" | ... 8 more ... | "texte">'.
}
}
}
}

case 'est non défini':
case 'est non applicable': {
console.log(`[EST_NON_DEF]:`, node)
return {
[node.nodeKind]: serializeASTNode(node.explanation),

Check failure on line 130 in source/serializeParsedRules.ts

View workflow job for this annotation

GitHub Actions / main

Argument of type 'ASTNode<"unité" | "rule" | "replacementRule" | "reference" | "arrondi" | "barème" | "durée" | "grille" | "est non applicable" | "est non défini" | "inversion" | "operation" | "une possibilité" | ... 8 more ... | "texte"> | { ...; }' is not assignable to parameter of type 'ASTNode<"unité" | "rule" | "replacementRule" | "reference" | "arrondi" | "barème" | "durée" | "grille" | "est non applicable" | "est non défini" | "inversion" | "operation" | "une possibilité" | ... 8 more ... | "texte">'.
}
}
default: {
console.log('[DEFAULT]:', node.nodeKind)
// console.log('[KIND]:', node.nodeKind)
// console.log('[SOURCE_MAP]:', node.sourceMap)
// if (node?.sourceMap) {
// switch (node.sourceMap.mecanismName) {
// case 'dans la situation': {
// if (node.nodeKind === 'condition') {
// console.log(`\n----- serializing `, node.nodeKind)
// console.log(`----- node `, node)
// const serializedNode = serializeASTNode(
// node.explanation.alors,
// )
// if (typeof serializedNode !== 'object') {
// return {
// valeur: serializedNode,
// }
// }
// return {
// ...rawRule,
// ...serializeASTNode(node.explanation.alors),
// }
// } else {
// console.error(
// `'dans la situation' expect be resolved to a condition got ${node.nodeKind}`,
// )
// }
// }
// default: {
// return { ...rawRule, ...serializeMechanism(node) }
// }
// }
// } else {
// return { ...rawRule, ...serializeMechanism(node) }
// }
return { ...rawRule, ...serializeMechanism(node) }
}
}
Expand All @@ -128,11 +180,22 @@ export function serializeParsedRules(
const rawRules = {}

for (const [rule, node] of Object.entries(parsedRules)) {
console.log(`serializing rule ${node.nodeKind}`)
rawRules[rule] = {
...node.rawNode,
...serializeASTNode(node.explanation.valeur),
console.log(`serializing ${rule}`)
const serializedNode = serializeASTNode(node.explanation.valeur)

console.log('serializedNode:', serializedNode)
if (typeof serializedNode === 'object') {
rawRules[rule] = {
...node.rawNode,
...serializedNode,
}
} else {
rawRules[rule] = {
...node.rawNode,
valeur: serializedNode,
}
}

delete rawRules[rule].nom
}

Expand Down
137 changes: 132 additions & 5 deletions test/serializeParsedRules.test.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,147 @@
import Engine from 'publicodes'
import { serializeParsedRules } from '../source/index'

describe('serializeParsedRules', () => {
describe('[serializeParsedRules] basic mecanisms', () => {
it('should serialize empty rules', () => {
expect(serializeParsedRules({})).toStrictEqual({})
})

it('should serialize simple rule with one mecanism', () => {
it('should serialize rule with constant [valeur]', () => {
const rules = {
rule: {
titre: 'My rule',
valeur: 10,
},
}
expect(
serializeParsedRules(new Engine(rules).getParsedRules()),
).toStrictEqual(rules)
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with ref [valeur]', () => {
const rules = {
rule: {
titre: 'My rule',
valeur: 10,
},
rule2: {
titre: 'Rule with a ref',
valeur: 'rule',
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with ref [applicable si]', () => {
const rules = {
rule: {
'applicable si': 'rule2',
valeur: 10,
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with condition [applicable si]', () => {
const rules = {
rule: {
'applicable si': 'rule2 < 5',
valeur: 10,
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with condition [non applicable si]', () => {
const rules = {
rule: {
'non applicable si': 'rule2 < 5',
valeur: 10,
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with [est non défini]', () => {
const rules = {
rule: {
'est non défini': 'rule2',
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with [est défini]', () => {
const rules = {
rule: {
'est défini': 'rule2',
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with [est non applicable]', () => {
const rules = {
rule: {
'est non applicable': 'rule2',
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
expect(serializedRules).toStrictEqual(rules)
})

it('should serialize rule with [est applicable]', () => {
const rules = {
rule: {
'est applicable': 'rule2',
},
rule2: {
valeur: 20,
},
}
const serializedRules = serializeParsedRules(
new Engine(rules).getParsedRules(),
)
console.log(serializedRules)
expect(serializedRules).toStrictEqual(rules)
})
})

0 comments on commit 3c109e6

Please sign in to comment.