Badges and printed views need a PDF writer, an embedded font whose metrics the tests can measure, and the paper the machine prints on. pdf-lib with fontkit writes the sheet; Noto Sans (OFL) ships with its provenance and SHA-256, and travels into www/ with every third-party notice that the minified bundle drops. The paper is kept per machine in reglages_locaux.json. A4 and Letter derive the A6 grid from their dimensions; the PDF libraries load in two deferred chunks, each under the 1000 kB threshold. Checked: 3048 node, 639 browser and 67 long tests green from the index. --- FR --- [ADD] sorties : pdf-lib, Noto Sans, formats de papier, imposition Les badges et les vues imprimables exigent un producteur de PDF, une police embarquée que les épreuves mesurent, et le papier de la machine. pdf-lib et fontkit écrivent la planche ; Noto Sans (OFL) arrive avec sa provenance et son SHA-256, et voyage dans www/ avec chaque avis de tiers que le paquet minifié retire. Le papier se garde par machine dans reglages_locaux.json. A4 et Lettre dérivent la grille A6 de leurs dimensions ; les bibliothèques PDF se chargent en deux morceaux différés, chacun sous le seuil de 1000 ko. Vérifié : 3048 node, 639 navigateur et 67 longues vertes depuis l'index. Assisted-by: Claude Opus 5.5
67 lines
2.7 KiB
JavaScript
67 lines
2.7 KiB
JavaScript
// © 2026 TechnoLibre (http://www.technolibre.ca)
|
||
// License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl)
|
||
|
||
// L'imprimante de la plateforme web (§ 13.4, § 11.7) : la boîte de dialogue
|
||
// du navigateur, sans retour sur ce qu'elle devient. Une fenêtre factice
|
||
// compte ses appels à print.
|
||
import assert from 'node:assert/strict';
|
||
import { describe, test } from '../../test/lanceur.js';
|
||
import { PAPIERS } from '../geometrie/papiers.js';
|
||
import { creerImprimanteWeb } from './imprimante_web.js';
|
||
|
||
// Une fenêtre qui ne sait qu'imprimer, et compte ses appels.
|
||
function fenetreFactice() {
|
||
const fenetre = {
|
||
appels: 0,
|
||
print() {
|
||
fenetre.appels += 1;
|
||
},
|
||
};
|
||
return fenetre;
|
||
}
|
||
|
||
describe('imprimante web (§ 13.4)', () => {
|
||
test('imprimer appelle print une fois, et rend l’issue inconnue sans cause, pour chaque papier et chaque orientation', async () => {
|
||
for (const papier of Object.keys(PAPIERS)) {
|
||
for (const orientation of ['portrait', 'paysage']) {
|
||
const fenetre = fenetreFactice();
|
||
const issue = await creerImprimanteWeb(fenetre).imprimer({ papier, orientation });
|
||
assert.deepEqual(issue, { issue: 'inconnue', cause: null }, `${papier} ${orientation}`);
|
||
assert.equal(fenetre.appels, 1, `${papier} ${orientation}`);
|
||
}
|
||
}
|
||
});
|
||
|
||
test('chaque impression appelle print à nouveau : l’imprimante ne garde aucun état', async () => {
|
||
const fenetre = fenetreFactice();
|
||
const imprimante = creerImprimanteWeb(fenetre);
|
||
await imprimante.imprimer({ papier: 'A4', orientation: 'portrait' });
|
||
await imprimante.imprimer({ papier: 'A4', orientation: 'paysage' });
|
||
assert.equal(fenetre.appels, 2);
|
||
});
|
||
|
||
test('une option hors domaine rejette TypeError sans appeler print', async () => {
|
||
const refusees = [
|
||
{ papier: 'A3', orientation: 'portrait' },
|
||
{ papier: 'toString', orientation: 'portrait' },
|
||
{ papier: undefined, orientation: 'portrait' },
|
||
{ papier: 'A4', orientation: 'Portrait' },
|
||
{ papier: 'A4', orientation: 'landscape' },
|
||
{ papier: 'A4' },
|
||
];
|
||
for (const options of refusees) {
|
||
const fenetre = fenetreFactice();
|
||
await assert.rejects(creerImprimanteWeb(fenetre).imprimer(options), TypeError, JSON.stringify(options));
|
||
assert.equal(fenetre.appels, 0, JSON.stringify(options));
|
||
}
|
||
const fenetre = fenetreFactice();
|
||
await assert.rejects(creerImprimanteWeb(fenetre).imprimer(), TypeError);
|
||
assert.equal(fenetre.appels, 0);
|
||
});
|
||
|
||
test('une fenêtre sans print se refuse à la construction', () => {
|
||
for (const fenetre of [null, undefined, {}, { print: 'oui' }]) {
|
||
assert.throws(() => creerImprimanteWeb(fenetre), TypeError, String(fenetre));
|
||
}
|
||
});
|
||
});
|