mon-entreprise/test/inversion.test.js

237 lines
6.1 KiB
JavaScript

import { expect } from 'chai'
import dedent from 'dedent-js'
import yaml from 'js-yaml'
import { collectMissingVariables } from '../source/engine/generateQuestions'
import { enrichRule, rules as realRules } from '../source/engine/rules'
import { analyse, analyseMany, parseAll } from '../source/engine/traverse'
describe('inversions', () => {
it('should handle non inverted example', () => {
let fakeState = { brut: 2300 }
let stateSelector = name => fakeState[name]
let rawRules = dedent`
- nom: net
formule:
multiplication:
assiette: brut
taux: 77%
- nom: brut
format: euro
`,
rules = parseAll(yaml.safeLoad(rawRules).map(enrichRule)),
analysis = analyse(rules, 'net')(stateSelector)
expect(analysis.targets[0].nodeValue).to.be.closeTo(1771, 0.001)
})
it('should handle simple inversion', () => {
let fakeState = { net: 2000 }
let stateSelector = name => fakeState[name]
let rawRules = dedent`
- nom: net
formule:
multiplication:
assiette: brut
taux: 77%
- nom: brut
format: euro
formule:
inversion:
avec:
- net
`,
rules = parseAll(yaml.safeLoad(rawRules).map(enrichRule)),
analysis = analyse(rules, 'brut')(stateSelector)
expect(analysis.targets[0].nodeValue).to.be.closeTo(
2000 / (77 / 100),
0.0001 * 2000
)
})
it('should ask the input of one of the possible inversions', () => {
let rawRules = dedent`
- nom: net
formule:
multiplication:
assiette: assiette
variations:
- si: cadre
alors:
taux: 80%
- sinon:
taux: 70%
- nom: brut
format: euro
formule:
inversion:
avec:
- net
- nom: cadre
- nom: assiette
formule: 67 + brut
`,
rules = parseAll(yaml.safeLoad(rawRules).map(enrichRule)),
stateSelector = () => null,
analysis = analyse(rules, 'brut')(stateSelector),
missing = collectMissingVariables(analysis.targets)
expect(analysis.targets[0].nodeValue).to.be.null
expect(missing).to.include('brut')
})
it('should handle inversions with missing variables', () => {
let rawRules = dedent`
- nom: net
formule:
multiplication:
assiette: assiette
variations:
- si: cadre
alors:
taux: 80%
- sinon:
taux: 70%
- nom: brut
format: euro
formule:
inversion:
avec:
- net
- nom: cadre
- nom: assiette
formule:
somme:
- 1200
- brut
- taxeOne
- nom: taxeOne
non applicable si: cadre
formule: taxe + taxe
- nom: taxe
formule:
multiplication:
assiette: 1200
variations:
- si: cadre
alors:
taux: 80%
- sinon:
taux: 70%
`,
rules = parseAll(yaml.safeLoad(rawRules).map(enrichRule)),
stateSelector = name => ({ net: 2000 }[name]),
analysis = analyse(rules, 'brut')(stateSelector),
missing = collectMissingVariables(analysis.targets)
expect(analysis.targets[0].nodeValue).to.be.null
expect(missing).to.include('cadre')
})
it("shouldn't report a missing salary if another salary was input", () => {
let rawRules = dedent`
- nom: net
formule:
multiplication:
assiette: assiette
variations:
- si: cadre
alors:
taux: 80%
- si: ≠ cadre
alors:
taux: 70%
- nom: total
formule:
multiplication:
assiette: assiette
taux: 150%
- nom: brut
format: euro
formule:
inversion:
avec:
- net
- total
- nom: cadre
- nom: assiette
formule: 67 + brut
`,
rules = parseAll(yaml.safeLoad(rawRules).map(enrichRule)),
stateSelector = name => ({ net: 2000, cadre: 'oui' }[name]),
analysis = analyse(rules, 'total')(stateSelector),
missing = collectMissingVariables(analysis.targets)
expect(analysis.targets[0].nodeValue).to.equal(3750)
expect(missing).to.be.empty
})
})
it('complex inversion with composantes', () => {
let rawRules = dedent`
- nom: net
formule:
multiplication:
assiette: 67 + brut
taux: 80%
- nom: cotisation
formule:
multiplication:
assiette: 67 + brut
composantes:
- attributs:
dû par: employeur
taux: 100%
- attributs:
dû par: salarié
taux: 50%
- nom: total
formule: cotisation (employeur) + cotisation (salarié)
- nom: brut
format: euro
formule:
inversion:
avec:
- net
- total
`,
rules = parseAll(yaml.safeLoad(rawRules).map(enrichRule)),
stateSelector = name => ({ net: 2000 }[name]),
analysis = analyse(rules, 'total')(stateSelector),
missing = collectMissingVariables(analysis.targets)
expect(analysis.targets[0].nodeValue).to.equal(3750)
expect(missing).to.be.empty
})
it('should collect missing variables not too slowly', function() {
let stateSelector = name =>
({ 'contrat salarié . salaire . net': '2300' }[name])
let rules = parseAll(realRules.map(enrichRule)),
analysis = analyseMany(rules, [
'contrat salarié . salaire . brut',
'contrat salarié . rémunération . total'
])(stateSelector)
let start = Date.now()
collectMissingVariables(analysis.targets)
let elapsed = Date.now() - start
expect(elapsed).to.be.below(500)
})