Snapshot testing

Ajout de tests de non-regressions des calculs afin d'éviter de déployer
silencieusement des effets de bord non-désirés dans les règles de calculs.

J'ai ajouté Jest pour sa fonction de snapshot testing qui est
particulièrement adaptée pour ce type de cas (voir #717). J'ai essayé
avec mocha-snapshot sans succès.

J'ai eu un petit peu de mal à configurer Jest, car il n'est pas possible
de ré-utiliser la configuration Webpack, qu'il faut alors dupliquer. C'est
pourquoi j'ai limité l'utilisation de Jest aux seuls tests de snapshot.
À voir s'il y a un intérêt à migrer les tests Mocha vers Jest ultérieurement.

Fixes #717
pull/739/head
Maxime Quandalle 2019-10-18 19:15:58 +02:00
parent 3017c81f33
commit 1e7730dd25
No known key found for this signature in database
GPG Key ID: 428641C03D29CA10
18 changed files with 2199 additions and 128 deletions

View File

@ -1,19 +0,0 @@
{
"presets": ["@babel/react", "@babel/flow"],
"plugins": [
"@babel/plugin-proposal-class-properties",
"@babel/plugin-proposal-do-expressions",
"@babel/plugin-proposal-optional-chaining",
"@babel/plugin-proposal-object-rest-spread",
"@babel/plugin-syntax-dynamic-import",
"react-hot-loader/babel",
["webpack-alias", { "config": "./source/webpack.dev.js" }],
[
"ramda",
{
"useES": true
}
],
"babel-plugin-styled-components"
]
}

View File

@ -26,6 +26,7 @@ Nous utilisons :
- [Eslint](http://eslint.org) qui permet par exemple d'éviter de garder des variables inutilisées
- [Flow](https://flow.org/) pour ajouter un système de typage à notre code JavaScript. Le typage Flow n'est pas utilisé partout et il n'est pas obligatoire de le prendre en compte pour contribuer.
- [Ramda](https://ramdajs.com) comme libraire d'utilitaires pour manipuler les listes/objects/etc (c'est une alternative à lodash ou underscore)
- [Mocha](https://mochajs.org), [Jest](https://jestjs.io) et [Cypress](https://www.cypress.io) pour les l'execution des tests. Plus d'informations dans la section consacrée aux tests.
### Démarrage
@ -69,3 +70,25 @@ Et ceux spécifiques au projet :
- :alien: `:alien:` pour ajouter des traductions
- :wheelchair: `:wheelchair:` pour corriger les problèmes liés à l'accessibilité
- :fountain_pen: `:fountain_pen:` pour séparer les commits liés à la modification du contenu
### Tests
Pour executer les tests unitaires :
```sh
$ yarn run test-common
```
Pour le snapshot testing :
```sh
$ yarn run test-regressions
```
Si vous souhaitez mettre à jour les snapshots vous pouvez utiliser le paramètre `--updateSnapshot`, son raccourci `-u`, ou encore le [mode interactif](https://jestjs.io/docs/en/snapshot-testing#interactive-snapshot-mode).
Enfin pour les tests d'intégration :
```sh
$ yarn run test-cypress
```

30
babel.config.js Normal file
View File

@ -0,0 +1,30 @@
module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
node: 'current'
}
}
],
'@babel/react',
'@babel/flow'
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-do-expressions',
'@babel/plugin-proposal-optional-chaining',
'@babel/plugin-proposal-object-rest-spread',
'@babel/plugin-syntax-dynamic-import',
'react-hot-loader/babel',
['webpack-alias', { config: './source/webpack.dev.js' }],
[
'ramda',
{
useES: true
}
],
'babel-plugin-styled-components'
]
}

View File

@ -39,6 +39,7 @@ jobs:
yarn run flow-typed install
git config --global core.quotepath false
yarn test
yarn test-regressions
end-to-end-test:
docker:

197
jest.config.js Normal file
View File

@ -0,0 +1,197 @@
// For a detailed explanation regarding each configuration property, visit:
// https://jestjs.io/docs/en/configuration.html
module.exports = {
// All imported modules in your tests should be mocked automatically
// automock: false,
// Stop running tests after `n` failures
// bail: 0,
// Respect "browser" field in package.json when resolving modules
// browser: false,
// The directory where Jest should store its cached dependency information
// cacheDirectory: "/tmp/jest_rs",
// Automatically clear mock calls and instances between every test
// clearMocks: false,
// Indicates whether the coverage information should be collected while executing the test
// collectCoverage: false,
// An array of glob patterns indicating a set of files for which coverage information should be collected
// collectCoverageFrom: null,
// The directory where Jest should output its coverage files
// coverageDirectory: null,
// An array of regexp pattern strings used to skip coverage collection
// coveragePathIgnorePatterns: [
// "/node_modules/"
// ],
// A list of reporter names that Jest uses when writing coverage reports
// coverageReporters: [
// "json",
// "text",
// "lcov",
// "clover"
// ],
// An object that configures minimum threshold enforcement for coverage results
// coverageThreshold: null,
// A path to a custom dependency extractor
// dependencyExtractor: null,
// Make calling deprecated APIs throw helpful error messages
// errorOnDeprecated: false,
// Force coverage collection from ignored files using an array of glob patterns
// forceCoverageMatch: [],
// A path to a module which exports an async function that is triggered once before all test suites
// globalSetup: null,
// A path to a module which exports an async function that is triggered once after all test suites
// globalTeardown: null,
// A set of global variables that need to be available in all test environments
// globals: {},
// The maximum amount of workers used to run your tests. Can be specified as % or a number. E.g. maxWorkers: 10% will use 10% of your CPU amount + 1 as the maximum worker number. maxWorkers: 2 will use a maximum of 2 workers.
// maxWorkers: "50%",
// An array of directory names to be searched recursively up from the requiring module's location
// moduleDirectories: [
// "node_modules"
// ],
// An array of file extensions your modules use
// moduleFileExtensions: [
// "js",
// "json",
// "jsx",
// "ts",
// "tsx",
// "node"
// ],
// A map from regular expressions to module names that allow to stub out resources with a single module
moduleNameMapper: {
'\\.css$': '<rootDir>/test/regressions/styleMock.js'
},
// An array of regexp pattern strings, matched against all module paths before considered 'visible' to the module loader
// modulePathIgnorePatterns: [],
// Activates notifications for test results
// notify: false,
// An enum that specifies notification mode. Requires { notify: true }
// notifyMode: "failure-change",
// A preset that is used as a base for Jest's configuration
// preset: null,
// Run tests from one or more projects
// projects: null,
// Use this configuration option to add custom reporters to Jest
// reporters: undefined,
// Automatically reset mock state between every test
// resetMocks: false,
// Reset the module registry before running each individual test
// resetModules: false,
// A path to a custom resolver
// resolver: null,
// Automatically restore mock state between every test
// restoreMocks: false,
// The root directory that Jest should scan for tests and modules within
// rootDir: null,
// A list of paths to directories that Jest should use to search for files in
// roots: [
// "<rootDir>"
// ],
// Allows you to use a custom runner instead of Jest's default test runner
// runner: "jest-runner",
// The paths to modules that run some code to configure or set up the testing environment before each test
// setupFiles: [],
// A list of paths to modules that run some code to configure or set up the testing framework before each test
// setupFilesAfterEnv: [],
// A list of paths to snapshot serializer modules Jest should use for snapshot testing
// snapshotSerializers: [],
// The test environment that will be used for testing
testEnvironment: 'node',
// Options that will be passed to the testEnvironment
// testEnvironmentOptions: {},
// Adds a location field to test results
// testLocationInResults: false,
// The glob patterns Jest uses to detect test files
testMatch: [
// We have 2 test runners (Mocha and Jest), so we create a custom extension without `.test.js`
// to dissociate the two.
'**/*.jest.js'
// "**/__tests__/**/*.[jt]s?(x)",
// "**/?(*.)+(spec|test).[tj]s?(x)"
],
// An array of regexp pattern strings that are matched against all test paths, matched tests are skipped
// testPathIgnorePatterns: [
// "/node_modules/"
// ],
// The regexp pattern or array of patterns that Jest uses to detect test files
// testRegex: [],
// This option allows the use of a custom results processor
// testResultsProcessor: null,
// This option allows use of a custom test runner
// testRunner: "jasmine2",
// This option sets the URL for the jsdom environment. It is reflected in properties such as location.href
// testURL: "http://localhost",
// Setting this value to "fake" allows the use of fake timers for functions such as "setTimeout"
// timers: "real",
// A map from regular expressions to paths to transformers
transform: {
// It's not possible to have 2 piped transformers like in webpack
// ie ['jest-transform-nearley', 'babel-jest'], so we removed ES6 module from nearley output.
'\\.ne$': 'jest-transform-nearley',
'\\.yaml$': 'yaml-jest',
'\\.js?$': 'babel-jest'
},
// An array of regexp pattern strings that are matched against all source file paths, matched files will skip transformation
transformIgnorePatterns: ['/node_modules/(?!ramda).+\\.js$']
// An array of regexp pattern strings that are matched against all modules before the module loader will automatically return a mock for them
// unmockedModulePathPatterns: undefined,
// Indicates whether each individual test should be reported during the run
// verbose: null,
// An array of regexp patterns that are matched against all source file paths before re-running tests in watch mode
// watchPathIgnorePatterns: [],
// Whether to use watchman for file crawling
// watchman: true,
}

View File

@ -84,6 +84,7 @@
"test-lib": "mocha-webpack --webpack-config source/webpack.lib.js --require source-map-support/register --include componentTestSetup.js --require mock-local-storage test/library.test.js",
"test-expressions": "yarn test-common --grep 'Suite expressions'",
"test-units": "mocha-webpack --webpack-config source/webpack.test.js --require source-map-support/register --include componentTestSetup.js --require mock-local-storage --require test/helpers/browser.js test/units.test.js",
"test-regressions": "jest",
"compile-lib": "yarn webpack --config source/webpack.lib.js",
"compile-dev": "FR_SITE='http://localhost:5000${path}' EN_SITE='http://localhost:5001${path}' yarn run compile",
"mon-entreprise:serve": "PORT=5000 serve --config serve.mon-entreprise.json --no-clipboard",
@ -93,18 +94,19 @@
"serve-dev": "yarn run mon-entreprise:serve & yarn run mycompanyinfrance:serve"
},
"devDependencies": {
"@babel/core": "^7.1.0",
"@babel/core": "^7.6.4",
"@babel/plugin-proposal-class-properties": "^7.1.0",
"@babel/plugin-proposal-do-expressions": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/preset-env": "^7.3.4",
"@babel/preset-env": "^7.6.3",
"@babel/preset-flow": "^7.0.0-beta.51",
"@babel/preset-react": "^7.0.0",
"akh": "^3.1.2",
"autoprefixer": "^9.3.1",
"babel-eslint": "^11.0.0-beta.0",
"babel-jest": "^24.9.0",
"babel-loader": "^8.0.2",
"babel-plugin-ramda": "^1.6.3",
"babel-plugin-styled-components": "^1.10.0",
@ -134,6 +136,8 @@
"intl": "^1.2.5",
"intl-locales-supported": "^1.0.0",
"isomorphic-style-loader": "^5.1.0",
"jest": "^24.9.0",
"jest-transform-nearley": "^1.0.0",
"jsdom": "^12.0.0",
"json-loader": "^0.5.7",
"koa-connect": "^2.0.1",
@ -160,6 +164,7 @@
"webpack-dev-middleware": "^3.4.0",
"webpack-hot-middleware": "^2.24.2",
"workbox-webpack-plugin": "^3.6.1",
"yaml-jest": "^1.0.5",
"yaml-loader": "^0.5.0"
},
"optionalDependencies": {

View File

@ -74,7 +74,7 @@ export default class Provider extends PureComponent {
}
render() {
const iframeCouleur = new URLSearchParams(
document.location.search.substring(1)
document?.location.search.substring(1)
).get('couleur')
return (
// If IE < 11 display nothing

View File

@ -2,10 +2,11 @@
# Look for the PEMDAS system : Parentheses, Exponents (omitted here), Multiplication, and you should guess the rest :)
@preprocessor esmodule
# This preprocessor was disabled because it doesn't work with Jest
# @preprocessor esmodule
@{%
import {string, filteredVariable, variable, temporalVariable, binaryOperation, unaryOperation, boolean, number, numberWithUnit, percentage } from './grammarFunctions'
const {string, filteredVariable, variable, temporalVariable, binaryOperation, unaryOperation, boolean, number, numberWithUnit, percentage } = require('./grammarFunctions')
const moo = require("moo");

View File

@ -5,7 +5,8 @@ import unitsTranslations from './locales/units.yaml'
import { getSessionStorage } from './utils'
let lang =
new URLSearchParams(document.location.search.substring(1)).get('lang') ||
(typeof document !== 'undefined' &&
new URLSearchParams(document.location.search.substring(1)).get('lang')) ||
getSessionStorage()
?.getItem('lang')
?.match(/^(fr|en)$/)?.[0] ||

View File

@ -1,17 +0,0 @@
import { expect } from 'chai'
import Lib from '../source/engine/index'
describe('indeps', function() {
it('should compute income for indépendant', function() {
let values = Lib.evaluate(['revenu net après impôt'], {
"entreprise . chiffre d'affaires": 70000,
'entreprise . charges': 1000,
indépendant: 'oui',
'auto-entrepreneur': 'non',
'contrat salarié': 'non',
période: 'année'
})
expect(values[0]).to.be.closeTo(39764, 1)
})
})

View File

@ -0,0 +1,287 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`calculate simulations-auto-entrepreneur: aides 1`] = `"[5299,299,5000,0,5000]"`;
exports[`calculate simulations-auto-entrepreneur: aides 2`] = `"[52991,2991,50000,2314,47686]"`;
exports[`calculate simulations-auto-entrepreneur: impôt sur le revenu 1`] = `"[32092,7092,25000,706,24294]"`;
exports[`calculate simulations-auto-entrepreneur: périodes 1`] = `"[128,28,100,0,100]"`;
exports[`calculate simulations-auto-entrepreneur: périodes 2`] = `"[642,142,500,0,500]"`;
exports[`calculate simulations-auto-entrepreneur: périodes 3`] = `"[1284,284,1000,0,1000]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 1`] = `"[642,142,500,0,500]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 2`] = `"[1284,284,1000,0,1000]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 3`] = `"[2569,569,2000,0,2000]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 4`] = `"[6422,1422,5000,0,5000]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 5`] = `"[12844,2844,10000,0,10000]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 6`] = `"[25688,5688,20000,0,20000]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 7`] = `"[64221,14221,50000,3835,46165]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 8`] = `"[89910,19910,70000,7688,62312]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 9`] = `"[128442,28442,100000,13468,86532]"`;
exports[`calculate simulations-auto-entrepreneur: échelle de revenus 10`] = `"[1284423,284423,1000000,282020,717980]"`;
exports[`calculate simulations-indépendant: acre 1`] = `"[73015,23015,50000,51980,8237,41763,null,73015]"`;
exports[`calculate simulations-indépendant: activité 1`] = `"[29091,9091,20000,20787,1224,18776,null,29091]"`;
exports[`calculate simulations-indépendant: activité 2`] = `"[29108,9108,20000,20787,1224,18776,null,29108]"`;
exports[`calculate simulations-indépendant: impôt sur le revenu 1`] = `"[29091,9091,20000,20787,728,19272,null,29091]"`;
exports[`calculate simulations-indépendant: impôt sur le revenu 2`] = `"[73015,23015,50000,51980,8317,41683,null,73015]"`;
exports[`calculate simulations-indépendant: impôt sur le revenu 3`] = `"[29091,9091,20000,20787,2079,17921,null,29091]"`;
exports[`calculate simulations-indépendant: inversions 1`] = `"[2000,1369,631,683,0,631,null,2000]"`;
exports[`calculate simulations-indépendant: inversions 2`] = `"[50000,16017,33983,35338,3743,30240,null,50000]"`;
exports[`calculate simulations-indépendant: inversions 3`] = `"[14592,4592,10000,10393,0,10000,null,14592]"`;
exports[`calculate simulations-indépendant: inversions 4`] = `"[88759,27318,61441,63848,11441,50000,null,88759]"`;
exports[`calculate simulations-indépendant: inversions 5`] = `"[14592,4592,10000,10393,0,10000,null,15592]"`;
exports[`calculate simulations-indépendant: inversions 6`] = `"[19000,5926,13074,13588,0,13074,1000,20000]"`;
exports[`calculate simulations-indépendant: inversions 7`] = `"[18000,5623,12377,12863,0,12377,2000,20000]"`;
exports[`calculate simulations-indépendant: période 1`] = `"[1455,455,1000,1039,0,1000,null,1455]"`;
exports[`calculate simulations-indépendant: période 2`] = `"[7239,2239,5000,5196,920,4080,null,7239]"`;
exports[`calculate simulations-indépendant: échelle de revenus 1`] = `"[1840,1340,500,547,0,500,null,1840]"`;
exports[`calculate simulations-indépendant: échelle de revenus 2`] = `"[2448,1448,1000,1064,0,1000,null,2448]"`;
exports[`calculate simulations-indépendant: échelle de revenus 3`] = `"[3056,1556,1500,1580,0,1500,null,3056]"`;
exports[`calculate simulations-indépendant: échelle de revenus 4`] = `"[3664,1664,2000,2097,0,2000,null,3664]"`;
exports[`calculate simulations-indépendant: échelle de revenus 5`] = `"[7423,2423,5000,5199,0,5000,null,7423]"`;
exports[`calculate simulations-indépendant: échelle de revenus 6`] = `"[14592,4592,10000,10393,0,10000,null,14592]"`;
exports[`calculate simulations-indépendant: échelle de revenus 7`] = `"[139472,39472,100000,103784,24383,75617,null,139472]"`;
exports[`calculate simulations-indépendant: échelle de revenus 8`] = `"[1239593,239593,1000000,1033657,467702,532298,null,1239593]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 1`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 2`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 3`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 4`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - activités 5`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - avec charges 1`] = `"[5291,5291,5306,4,10,12]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - avec charges 2`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - périodes 1`] = `"[80,80,98,1,2,3]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - périodes 2`] = `"[251,251,261,2,6,7]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - périodes 3`] = `"[2485,2808,2693,4,45,71]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 1`] = `"[169,169,139,0,1,1]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 2`] = `"[738,738,323,0,2,2]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 3`] = `"[2446,2446,2588,2,5,6]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 4`] = `"[5291,5291,5306,4,10,12]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 5`] = `"[10982,10982,10742,4,19,23]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 6`] = `"[25686,28055,27050,4,45,59]"`;
exports[`calculate simulations-rémunération-dirigeant: Assimilé salarié - échelle de rémunération 7`] = `"[46640,57031,52655,4,45,119]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 1`] = `"[15580,15580,6600,4,18,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 2`] = `"[15560,15560,0,4,18,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 3`] = `"[15444,15444,7047,4,14,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 4`] = `"[17417,17417,4093,3,8,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - activités 5`] = `"[17417,17417,4093,3,8,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - avec charges 1`] = `"[7343,7343,4228,3,8,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - avec charges 2`] = `"[11286,12250,12332,4,24,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - périodes 1`] = `"[156,156,20,0,0,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - périodes 2`] = `"[389,389,176,2,0,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - périodes 3`] = `"[3626,3893,1762,4,41,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 1`] = `"[779,779,102,0,0,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 2`] = `"[1557,1557,205,0,0,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 3`] = `"[3893,3893,1762,2,0,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 4`] = `"[7786,7786,3523,3,7,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 5`] = `"[15571,15571,7047,4,14,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 6`] = `"[36823,38928,17617,4,34,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Auto-entrepreneur - échelle de rémunération 7`] = `"[68654,77856,30496,4,56,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 1`] = `"[13772,13772,10085,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 2`] = `"[14563,14571,0,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 3`] = `"[13761,13761,10077,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 4`] = `"[13772,13772,10085,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - activités 5`] = `"[13772,13772,10085,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - avec charges 1`] = `"[6797,6797,4979,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - avec charges 2`] = `"[13772,13772,10085,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - périodes 1`] = `"[80,80,60,3,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - périodes 2`] = `"[327,327,240,3,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - périodes 3`] = `"[2927,3397,2422,4,56,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 1`] = `"[0,0,36807,3,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 2`] = `"[631,631,481,3,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 3`] = `"[3100,3100,2278,3,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 4`] = `"[6797,6797,4979,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 5`] = `"[13772,13772,10085,4,21,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 6`] = `"[30240,33983,24902,4,48,0]"`;
exports[`calculate simulations-rémunération-dirigeant: Indépendant - échelle de rémunération 7`] = `"[56157,69988,36158,4,56,0]"`;
exports[`calculate simulations-salarié: aides 1`] = `"[2302,0,0,2000,1561,1477]"`;
exports[`calculate simulations-salarié: aides 2`] = `"[12823,0,0,10000,8910,7652]"`;
exports[`calculate simulations-salarié: apprentissage 1`] = `"[1551,0,0,1500,1446,1446]"`;
exports[`calculate simulations-salarié: apprentissage 2`] = `"[1384,167,0,1500,1446,1446]"`;
exports[`calculate simulations-salarié: assimilé salarié 1`] = `"[7014,0,0,5000,3943,3304]"`;
exports[`calculate simulations-salarié: assimilé salarié 2`] = `"[1583,0,0,1500,1163,1163]"`;
exports[`calculate simulations-salarié: assimilé salarié 3`] = `"[3742,0,0,3000,2348,2150]"`;
exports[`calculate simulations-salarié: atmp 1`] = `"[2549,0,0,2000,1561,1477]"`;
exports[`calculate simulations-salarié: avantages 1`] = `"[2682,0,0,2000,1540,1440]"`;
exports[`calculate simulations-salarié: avantages 2`] = `"[2692,0,0,2000,1539,1438]"`;
exports[`calculate simulations-salarié: avantages 3`] = `"[2602,0,0,2000,1549,1455]"`;
exports[`calculate simulations-salarié: cadre 1`] = `"[4122,0,0,3000,2348,2149]"`;
exports[`calculate simulations-salarié: cdd 1`] = `"[2494,0,0,2000,1561,1477]"`;
exports[`calculate simulations-salarié: cdd 2`] = `"[2494,0,0,2000,1561,1477]"`;
exports[`calculate simulations-salarié: heures supplémentaires 1`] = `"[2642,0,0,2000,1636,1551]"`;
exports[`calculate simulations-salarié: heures supplémentaires 2`] = `"[3349,0,0,2000,2009,1914]"`;
exports[`calculate simulations-salarié: heures supplémentaires 3`] = `"[2713,0,0,2000,1636,1551]"`;
exports[`calculate simulations-salarié: heures supplémentaires 4`] = `"[2623,0,0,2000,1627,1543]"`;
exports[`calculate simulations-salarié: heures supplémentaires 5`] = `"[3291,0,0,2000,1970,1885]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 1`] = `"[4076,0,0,3000,2353,2168]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 2`] = `"[41765,0,0,30000,24267,14656]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 3`] = `"[4076,0,0,3000,2353,2270]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 4`] = `"[4076,0,0,3000,2353,2205]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 5`] = `"[41765,0,0,30000,24267,14656]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 6`] = `"[4076,0,0,3000,2353,2242]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 7`] = `"[41765,0,0,30000,24267,15913]"`;
exports[`calculate simulations-salarié: impôt sur le revenu 8`] = `"[4076,0,0,3000,2353,2107]"`;
exports[`calculate simulations-salarié: inversions 1`] = `"[2000,0,0,1738,1354,1317]"`;
exports[`calculate simulations-salarié: inversions 2`] = `"[3474,0,0,2554,2000,1852]"`;
exports[`calculate simulations-salarié: inversions 3`] = `"[3764,0,0,2769,2170,2000]"`;
exports[`calculate simulations-salarié: périodes 1`] = `"[3405,0,0,3000,2112,2112]"`;
exports[`calculate simulations-salarié: périodes 2`] = `"[61150,0,0,45000,35349,31190]"`;
exports[`calculate simulations-salarié: périodes 3`] = `"[674660,0,0,500000,417064,243499]"`;
exports[`calculate simulations-salarié: stage 1`] = `"[507,0,0,500,500,500]"`;
exports[`calculate simulations-salarié: stage 2`] = `"[2493,0,0,2000,1749,1749]"`;
exports[`calculate simulations-salarié: temps partiel 1`] = `"[2605,0,2188,2000,1561,1477]"`;
exports[`calculate simulations-salarié: temps partiel 2`] = `"[2533,0,2500,1857,1448,1390]"`;
exports[`calculate simulations-salarié: échelle de salaires 1`] = `"[130,0,0,100,57,57]"`;
exports[`calculate simulations-salarié: échelle de salaires 2`] = `"[284,0,0,250,176,176]"`;
exports[`calculate simulations-salarié: échelle de salaires 3`] = `"[541,0,0,500,374,374]"`;
exports[`calculate simulations-salarié: échelle de salaires 4`] = `"[798,0,0,750,572,572]"`;
exports[`calculate simulations-salarié: échelle de salaires 5`] = `"[1055,0,0,1000,770,770]"`;
exports[`calculate simulations-salarié: échelle de salaires 6`] = `"[1312,0,0,1250,968,968]"`;
exports[`calculate simulations-salarié: échelle de salaires 7`] = `"[1569,0,0,1500,1165,1165]"`;
exports[`calculate simulations-salarié: échelle de salaires 8`] = `"[2494,0,0,2000,1561,1477]"`;
exports[`calculate simulations-salarié: échelle de salaires 9`] = `"[3401,0,0,2500,1957,1815]"`;
exports[`calculate simulations-salarié: échelle de salaires 10`] = `"[4076,0,0,3000,2353,2159]"`;
exports[`calculate simulations-salarié: échelle de salaires 11`] = `"[5674,0,0,4000,3146,2744]"`;
exports[`calculate simulations-salarié: échelle de salaires 12`] = `"[7085,0,0,5000,3948,3321]"`;
exports[`calculate simulations-salarié: échelle de salaires 13`] = `"[14319,0,0,10000,7959,6069]"`;
exports[`calculate simulations-salarié: échelle de salaires 14`] = `"[28336,0,0,20000,15969,10941]"`;
exports[`calculate simulations-salarié: échelle de salaires 15`] = `"[128506,0,0,100000,87197,50180]"`;
exports[`calculate simulations-salarié: échelle de salaires 16`] = `"[1243750,0,0,1000000,896297,451743]"`;

View File

@ -0,0 +1,30 @@
échelle de revenus:
- auto-entrepreneur . revenu net de cotisations: 500
- auto-entrepreneur . revenu net de cotisations: 1000
- auto-entrepreneur . revenu net de cotisations: 2000
- auto-entrepreneur . revenu net de cotisations: 5000
- auto-entrepreneur . revenu net de cotisations: 10000
- auto-entrepreneur . revenu net de cotisations: 20000
- auto-entrepreneur . revenu net de cotisations: 50000
- auto-entrepreneur . revenu net de cotisations: 70000
- auto-entrepreneur . revenu net de cotisations: 100000
- auto-entrepreneur . revenu net de cotisations: 1000000
périodes:
- auto-entrepreneur . revenu net de cotisations: 100
période: mois
- auto-entrepreneur . revenu net de cotisations: 500
période: mois
- auto-entrepreneur . revenu net de cotisations: 1000
période: mois
aides:
- auto-entrepreneur . revenu net de cotisations: 5000
entreprise . ACRE: true
- auto-entrepreneur . revenu net de cotisations: 50000
entreprise . ACRE: true
impôt sur le revenu:
- auto-entrepreneur . revenu net de cotisations: 25000
entreprise . catégorie d'activité: 'libérale'
auto-entrepreneur . impôt . versement libératoire: true

View File

@ -0,0 +1,46 @@
échelle de revenus:
- indépendant . revenu net de cotisations: 500
- indépendant . revenu net de cotisations: 1000
- indépendant . revenu net de cotisations: 1500
- indépendant . revenu net de cotisations: 2000
- indépendant . revenu net de cotisations: 5000
- indépendant . revenu net de cotisations: 10000
- indépendant . revenu net de cotisations: 100000
- indépendant . revenu net de cotisations: 1000000
période:
- indépendant . revenu net de cotisations: 1000
période: mois
- indépendant . revenu net de cotisations: 5000
période: mois
inversions:
- entreprise . rémunération totale du dirigeant: 2000
- entreprise . rémunération totale du dirigeant: 50000
- revenu net après impôt: 10000
- revenu net après impôt: 50000
- revenu net après impôt: 10000
entreprise . charges: 1000
- entreprise . chiffre d'affaires minimum: 20000
entreprise . charges: 1000
- entreprise . chiffre d'affaires minimum: 20000
entreprise . charges: 2000
activité:
- indépendant . revenu net de cotisations: 20000
entreprise . catégorie d'activité: libérale
- indépendant . revenu net de cotisations: 20000
entreprise . catégorie d'activité: artisanale
acre:
- indépendant . revenu net de cotisations: 50000
entreprise . ACRE: true
impôt sur le revenu:
- indépendant . revenu net de cotisations: 20000
impôt . méthode de calcul: taux neutre
- indépendant . revenu net de cotisations: 50000
impôt . méthode de calcul: taux neutre
- indépendant . revenu net de cotisations: 20000
impôt . méthode de calcul: taux personnalisé
impôt . taux personnalisé: 0.1

View File

@ -0,0 +1,38 @@
échelle de rémunération:
- entreprise . rémunération totale du dirigeant: 1000
- entreprise . rémunération totale du dirigeant: 2000
- entreprise . rémunération totale du dirigeant: 5000
- entreprise . rémunération totale du dirigeant: 10000
- entreprise . rémunération totale du dirigeant: 20000
- entreprise . rémunération totale du dirigeant: 50000
- entreprise . rémunération totale du dirigeant: 100000
périodes:
- entreprise . rémunération totale du dirigeant: 200
période: mois
- entreprise . rémunération totale du dirigeant: 500
période: mois
- entreprise . rémunération totale du dirigeant: 5000
période: mois
avec charges:
- entreprise . rémunération totale du dirigeant: 10000
entreprise . charges: 2000
- entreprise . rémunération totale du dirigeant: 20000
entreprise . charges: 15000
activités:
- entreprise . rémunération totale du dirigeant: 20000
entreprise . catégorie d'activité: libérale
- entreprise . rémunération totale du dirigeant: 20000
entreprise . catégorie d'activité: libérale
entreprise . catégorie d'activité . libérale règlementée: true
- entreprise . rémunération totale du dirigeant: 20000
entreprise . catégorie d'activité: artisanale
- entreprise . rémunération totale du dirigeant: 20000
entreprise . catégorie d'activité: commerciale ou industrielle
entreprise . catégorie d'activité . service ou vente: vente de biens
- entreprise . rémunération totale du dirigeant: 20000
entreprise . catégorie d'activité: commerciale ou industrielle
entreprise . catégorie d'activité . service ou vente: prestation de service
entreprise . catégorie d'activité . restauration ou hébergement: true

View File

@ -0,0 +1,138 @@
échelle de salaires:
- contrat salarié . rémunération . brut de base: 100
- contrat salarié . rémunération . brut de base: 250
- contrat salarié . rémunération . brut de base: 500
- contrat salarié . rémunération . brut de base: 750
- contrat salarié . rémunération . brut de base: 1000
- contrat salarié . rémunération . brut de base: 1250
- contrat salarié . rémunération . brut de base: 1500
- contrat salarié . rémunération . brut de base: 2000
- contrat salarié . rémunération . brut de base: 2500
- contrat salarié . rémunération . brut de base: 3000
- contrat salarié . rémunération . brut de base: 4000
- contrat salarié . rémunération . brut de base: 5000
- contrat salarié . rémunération . brut de base: 10000
- contrat salarié . rémunération . brut de base: 20000
- contrat salarié . rémunération . brut de base: 100000
- contrat salarié . rémunération . brut de base: 1000000
périodes:
- contrat salarié . rémunération . brut de base: 3000
période: année
- contrat salarié . rémunération . brut de base: 45000
période: année
- contrat salarié . rémunération . brut de base: 500000
période: année
inversions:
- contrat salarié . prix du travail: 2000
- contrat salarié . rémunération . net: 2000
- contrat salarié . rémunération . net après impôt: 2000
stage:
- contrat salarié: stage
contrat salarié . rémunération . brut de base: 500
- contrat salarié: stage
contrat salarié . rémunération . brut de base: 2000
apprentissage:
- contrat salarié: apprentissage
contrat salarié . rémunération . brut de base: 1500
- contrat salarié: apprentissage
contrat salarié . rémunération . brut de base: 1500
contrat salarié . apprentissage . diplôme préparé: niveau bac ou moins
contrat salarié . apprentissage . ancienneté: moins de deux ans
cadre:
- contrat salarié . rémunération . brut de base: 3000
contrat salarié . statut cadre: true
cdd:
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . cdd: true
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . cdd: true
contrat salarié . cdd . durée contrat: 6
contrat salarié . CDD . congés non pris: 3
atmp:
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . ATMP . taux collectif ATMP: 0.05
assimilé salarié:
- contrat salarié . assimilé salarié: true
contrat salarié . rémunération . brut de base: 5000
- contrat salarié . assimilé salarié: true
contrat salarié . rémunération . brut de base: 1500
entreprise . ACRE: true
- contrat salarié . assimilé salarié: true
contrat salarié . rémunération . brut de base: 3000
entreprise . ACRE: true
aides:
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . statut JEI: true
- contrat salarié . rémunération . brut de base: 10000
contrat salarié . régime des impatriés: true
temps partiel:
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . temps partiel: true
- contrat salarié . rémunération . brut de base . équivalent temps plein: 2500
contrat salarié . temps de travail . temps partiel: true
contrat salarié . temps de travail . temps partiel . heures par semaine: 26
impôt sur le revenu:
- contrat salarié . rémunération . brut de base: 3000
impôt . méthode de calcul: taux neutre
- contrat salarié . rémunération . brut de base: 30000
impôt . méthode de calcul: taux neutre
- contrat salarié . rémunération . brut de base: 3000
impôt . méthode de calcul: taux neutre
contrat salarié . CDD: true
contrat salarié . CDD . durée contrat: 2
- contrat salarié . rémunération . brut de base: 3000
impôt . méthode de calcul: taux neutre
établissement . localisation . département: Guadeloupe
- contrat salarié . rémunération . brut de base: 30000
impôt . méthode de calcul: taux neutre
établissement . localisation . département: Guadeloupe
- contrat salarié . rémunération . brut de base: 3000
impôt . méthode de calcul: taux neutre
établissement . localisation . département: Mayotte
- contrat salarié . rémunération . brut de base: 30000
impôt . méthode de calcul: taux neutre
établissement . localisation . département: Mayotte
- contrat salarié . rémunération . brut de base: 3000
impôt . méthode de calcul: taux personnalisé
impôt . taux personnalisé: 0.1
heures supplémentaires:
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 5
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 30
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 5
entreprise . effectif: 100
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 5
entreprise . hôtel café restaurant: true
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . temps de travail . heures supplémentaires: 30
entreprise . hôtel café restaurant: true
avantages:
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . rémunération . avantages en nature: true
contrat salarié . rémunération . avantages en nature . montant: 100
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . rémunération . avantages en nature: true
contrat salarié . rémunération . avantages en nature . autres: true
contrat salarié . rémunération . avantages en nature . autres . montant: 100
contrat salarié . rémunération . avantages en nature . ntic . coût appareils: 400
contrat salarié . rémunération . avantages en nature . ntic . abonnements: 20
- contrat salarié . rémunération . brut de base: 2000
contrat salarié . rémunération . avantages en nature: true
contrat salarié . rémunération . avantages en nature . nourriture: true
contrat salarié . rémunération . avantages en nature . nourriture . repas par mois: 10

View File

@ -0,0 +1,73 @@
// The goal of these tests is to avoid deploying unwanted changes in the calculations. We run a number
// of simulations and persist their results in a snapshot (ie, a file commited in git). Our test runner,
// Jest, then compare the existing snapshot with the current Engine calculation and reports any difference.
//
// We only persist goals values in the file system, in order to be resilient to rule renaming (if a rule is
// renamed the test configuration may be adapted but the persisted snapshot will remain unchanged).
/* eslint-disable no-undef */
import Lib from '../../source/engine/index'
import employeeConfig from '../../source/components/simulationConfigs/salarié.yaml'
import independantConfig from '../../source/components/simulationConfigs/indépendant.yaml'
import autoentrepreneurConfig from '../../source/components/simulationConfigs/auto-entrepreneur.yaml'
import remunerationDirigeantConfig from '../../source/components/simulationConfigs/rémunération-dirigeant.yaml'
import employeeSituations from './simulations-salarié.yaml'
import independentSituations from './simulations-indépendant.yaml'
import autoEntrepreneurSituations from './simulations-auto-entrepreneur.yaml'
import remunerationDirigeantSituations from './simulations-rémunération-dirigeant.yaml'
const roundResult = arr => arr.map(x => Math.round(x))
const runSimulations = (
situations,
goals,
baseSituation = {},
namePrefix = ''
) =>
Object.entries(situations).map(([name, situations]) =>
situations.forEach(situation => {
const res = Lib.evaluate(goals, { ...baseSituation, ...situation })
// Stringify is not required, but allows the result to be displayed in a single
// line in the snapshot, which considerably reduce the number of lines of this snapshot
// and improve its readability.
expect(JSON.stringify(roundResult(res))).toMatchSnapshot(
namePrefix + name
)
})
)
it('calculate simulations-salarié', () => {
runSimulations(
employeeSituations,
employeeConfig.objectifs,
employeeConfig.situation
)
})
it('calculate simulations-indépendant', () => {
const goals = independantConfig.objectifs.reduce(
(acc, cur) => [...acc, ...cur.objectifs],
[]
)
runSimulations(independentSituations, goals, independantConfig.situation)
})
it('calculate simulations-auto-entrepreneur', () => {
runSimulations(
autoEntrepreneurSituations,
autoentrepreneurConfig.objectifs,
autoentrepreneurConfig.situation
)
})
it('calculate simulations-rémunération-dirigeant', () => {
const baseSituation = remunerationDirigeantConfig.situation
remunerationDirigeantConfig.branches.forEach(({ nom, situation }) => {
runSimulations(
remunerationDirigeantSituations,
remunerationDirigeantConfig.objectifs,
{ ...baseSituation, ...situation },
`${nom} - `
)
})
})

View File

@ -0,0 +1,3 @@
// https://jestjs.io/docs/en/webpack
module.exports = {}

1406
yarn.lock

File diff suppressed because it is too large Load Diff