diff --git a/source/serializeParsedRules.ts b/source/serializeParsedRules.ts index 276fa14..f69082c 100644 --- a/source/serializeParsedRules.ts +++ b/source/serializeParsedRules.ts @@ -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: ' + // as + // 'est non défini: = 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) @@ -78,41 +88,83 @@ function serializeMechanism(node: ASTNode): Record { function serializeASTNode(node: ASTNode): RawRule { return reduceAST( (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: . $SITUATION + // - alors: + // - sinon: . $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]), } } } + } + + case 'est non défini': + case 'est non applicable': { + console.log(`[EST_NON_DEF]:`, node) + return { + [node.nodeKind]: serializeASTNode(node.explanation), + } + } + 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) } } } @@ -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 } diff --git a/test/serializeParsedRules.test.ts b/test/serializeParsedRules.test.ts index 5946a4c..8335541 100644 --- a/test/serializeParsedRules.test.ts +++ b/test/serializeParsedRules.test.ts @@ -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) }) })