gestion_table_tournante_libre/src/interface/apropos.test.js

122 lines
5.9 KiB
JavaScript
Raw Normal View History

[ADD] interface: application shell — banner, sections, theme, about The window showed only a banner; it now holds the application. App mounts the session, the facade and the generation, settles the working folder and lists its events before it reports ready, re-reading the list once a question is answered or a refused determination succeeds. The banner carries version, mode and the event list command; an open event shows its sections in their first form; the theme follows the system at each start and the operator's choice lasts the session; À propos names the build. Errors are collected for a report, and Electron removes the session's locks at exit. Checked: 2189 node, 193 browser, 60 node-long; the Electron start check. --- FR --- [ADD] interface : coquille — bandeau, sections, thème, À propos La fenêtre ne montrait qu'un bandeau ; elle tient désormais l'application. App monte la séance, la façade et la génération, règle le dossier de travail et liste ses événements avant de se dire prête, et relit la liste une fois une question répondue ou une détermination refusée réussie. Le bandeau porte version, mode et la commande de la liste ; un événement ouvert montre ses sections dans leur première forme ; le thème suit le système à chaque démarrage et le choix de l'opérateur vaut pour la séance ; À propos nomme la construction. Les erreurs se collectent pour un signalement, et Electron efface à la sortie les verrous de la séance. Vérifié : 2189 node, 193 navigateur, 60 node-long ; démarrage d'Electron. Assisted-by: Claude Opus 5.5
2026-10-07 07:22:05 -04:00
// © 2026 TechnoLibre (http://www.technolibre.ca)
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
// Le bloc « À propos » (§ 18.6) : une ligne que l'opérateur copie dans un
// courriel — nom, version affichée, version Windows, plateforme, provenance,
// version de format —, et ce qui tient lieu de version à l'écran, la marque
// de provenance dans une construction de documentation (§ 19.4).
import assert from 'node:assert/strict';
import { readFileSync } from 'node:fs';
[ADD] interface: application shell — banner, sections, theme, about The window showed only a banner; it now holds the application. App mounts the session, the facade and the generation, settles the working folder and lists its events before it reports ready, re-reading the list once a question is answered or a refused determination succeeds. The banner carries version, mode and the event list command; an open event shows its sections in their first form; the theme follows the system at each start and the operator's choice lasts the session; À propos names the build. Errors are collected for a report, and Electron removes the session's locks at exit. Checked: 2189 node, 193 browser, 60 node-long; the Electron start check. --- FR --- [ADD] interface : coquille — bandeau, sections, thème, À propos La fenêtre ne montrait qu'un bandeau ; elle tient désormais l'application. App monte la séance, la façade et la génération, règle le dossier de travail et liste ses événements avant de se dire prête, et relit la liste une fois une question répondue ou une détermination refusée réussie. Le bandeau porte version, mode et la commande de la liste ; un événement ouvert montre ses sections dans leur première forme ; le thème suit le système à chaque démarrage et le choix de l'opérateur vaut pour la séance ; À propos nomme la construction. Les erreurs se collectent pour un signalement, et Electron efface à la sortie les verrous de la séance. Vérifié : 2189 node, 193 navigateur, 60 node-long ; démarrage d'Electron. Assisted-by: Claude Opus 5.5
2026-10-07 07:22:05 -04:00
import { describe, test } from '../../test/lanceur.js';
import { TABLES_APPLICATION } from '../application/libelles.js';
import { MARQUE_TEMOIN, creerTraduction } from '../application/traduction.js';
import { FORMAT } from '../stockage/document.js';
import { VERSION } from '../version.genere.js';
import { blocAPropos, provenanceVisible, versionVisible } from './apropos.js';
import { TABLES_INTERFACE, libelleProvenance } from './libelles.js';
const { t } = creerTraduction([...TABLES_APPLICATION, ...TABLES_INTERFACE]);
const temoin = creerTraduction([...TABLES_APPLICATION, ...TABLES_INTERFACE], { langue: 'temoin' }).t;
describe('blocAPropos (§ 18.6)', () => {
test('une ligne : nom, version affichée, version Windows, plateforme, provenance, format, séparés par « · »', () => {
assert.match(VERSION.windows ?? '', /^\d+\.\d+\.\d+\.0$/, 'VERSION.windows engendré');
const bloc = blocAPropos({ version: VERSION, plateforme: 'electron', provenance: 'livraison', format: FORMAT }, t);
assert.equal(typeof bloc, 'string');
assert.doesNotMatch(bloc, /[\n\r\u{2028}\u{2029}]/u);
assert.deepEqual(bloc.split(' \u{00B7} '), [
t('coquille.nom'),
VERSION.affichee,
VERSION.windows,
'electron',
libelleProvenance('livraison'),
t('coquille.apropos.format', { format: FORMAT }),
]);
assert.ok(bloc.includes(String(FORMAT)));
});
test('chaque plateforme et chaque provenance s’y lisent ; un mode sans libellé sous son propre nom', () => {
const cas = [
['web', 'developpement', libelleProvenance('developpement')],
['epreuve', 'test', libelleProvenance('test')],
['electron', 'documentation', libelleProvenance('documentation')],
['web', 'production', 'production'],
];
assert.ok(cas.length > 0);
for (const [plateforme, provenance, libelle] of cas) {
const champs = blocAPropos({ version: VERSION, plateforme, provenance, format: FORMAT }, t).split(' \u{00B7} ');
assert.equal(champs[3], plateforme, provenance);
assert.equal(champs[4], libelle, provenance);
}
});
test('une forme de la version absente, vide ou qui n’est pas une chaîne lève RangeError en la nommant : jamais un bloc copiable faux', () => {
const fautes = [undefined, null, '', 7];
assert.equal(fautes.length, 4);
for (const faute of fautes) {
for (const [forme, version] of [
['windows', { affichee: VERSION.affichee, windows: faute }],
['affichee', { affichee: faute, windows: VERSION.windows }],
]) {
assert.throws(
() => blocAPropos({ version, plateforme: 'web', provenance: 'test', format: FORMAT }, t),
(erreur) => erreur instanceof RangeError && erreur.message.includes(forme),
`${forme} ${String(faute)}`,
);
}
}
});
[ADD] interface: application shell — banner, sections, theme, about The window showed only a banner; it now holds the application. App mounts the session, the facade and the generation, settles the working folder and lists its events before it reports ready, re-reading the list once a question is answered or a refused determination succeeds. The banner carries version, mode and the event list command; an open event shows its sections in their first form; the theme follows the system at each start and the operator's choice lasts the session; À propos names the build. Errors are collected for a report, and Electron removes the session's locks at exit. Checked: 2189 node, 193 browser, 60 node-long; the Electron start check. --- FR --- [ADD] interface : coquille — bandeau, sections, thème, À propos La fenêtre ne montrait qu'un bandeau ; elle tient désormais l'application. App monte la séance, la façade et la génération, règle le dossier de travail et liste ses événements avant de se dire prête, et relit la liste une fois une question répondue ou une détermination refusée réussie. Le bandeau porte version, mode et la commande de la liste ; un événement ouvert montre ses sections dans leur première forme ; le thème suit le système à chaque démarrage et le choix de l'opérateur vaut pour la séance ; À propos nomme la construction. Les erreurs se collectent pour un signalement, et Electron efface à la sortie les verrous de la séance. Vérifié : 2189 node, 193 navigateur, 60 node-long ; démarrage d'Electron. Assisted-by: Claude Opus 5.5
2026-10-07 07:22:05 -04:00
test('en langue témoin, le bloc entier est encadré une fois', () => {
const bloc = blocAPropos({ version: VERSION, plateforme: 'web', provenance: 'test', format: FORMAT }, temoin);
const { ouverture, fermeture } = MARQUE_TEMOIN;
assert.ok(bloc.startsWith(ouverture) && bloc.endsWith(fermeture), bloc);
assert.equal(bloc.split(ouverture).length, 2, bloc);
assert.equal(bloc.split(fermeture).length, 2, bloc);
});
});
describe('versionVisible (§ 18.6, § 19.4)', () => {
test('la version affichée, hors d’une construction de documentation', () => {
for (const provenance of ['developpement', 'livraison', 'test']) {
assert.equal(versionVisible(provenance, VERSION.affichee, t), VERSION.affichee, provenance);
}
});
test('la marque de provenance, sans le numéro, dans une construction de documentation', () => {
const marque = versionVisible('documentation', VERSION.affichee, t);
assert.equal(marque, t('coquille.version.documentation'));
assert.ok(!marque.includes(VERSION.affichee), marque);
});
});
describe('provenanceVisible (§ 18.6)', () => {
test('le libellé du mode par la traduction reçue ; un mode sans libellé sous son propre nom', () => {
for (const mode of ['developpement', 'livraison', 'documentation', 'test']) {
assert.equal(provenanceVisible(mode, t), libelleProvenance(mode), mode);
}
assert.equal(provenanceVisible('production', t), 'production');
assert.equal(provenanceVisible('constructor', t), 'constructor');
});
test('en langue témoin, le libellé est encadré, le mode sans libellé non : il est une donnée', () => {
const { ouverture, fermeture } = MARQUE_TEMOIN;
assert.equal(provenanceVisible('test', temoin), `${ouverture}${libelleProvenance('test')}${fermeture}`);
assert.equal(provenanceVisible('production', temoin), 'production');
});
});
describe('la version de l’interface vient des dépendances (§ 13.4, § 18.6)', () => {
test('App.svelte ne lit pas la version engendrée : la version affichée et la forme Windows arrivent par ses propriétés, produitVersion et versionWindows', () => {
const source = readFileSync(new URL('./App.svelte', import.meta.url), 'utf8');
const imports = [...source.matchAll(/^\s*import\s[^;]*?from\s+'([^']+)'/gmu)].map(([, chemin]) => chemin);
assert.ok(imports.length > 0, 'des imports relevés');
assert.deepEqual(
imports.filter((chemin) => chemin.includes('version.genere')),
[],
);
assert.match(source, /\bversionWindows\b/u);
assert.match(source, /blocAPropos\(\s*\{\s*version:\s*\{\s*affichee:\s*produitVersion,\s*windows:\s*versionWindows\s*\}/u);
});
});