gestion_table_tournante_libre/test/chargements.test.js
Mathieu Benoit 4795114093 [ADD] tests: budget reporter, one import parser, key-order guard
The time budget of § 14.14 had no enforcement: a reporter now prints the
total and the ten slowest tests, and fails a run whose node project
exceeds 30 s or node-long 60 s. Two guards parsed imports with two
patterns, one blind past an apostrophe in a comment; both now use one
parser anchored on « from ». The determinism guard refuses key-order
walks, and one test binds the application name across its three
declarations. The end-to-end generations drop to 100 000 moves.

Checked: each ceiling, the apostrophe case and a key walk are shown
failing before the guard that catches them.

--- FR ---

[ADD] épreuves : rapporteur de budget, imports, ordre des clés

Le budget de temps du § 14.14 n'avait aucune garde : un rapporteur
imprime désormais la durée totale et les dix épreuves les plus lentes,
et fait échouer une exécution dont le projet node dépasse 30 s ou
node-long 60 s. Deux gardes lisaient les imports par deux motifs, l'un
aveugle après une apostrophe en commentaire ; les deux passent par un
seul analyseur ancré sur « from ». La garde de déterminisme refuse les
parcours de clés, et une épreuve lie le nom de l'application à ses
trois déclarations. Les générations de bout en bout passent à 100 000.

Vérifié : chaque plafond, le cas de l'apostrophe et un parcours de clés
sont montrés en échec avant la garde qui les attrape.

Assisted-by: Claude Opus 5.5
2026-10-06 04:23:13 -04:00

91 lines
3.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// L'analyseur des chargements, test/chargements.js, que lisent les gardes de
// l'arborescence et du livrable. Chaque épreuve donne un texte et les
// chargements qu'il demande, dans l'ordre du texte. Les spécificateurs nus
// des données sont des paquets de devDependencies ou des modules de Node :
// la garde des dépendances lit aussi ce fichier.
import assert from 'node:assert/strict';
import { chargements } from './chargements.js';
import { describe, test } from './lanceur.js';
// Numéro, à partir de 1, de la ligne qui porte le caractère d'indice donné.
const ligneDe = (texte, indice) => texte.slice(0, indice).split('\n').length;
// Chaque chargement d'un texte, en « ligne spécificateur », ou en « ligne
// calculé argument » pour un argument qui n'est pas une chaîne littérale.
const lus = (texte) =>
chargements(texte).map(({ indice, specificateur, argument }) =>
specificateur === undefined
? `${ligneDe(texte, indice)} calculé ${argument}`
: `${ligneDe(texte, indice)} ${specificateur}`,
);
describe('chargements', () => {
test("un import dont les accolades portent un commentaire à apostrophe se relève, comme celui qui le suit", () => {
const texte = [
'import {',
" // l'écran d'accueil",
' App,',
"} from '../interface/App.svelte';",
"import { a } from './a.js';",
].join('\n');
assert.deepEqual(
chargements(texte).map(({ specificateur }) => specificateur),
['../interface/App.svelte', './a.js'],
);
});
test('import et export à from, import seul, import() et require() de chaîne, avec ou sans options, se relèvent à leur ligne, dans l’ordre du texte', () => {
const texte = [
"import { a } from './a.js';",
'import b, { c } from "../b.js";',
"export * from './c.js';",
"export { d } from'./d.js';",
"import 'svelte';",
'const e = require("electron");',
"const f = await import('node:fs', { with: {} });",
'const g = await import(`vitest`);',
"import * as h from 'svelte/store'; const i = require('./i.cjs');",
].join('\n');
assert.deepEqual(lus(texte), [
'1 ./a.js',
'2 ../b.js',
'3 ./c.js',
'4 ./d.js',
'5 svelte',
'6 electron',
'7 node:fs',
'8 vitest',
'9 svelte/store',
'9 ./i.cjs',
]);
});
test("un argument qui n'est pas une chaîne littérale se relève comme calculé, sans spécificateur", () => {
const texte = [
'const a = require(nom);',
'const b = await import(`./${module}.js`);',
"const c = require('./' + nom);",
'const d = await import( cible );',
].join('\n');
assert.deepEqual(lus(texte), [
'1 calculé nom',
'2 calculé `./${module}.js`',
"3 calculé './' + nom",
'4 calculé cible',
]);
});
test("ni une chaîne qui finit sur « import », ni la règle @import d'une feuille de style ne sont des chargements", () => {
const texte = [
"spawnSync(process.execPath, ['--import', 'chargeur.js']);",
'<style>',
" @import 'jetons.css';",
'</style>',
"const mot = 'import';",
].join('\n');
assert.deepEqual(lus(texte), []);
});
});