Before generating, the operator must know what no plan can avoid: the encounters a table size forces, the conflicts when every table holds colleagues, the anchors that impose a return. The engine's diagnosis is turned into sentences with their figures and their remedies, shown in its section and, compact, beside the plan, whose banner states the floors when every table is in conflict (§ 7.5). Checked: 2425 node and 413 browser tests. --- FR --- [ADD] interface : diagnostic — ce qu'une configuration rend inévitable Avant de générer, l'opérateur doit savoir ce qu'aucun plan n'évite : les rencontres qu'une taille de table impose, les conflits quand chaque table réunit des collègues, les ancrages qui imposent un retour. Le diagnostic du moteur devient des phrases, avec leurs chiffres et leurs remèdes, montrées dans sa section et, en compact, à côté du plan, dont le bandeau énonce les planchers quand toutes les tables sont en conflit (§ 7.5). Vérifié : 2425 node et 413 navigateur. Assisted-by: Claude Opus 5.5
83 lines
3.9 KiB
JavaScript
83 lines
3.9 KiB
JavaScript
// © 2026 TechnoLibre (http://www.technolibre.ca)
|
|
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
|
|
|
// Épreuves du diagnostic d'une charge (§ 5.6, § 15.3) : la valeur rendue est
|
|
// celle de diagnostiquer sur la configuration de la charge, sollicitée une
|
|
// seconde fois (§ 19.1) ; une configuration qui ne se normalise pas rend son
|
|
// code et ses détails, sans lever. Les noms d'épreuve sont inventés.
|
|
import assert from 'node:assert/strict';
|
|
import { describe, test } from '../../test/lanceur.js';
|
|
import { texteLivre } from '../demo/livrees.js';
|
|
import { diagnostiquer } from '../moteur/diagnostic.js';
|
|
import { ErreurConfiguration } from '../moteur/erreurs.js';
|
|
import { normaliser } from '../moteur/configuration.js';
|
|
import { serialiser } from '../stockage/canonique.js';
|
|
import { analyser, configurationDepuisCharge, creerCharge } from '../stockage/document.js';
|
|
import { VERSION } from '../version.genere.js';
|
|
import { diagnostiquerCharge } from './diagnostic.js';
|
|
|
|
const chargeDemo = (cle) => analyser(texteLivre(cle)).charge;
|
|
|
|
// La petite démonstration où quatre personnes portent une réservation de
|
|
// portée « tous les tours », sans siège, à la table 1, de 3 places.
|
|
function quatreReserveesSurTrois() {
|
|
const charge = chargeDemo('petite');
|
|
charge.reservations = [1, 2, 3, 4].map((participant) => ({ participant, table: 1, siege: null, portee: 'tous', tour: null }));
|
|
return charge;
|
|
}
|
|
|
|
describe('diagnostiquerCharge', () => {
|
|
test('petite démonstration : le diagnostic de sa configuration, erreur null', () => {
|
|
const charge = chargeDemo('petite');
|
|
const rendu = diagnostiquerCharge(charge);
|
|
assert.deepEqual(rendu, { diagnostic: diagnostiquer(configurationDepuisCharge(charge)), erreur: null });
|
|
assert.ok(rendu.diagnostic.plafondAPriori.repartition.length > 0);
|
|
});
|
|
|
|
test('petite démonstration au conflit inévitable : le plancher du groupe de 5', () => {
|
|
const charge = chargeDemo('petite-conflit');
|
|
const { diagnostic, erreur } = diagnostiquerCharge(charge);
|
|
assert.equal(erreur, null);
|
|
assert.equal(diagnostic.collisions.length, 1);
|
|
assert.deepEqual(diagnostic, diagnostiquer(configurationDepuisCharge(charge)));
|
|
});
|
|
|
|
test('quatre réservées sur une table de 3 : analyser admet, normaliser refuse ; le code rendu, sans lever', () => {
|
|
const charge = quatreReserveesSurTrois();
|
|
// Le fichier qui la porte se relit : la charge est admise par le stockage.
|
|
const relue = analyser(serialiser(charge, { revision: 1, produitVersion: VERSION.affichee })).charge;
|
|
assert.equal(relue.reservations.length, 4);
|
|
let attendue = null;
|
|
try {
|
|
normaliser(configurationDepuisCharge(relue));
|
|
} catch (erreur) {
|
|
assert.ok(erreur instanceof ErreurConfiguration);
|
|
attendue = erreur;
|
|
}
|
|
assert.notEqual(attendue, null);
|
|
const rendu = diagnostiquerCharge(relue);
|
|
assert.deepEqual(rendu, { diagnostic: null, erreur: { code: 'SURRESERVATION', details: attendue.details } });
|
|
assert.equal(rendu.erreur.code, attendue.code);
|
|
});
|
|
|
|
test('un événement neuf, sans participant ni table : un diagnostic, aucune erreur', () => {
|
|
const charge = creerCharge({ id: 'evt-neuf', nom: 'Club des Merles', siegesParDefaut: 8, tours: 4 });
|
|
const { diagnostic, erreur } = diagnostiquerCharge(charge);
|
|
assert.equal(erreur, null);
|
|
assert.deepEqual(diagnostic, diagnostiquer(configurationDepuisCharge(charge)));
|
|
});
|
|
|
|
test('une erreur qui n\u{2019}est pas une ErreurConfiguration remonte', () => {
|
|
const charge = chargeDemo('petite');
|
|
charge.tables = null;
|
|
assert.throws(() => diagnostiquerCharge(charge), TypeError);
|
|
});
|
|
|
|
test('la charge reçue ne change pas', () => {
|
|
const charge = quatreReserveesSurTrois();
|
|
const avant = structuredClone(charge);
|
|
diagnostiquerCharge(charge);
|
|
diagnostiquerCharge(chargeDemo('grande'));
|
|
assert.deepEqual(charge, avant);
|
|
});
|
|
});
|