[ADD] tests: per-module coverage, 100 % branch floors, layer guards
make couverture runs the node series under V8 instrumentation and prints one row per module, full ones included, plus a line-by-line HTML report. Four modules hold a hard 100 % branch floor — indicateurs.js, plafond.js, depot.js, journal.js — and the command fails below it; there is no global threshold, which covering the easy modules would satisfy. The tree guard refuses a lowered or global floor, a floor on a file the measure never loads, and a command that does not measure. It extends determinism and layer boundaries to src/stockage, src/csv and src/application (§ 13.4), and no longer takes a string literal for DOM access. Checked: 1266 node tests; the four floors at 100 %. --- FR --- [ADD] épreuves : couverture par module, seuils durs, gardes des couches make couverture joue la série node sous l'instrumentation de V8 et imprime une ligne par module, pleins compris, et un rapport HTML ligne à ligne. Quatre modules tiennent un seuil dur de 100 % des branches — indicateurs.js, plafond.js, depot.js, journal.js — et la commande échoue en deçà ; aucun seuil global, qu'on satisferait en couvrant les modules faciles. La garde de l'arborescence refuse un seuil abaissé ou global, un seuil sur un fichier que la mesure ne charge pas, et une commande qui ne mesure pas. Elle étend le déterminisme et les frontières des couches à src/stockage, src/csv et src/application (§ 13.4), et ne prend plus une chaîne littérale pour le DOM. Vérifié : 1266 épreuves node ; les quatre seuils à 100 %. Assisted-by: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01EUXSGcwCLSC69FWEdCtWSb
This commit is contained in:
parent
fa32ad9fae
commit
aa5fafab1a
5 changed files with 933 additions and 98 deletions
4
Makefile
4
Makefile
|
|
@ -64,6 +64,10 @@ test_navigateur: ## Joue les épreuves du navigateur, sous Chromium
|
|||
test_tout: ## Joue les trois séries
|
||||
$(AVEC_NODE) npm run test:tout
|
||||
|
||||
.PHONY: couverture
|
||||
couverture: ## Mesure la couverture de la série node, module par module ; seuils durs du § 14.13
|
||||
$(AVEC_NODE) npm run couverture
|
||||
|
||||
.PHONY: build
|
||||
build: ## Construit la page dans www/
|
||||
$(AVEC_NODE) npm run build
|
||||
|
|
|
|||
144
package-lock.json
generated
144
package-lock.json
generated
|
|
@ -13,6 +13,7 @@
|
|||
"@capacitor/core": "^8.5.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^7.3.1",
|
||||
"@vitest/browser-playwright": "^5.0.3",
|
||||
"@vitest/coverage-v8": "^5.0.3",
|
||||
"electron": "^44.5.1",
|
||||
"electron-builder": "^26.15.3",
|
||||
"fast-check": "^4.10.2",
|
||||
|
|
@ -22,6 +23,66 @@
|
|||
"vitest": "^5.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-string-parser": {
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
|
||||
"integrity": "sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/helper-validator-identifier": {
|
||||
"version": "7.29.7",
|
||||
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.29.7.tgz",
|
||||
"integrity": "sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/parser": {
|
||||
"version": "7.29.9",
|
||||
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.9.tgz",
|
||||
"integrity": "sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/types": "^7.29.8"
|
||||
},
|
||||
"bin": {
|
||||
"parser": "bin/babel-parser.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@babel/types": {
|
||||
"version": "7.29.8",
|
||||
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz",
|
||||
"integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/helper-string-parser": "^7.29.7",
|
||||
"@babel/helper-validator-identifier": "^7.29.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=6.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@bcoe/v8-coverage": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
|
||||
"integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@blazediff/core": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@blazediff/core/-/core-1.10.0.tgz",
|
||||
|
|
@ -1249,6 +1310,58 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-5.0.3.tgz",
|
||||
"integrity": "sha512-+klsyz7BvT1vCU28Zkfzms1Ia78XD0V41U3FUtRaa3S+vOr/EXvK1O6BvVD7l1RzEjm6SONR2aybOvDDf9u0mQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@bcoe/v8-coverage": "^1.0.2",
|
||||
"@vitest/istanbul-lib-coverage": "^1.0.0",
|
||||
"@vitest/istanbul-lib-report": "^1.0.0",
|
||||
"ast-v8-to-istanbul": "^1.0.5",
|
||||
"magicast": "^0.5.4",
|
||||
"obug": "^2.1.4",
|
||||
"std-env": "^4.2.0",
|
||||
"tinyrainbow": "^3.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@vitest/browser": "5.0.3",
|
||||
"vitest": "5.0.3"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@vitest/browser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/istanbul-lib-coverage": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.2.tgz",
|
||||
"integrity": "sha512-9J/JMwOf9AoJhAywhrn7ScKTL38hsWQP/qPG60OtaAFcQ5OXPwKsxZFlbnuCKmZ61m8/lGgHYnFpdyQZUvG/iA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/istanbul-lib-report": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/istanbul-lib-report/-/istanbul-lib-report-1.0.2.tgz",
|
||||
"integrity": "sha512-gUsfXZJbzPamoIY5TvHFiMMoXESBrUMo+xqaj+rYrWI69+EnvRlYBlP96ZnHPY4vX8kyUpgAnFUCg5wZG/HkDQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@vitest/istanbul-lib-coverage": "1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=22"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker": {
|
||||
"version": "5.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-5.0.3.tgz",
|
||||
|
|
@ -1693,6 +1806,18 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-v8-to-istanbul": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-1.0.7.tgz",
|
||||
"integrity": "sha512-kFL68AG6ajd8fg248zwM9GQrUWEp79gsmjum34OEXjs4yHuUMZfYKwOLW9GMmB4oNvVrj+EAGxsP7ye2UR9UlA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@jridgewell/trace-mapping": "^0.3.31",
|
||||
"estree-walker": "^3.0.3",
|
||||
"js-tokens": "^10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/astral-regex": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz",
|
||||
|
|
@ -3521,6 +3646,13 @@
|
|||
"jiti": "lib/jiti-cli.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/js-tokens": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz",
|
||||
"integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/js-yaml": {
|
||||
"version": "4.3.2",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.2.tgz",
|
||||
|
|
@ -3936,6 +4068,18 @@
|
|||
"@jridgewell/sourcemap-codec": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"node_modules/magicast": {
|
||||
"version": "0.5.5",
|
||||
"resolved": "https://registry.npmjs.org/magicast/-/magicast-0.5.5.tgz",
|
||||
"integrity": "sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@babel/parser": "^7.29.7",
|
||||
"@babel/types": "^7.29.7",
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/matcher": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz",
|
||||
|
|
|
|||
|
|
@ -17,13 +17,15 @@
|
|||
"test:surveille": "vitest --project node",
|
||||
"test:long": "vitest run --project node-long",
|
||||
"test:navigateur": "vitest run --project navigateur",
|
||||
"test:tout": "vitest run"
|
||||
"test:tout": "vitest run",
|
||||
"couverture": "vitest run --project node --coverage --reporter=default"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@capacitor/cli": "^8.5.2",
|
||||
"@capacitor/core": "^8.5.2",
|
||||
"@sveltejs/vite-plugin-svelte": "^7.3.1",
|
||||
"@vitest/browser-playwright": "^5.0.3",
|
||||
"@vitest/coverage-v8": "^5.0.3",
|
||||
"electron": "^44.5.1",
|
||||
"electron-builder": "^26.15.3",
|
||||
"fast-check": "^4.10.2",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -32,6 +32,32 @@ export default defineConfig({
|
|||
// l'exécution quand node ou node-long dépasse son plafond (§ 14.14). Un
|
||||
// chemin relatif se lit depuis la racine du projet.
|
||||
reporters: ['default', './test/rapporteur.js'],
|
||||
// La couverture (§ 14.13), que lancent npm run couverture et make
|
||||
// couverture : la série node sous l'instrumentation de V8, sans le
|
||||
// rapporteur, dont les plafonds bornent la série surveillée et la série
|
||||
// longue, non une mesure. Aucun seuil global : un pourcentage d'ensemble
|
||||
// se satisfait en couvrant les modules faciles. Le tableau imprime une
|
||||
// ligne par couche et par module de src/, pleins compris — que Vitest
|
||||
// tait sinon quand un agent le lance — et à 0 % ceux qu'aucune épreuve ne
|
||||
// charge ; coverage/index.html montre, ligne à ligne, ce qui n'est jamais
|
||||
// exécuté. Quatre modules tiennent 100 % de branches, seuil dur : la
|
||||
// commande échoue en deçà. Une branche nue s'y couvre par un cas ajouté,
|
||||
// ou part avec le code mort ; le seuil ne s'abaisse pas, et
|
||||
// test/arborescence.test.js garde ces quatre seuils, ces deux rapports
|
||||
// et les deux commandes qui lancent la mesure.
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
include: ['src/**/*.js'],
|
||||
exclude: ['src/**/*.test.js'],
|
||||
reporter: [['text', { skipFull: false }], 'html'],
|
||||
reportsDirectory: 'coverage',
|
||||
thresholds: {
|
||||
'src/moteur/indicateurs.js': { branches: 100 },
|
||||
'src/moteur/plafond.js': { branches: 100 },
|
||||
'src/stockage/depot.js': { branches: 100 },
|
||||
'src/stockage/journal.js': { branches: 100 },
|
||||
},
|
||||
},
|
||||
// Sous surveillance, une épreuve se relance quand un module de son graphe
|
||||
// d'imports change. Les fichiers des motifs se lisent hors de tout
|
||||
// graphe : le contrôle de version (§ 18.5) lit les premiers par le
|
||||
|
|
|
|||
Loading…
Reference in a new issue