@mostajs/mjs-unit 0.11.2 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +85 -0
- package/bin/cli.mjs +97 -5
- package/dist/d4.d.ts +44 -0
- package/dist/d4.d.ts.map +1 -0
- package/dist/d4.js +225 -0
- package/dist/d4.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +75 -2
- package/dist/index.js.map +1 -1
- package/dist/report.d.ts +25 -0
- package/dist/report.d.ts.map +1 -1
- package/dist/report.js +1 -1
- package/dist/report.js.map +1 -1
- package/dist/s1p.d.ts +36 -0
- package/dist/s1p.d.ts.map +1 -0
- package/dist/s1p.js +146 -0
- package/dist/s1p.js.map +1 -0
- package/llms.txt +72 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -164,6 +164,91 @@ La clé de CI (opération « pousser ») : `QATRAX_CLE_CI`, sinon `~/.config/qat
|
|
|
164
164
|
qatrax prévient de son côté (webhook signé, courriel) quand un rapport de recette arrive. En code :
|
|
165
165
|
`import { configQatrax, creerClientQatrax } from '@mostajs/mjs-unit/qatrax'`.
|
|
166
166
|
|
|
167
|
+
## La suite une fois, en parallèle — S1P (0.12.0)
|
|
168
|
+
|
|
169
|
+
S1P — « suite une fois, en parallèle » (règle DEVRULES-S1P du 04/11/2026, premier usage : Guerway, 371 essais).
|
|
170
|
+
|
|
171
|
+
- **`--jobs=N`** (ou `--jobs` / `--jobs=auto` : nombre de processeurs, 4 au plus) : les fichiers sont répartis en N lots de
|
|
172
|
+
durée voisine (durées du rapport `--json` précédent), un processus par lot, puis réunis en UN rapport ; le total
|
|
173
|
+
exécuté reste vérifié contre le total déclaré. Une chaîne de fichiers marquée `// mjs-unit:lot <nom>` reste dans un même lot.
|
|
174
|
+
- **Le bloc `execution` du rapport JSON** (et une ligne ⏱ en sortie et dans le HTML) : mode, lots, durée réelle,
|
|
175
|
+
somme des durées des essais, gain, détail de chaque lot, espace, jeux de données, empreinte.
|
|
176
|
+
- **L'espace propre** : chaque suite a son `TMPDIR` dédié (un sous-espace par lot) ; ce que chaque fichier d'essai y laisse
|
|
177
|
+
est relevé (bases SQLite reconnues à leur en-tête, fichiers, octets), puis l'espace est supprimé, réussite ou échec ;
|
|
178
|
+
`--garder` le conserve pour examen. Fini les bases d'essai laissées dans `/tmp` (constaté : 16 036 dossiers, 26 Go).
|
|
179
|
+
- **`jeu(nom, { pour, construire, detruire })`** : un jeu de données partagé (un compte, puis une autorisation sur ce compte)
|
|
180
|
+
construit au premier `obtenir()`, gardé tant qu'un essai de `pour` n'a pas fini, détruit après le DERNIER ; un essai
|
|
181
|
+
déclaré jamais exécuté est une anomalie relevée.
|
|
182
|
+
- **`mjs-unit rejouer <essai> <fichier...>`** : cet essai seul, dans un espace neuf ; ses jeux de données sont reconstruits.
|
|
183
|
+
- **L'empreinte** de ce qui a été éprouvé (commit, arbre propre, empreinte du `package-lock.json`, Node) au bloc `execution`,
|
|
184
|
+
et **`mjs-unit empreinte --verifier=<rapport.json>`** : code 0 si le rapport vaut encore pour l'arbre courant, sinon les motifs
|
|
185
|
+
(c'est ce qui permet de ne pas rejouer une suite après une fusion `--ff-only`).
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npx mjs-unit test-scripts/*.test.mjs --jobs --json=test-scripts/.out/report.json --report=test-scripts/.out/report.html
|
|
189
|
+
npx mjs-unit rejouer T-CMP-4 test-scripts/comptes.test.mjs --garder
|
|
190
|
+
npx mjs-unit empreinte --verifier=test-scripts/.out/report.json
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
import { test, jeu } from "@mostajs/mjs-unit";
|
|
195
|
+
const compte = jeu("compte", { pour: ["T-CMP-1", "T-CMP-2"], construire: () => creerCompte(), detruire: (c) => supprimer(c) });
|
|
196
|
+
test("T-CMP-1 — crée le compte", async () => { const c = await compte.obtenir(); /* … */ });
|
|
197
|
+
test("T-CMP-2 — une autorisation sur le compte existant", async () => { const c = await compte.obtenir(); /* … */ });
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Après la suite — D4Q et D4PF (0.13.0)
|
|
201
|
+
|
|
202
|
+
Deux commandes pour ce qui suit une version **intégrée** (suite S1P verte, `main` avancé) ; premier usage : Guerway
|
|
203
|
+
(04/11/2026). L'application décrit ses étapes dans **`d4.config.json`** ; mjs-unit les enchaîne avec les mêmes règles partout.
|
|
204
|
+
|
|
205
|
+
**L'ordre d'une version** : essais rouges → code → suite (`--jobs`, rapport JSON) → intégration S1P
|
|
206
|
+
(`mjs-unit empreinte --verifier`, fusion `--ff-only`) → **`mjs-unit d4q`** → **`mjs-unit d4pf` sur feu vert**.
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npx mjs-unit d4q # la qualité : ne déploie RIEN (CAPTURES=0 saute une étape marquée « sauterSi »)
|
|
210
|
+
npx mjs-unit d4q ../worktrees/L2-1.4.0 # sur un autre dossier de l'application (un worktree)
|
|
211
|
+
npx mjs-unit d4pf --a-blanc # contrôles, puis les commandes qui seraient lancées ; rien n'est exécuté
|
|
212
|
+
npx mjs-unit d4pf # SEULEMENT sur feu vert explicite pour CETTE version
|
|
213
|
+
npx mjs-unit d4pfq # D4PF puis D4Q (D4Q seulement si D4PF réussit) — sur feu vert ; --a-blanc aussi
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
### D4Q — « déploie pour la qualité »
|
|
217
|
+
|
|
218
|
+
Régénère et publie tout ce qui sert à juger la version, dans l'ordre déclaré (chez Guerway : cahier des écrans, feuilles
|
|
219
|
+
de recette par rôle, feuilles de formation, plan Dev+Test, avancement, chiffrage, `mjs-unit qatrax pousser plan,run`).
|
|
220
|
+
|
|
221
|
+
- `exige` : les fichiers sans lesquels D4Q refuse (le rapport de la DERNIÈRE suite : `test-scripts/.out/report.json`) ;
|
|
222
|
+
- chaque étape s'arrête au premier échec, sauf si sa sortie contient son motif `reporterSi` (un quota de service de PDF) :
|
|
223
|
+
elle est alors « reportée » et la suite continue ; `sauterSi: "VAR=valeur"` la saute ;
|
|
224
|
+
- `dossier` : `app` (défaut) ou `racine` (le dossier de `d4.config.json`) ; `lignes` : les dernières lignes montrées.
|
|
225
|
+
|
|
226
|
+
### D4PF — « déploie pour prod et formation »
|
|
227
|
+
|
|
228
|
+
1. contrôles : la branche (`main`), aucun fichier suivi modifié hors `ignorer` (expressions sur `git status --porcelain`) ;
|
|
229
|
+
2. `sauvegardes` : chaque commande écrit sa copie dans `fichier` ; vide ou sans `entete` (ex. `PGDMP`) → arrêt AVANT
|
|
230
|
+
tout déploiement ;
|
|
231
|
+
3. et 4. `deploiements`, dans l'ordre (production, puis formation) ;
|
|
232
|
+
5. `sante` : chaque commande rend le JSON de `/health` ; `ok`, `version` du package.json ET `commit` de `main` exigés ;
|
|
233
|
+
6. `journaux` : les dernières erreurs, pour lecture (des lignes anciennes ne sont pas une erreur de la version).
|
|
234
|
+
|
|
235
|
+
Règles : aucune valeur du `.env` affichée ; ne pas figer la liste des processus du serveur (pas de `pm2 save`) ; le
|
|
236
|
+
`push` et la publication npm restent hors de D4PF. Jetons des commandes : `{racine}`, `{app}`, `{version}`, `{commit}`, `{date}`.
|
|
237
|
+
|
|
238
|
+
```json
|
|
239
|
+
{
|
|
240
|
+
"app": "mon-api",
|
|
241
|
+
"d4q": { "exige": ["test-scripts/.out/report.json"], "etapes": [
|
|
242
|
+
{ "titre": "feuilles de recette", "commande": "node outils/feuillets.mjs", "reporterSi": "QUOTA_EXCEEDED" },
|
|
243
|
+
{ "titre": "qatrax", "commande": "npx mjs-unit qatrax pousser plan,run" } ] },
|
|
244
|
+
"d4pf": { "branche": "main", "ignorer": [" \\.env\\.example$"],
|
|
245
|
+
"sauvegardes": [{ "nom": "production", "commande": "ssh serveur 'pg_dump -Fc \"$BASE\"'", "fichier": "sauvegardes/avant-{version}-{date}.dump", "entete": "PGDMP" }],
|
|
246
|
+
"deploiements": [{ "nom": "production", "commande": "bash deploy.sh ./prod.conf" }, { "nom": "formation", "commande": "bash deploy.sh ./formation.conf" }],
|
|
247
|
+
"sante": [{ "nom": "production", "commande": "ssh serveur 'curl -s http://127.0.0.1:5400/health'" }],
|
|
248
|
+
"journaux": "ssh serveur 'tail -n 5 logs/err.log'" }
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
167
252
|
## API
|
|
168
253
|
|
|
169
254
|
| Fonction | Rôle |
|
package/bin/cli.mjs
CHANGED
|
@@ -5,6 +5,8 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Usage : mjs-unit <fichier-de-test...> [options]
|
|
7
7
|
* --report[=fichier] écrit une preuve HTML (défaut : test-report.html)
|
|
8
|
+
* --jobs[=N|auto] 0.12.0 (S1P) : N lots parallèles, un seul rapport ; --garder : garde l'espace des essais
|
|
9
|
+
* rejouer <essai> <f…> 0.12.0 : cet essai seul, dans un espace neuf · empreinte --verifier=<rapport.json>
|
|
8
10
|
* --json[=fichier] écrit un rapport JSON (défaut : test-report.json)
|
|
9
11
|
* --junit[=fichier] écrit un rapport JUnit XML (défaut : test-report.xml) — Jenkins, GitLab, GitHub, QATrax
|
|
10
12
|
* --timeout=ms délai par défaut de chaque cas (un cas le surcharge par { timeout })
|
|
@@ -22,6 +24,7 @@
|
|
|
22
24
|
* JUnit XML, NUnit 2/3, TRX, TestNG, Robot Framework, CTest, Cucumber JSON, Behave JSON,
|
|
23
25
|
* Allure 2, CTRF, TAP, JSON mjs-unit — reconnus à leur contenu
|
|
24
26
|
* 0.11.0 — LE CLIENT QATRAX : mjs-unit qatrax <etat|rapatrier|pris|corrige|pousser> (voir : mjs-unit qatrax aide)
|
|
27
|
+
* 0.13.0 — mjs-unit d4q [dossier] | d4pf | d4pfq (D4PF puis D4Q) [--config=d4.config.json] [--a-blanc] : feu vert pour d4pf*
|
|
25
28
|
* --depuis=chemin un dossier (tous ses .xml, .json, .tap, .trx ; dans allure-results, les *-container et
|
|
26
29
|
* *-attachment sont écartés) ou un fichier
|
|
27
30
|
* → les mêmes sorties : --compte-rendu, --ctrf, --intoto, --json, --junit, --report
|
|
@@ -29,22 +32,42 @@
|
|
|
29
32
|
* @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
30
33
|
*/
|
|
31
34
|
// 0.11.0 — `mjs-unit qatrax …` : le client qatrax, chargé SEULEMENT pour cette sous-commande (le runner reste sans réseau).
|
|
35
|
+
// 0.13.0 — `mjs-unit d4q` / `mjs-unit d4pf` : ce qui suit une version intégrée, décrit par l'app dans d4.config.json.
|
|
36
|
+
if (process.argv[2] === "d4q" || process.argv[2] === "d4pf" || process.argv[2] === "d4pfq") {
|
|
37
|
+
const d4 = await import("../dist/d4.js");
|
|
38
|
+
process.exit(d4[process.argv[2]](process.argv.slice(3)));
|
|
39
|
+
}
|
|
32
40
|
if (process.argv[2] === "qatrax") {
|
|
33
41
|
const { principal } = await import("../dist/qatrax.js");
|
|
34
42
|
process.exit(await principal(process.argv.slice(3)));
|
|
35
43
|
}
|
|
36
44
|
import { register } from "node:module";
|
|
37
45
|
import { pathToFileURL } from "node:url";
|
|
38
|
-
import { writeFileSync, readFileSync, mkdirSync, statSync, readdirSync } from "node:fs";
|
|
39
|
-
import { hostname } from "node:os";
|
|
46
|
+
import { writeFileSync, readFileSync, mkdirSync, statSync, readdirSync, mkdtempSync, rmSync } from "node:fs";
|
|
47
|
+
import { hostname, tmpdir, availableParallelism } from "node:os";
|
|
48
|
+
import { spawn } from "node:child_process";
|
|
49
|
+
import { fileURLToPath } from "node:url";
|
|
40
50
|
import { createHash } from "node:crypto";
|
|
41
51
|
import { dirname, join } from "node:path";
|
|
42
52
|
|
|
43
53
|
register(new URL("../loader.mjs", import.meta.url));
|
|
44
|
-
const { run, pending, registered, takeRuns, setDefaultTimeout, setTagFilter } = await import("../dist/index.js");
|
|
54
|
+
const { run, pending, registered, takeRuns, setDefaultTimeout, setTagFilter, setSeul, takeJeux } = await import("../dist/index.js");
|
|
55
|
+
const { photographier, releverEntre, empreinteDe, verifierEmpreinte, repartir, dureesDe } = await import("../dist/s1p.js");
|
|
45
56
|
|
|
46
57
|
// ── Découpe arguments / options ──────────────────────────────────────────────
|
|
47
58
|
const argv = process.argv.slice(2);
|
|
59
|
+
// 0.12.0 (S1P) — `mjs-unit empreinte --verifier=<rapport.json>` : le rapport vaut-il encore pour l'arbre courant ?
|
|
60
|
+
if (argv[0] === "empreinte") {
|
|
61
|
+
const f = (argv.find((a) => a.startsWith("--verifier=")) || "").slice(11);
|
|
62
|
+
if (!f) { console.error("usage : mjs-unit empreinte --verifier=<rapport.json>"); process.exit(2); }
|
|
63
|
+
let r; try { r = JSON.parse(readFileSync(f, "utf8")); } catch (e) { console.error(`✗ ${f} : ${e?.message ?? e}`); process.exit(2); }
|
|
64
|
+
const v = verifierEmpreinte(r.execution?.empreinte, process.cwd());
|
|
65
|
+
if (v.ok) { console.log(`✓ le rapport vaut pour l'arbre courant : commit ${String(v.actuelle.commit).slice(0, 7)}, arbre propre, même verrou, Node ${v.actuelle.node}`); process.exit(0); }
|
|
66
|
+
console.log(`✗ le rapport ne vaut plus pour l'arbre courant :\n${v.motifs.map((m) => ` - ${m}`).join("\n")}`); process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
// 0.12.0 (S1P) — `mjs-unit rejouer <essai> <fichier...>` : cet essai seul, dans un espace neuf (ses jeux reconstruits).
|
|
69
|
+
let rejouer = null;
|
|
70
|
+
if (argv[0] === "rejouer") { rejouer = argv[1]; argv.splice(0, 2); if (!rejouer || rejouer.startsWith("--")) { console.error("usage : mjs-unit rejouer <essai> <fichier...>"); process.exit(2); } }
|
|
48
71
|
const opt = (name) => {
|
|
49
72
|
const hit = argv.find((a) => a === `--${name}` || a.startsWith(`--${name}=`));
|
|
50
73
|
if (!hit) return undefined;
|
|
@@ -62,6 +85,24 @@ const depuis = opt("depuis"); // 0.10.0 — mode lecteur : "" (les arguments
|
|
|
62
85
|
const lecteur = depuis !== undefined;
|
|
63
86
|
const files = argv.filter((a) => !a.startsWith("--"));
|
|
64
87
|
const debut = new Date().toISOString();
|
|
88
|
+
// ── 0.12.0 (S1P) — l'espace des essais, le parallèle, l'empreinte ─────────────────────────────────────────────
|
|
89
|
+
// Chaque suite a son ESPACE (TMPDIR dédié) : bases et fichiers des essais y naissent, sont relevés par fichier, puis
|
|
90
|
+
// supprimés (réussite ou échec) — sauf --garder. --jobs=N répartit les fichiers en N lots parallèles (un processus par
|
|
91
|
+
// lot, son sous-espace), puis réunit leurs rapports en un seul. Le bloc `execution` du rapport dit tout (chrono, gain,
|
|
92
|
+
// lots, espace, jeux de données, empreinte). --lot et --espace sont internes (un lot lancé par le CLI parent).
|
|
93
|
+
const t0 = Date.now();
|
|
94
|
+
const garder = opt("garder") !== undefined;
|
|
95
|
+
const enfant = opt("lot") !== undefined;
|
|
96
|
+
const jobsOpt = opt("jobs");
|
|
97
|
+
const jobs = jobsOpt === undefined ? 1 : (jobsOpt === "" || jobsOpt === "auto") ? Math.min(4, availableParallelism()) : Math.max(1, Number.parseInt(jobsOpt, 10) || 1);
|
|
98
|
+
const empreinte = lecteur ? null : empreinteDe(process.cwd());
|
|
99
|
+
let espace = null;
|
|
100
|
+
if (!lecteur) { espace = opt("espace") || mkdtempSync(join(tmpdir(), "mjs-unit-")); mkdirSync(espace, { recursive: true }); process.env.TMPDIR = espace; }
|
|
101
|
+
if (rejouer) setSeul([rejouer]);
|
|
102
|
+
const parallele = !lecteur && !enfant && jobs > 1 && files.length > 1;
|
|
103
|
+
const parFichier = [], lotsExec = [];
|
|
104
|
+
const jeux = { construits: 0, detruits: 0, anomalies: [] };
|
|
105
|
+
const ajouterJeux = (j) => { jeux.construits += j.construits || 0; jeux.detruits += j.detruits || 0; jeux.anomalies.push(...(j.anomalies || [])); };
|
|
65
106
|
if (!files.length && !depuis) { console.error("usage: mjs-unit <fichier-de-test...> [--report[=f]] [--json[=f]] — ou : mjs-unit --depuis <rapport...> (JUnit, NUnit, TRX, TestNG, Robot, CTest, Cucumber, Behave, Allure, CTRF, TAP)"); process.exit(2); }
|
|
66
107
|
|
|
67
108
|
// ── Exécution, une suite par fichier ─────────────────────────────────────────
|
|
@@ -108,7 +149,35 @@ if (lecteur) {
|
|
|
108
149
|
if (allure.length) ajouter(lireRapportEssais(allure).rapport, allureSource);
|
|
109
150
|
console.log(`\n${totalFail ? "✗" : "✓"} ${totalExecutes} cas lu(s) dans ${lecture.rapports.length} rapport(s) — mode lecteur : aucun essai exécuté par mjs-unit`);
|
|
110
151
|
}
|
|
111
|
-
|
|
152
|
+
if (parallele) {
|
|
153
|
+
const groupes = repartir(files, jobs, dureesDe(jsonOut || undefined));
|
|
154
|
+
console.log(`S1P : ${files.length} fichiers en ${groupes.length} lots parallèles (--jobs=${jobs})`);
|
|
155
|
+
const transmis = argv.filter((a) => /^--(timeout|tag)=/.test(a));
|
|
156
|
+
const lots = await Promise.all(groupes.map((g, i) => new Promise((ok) => {
|
|
157
|
+
const dir = join(espace, `lot-${i}`); mkdirSync(dir, { recursive: true });
|
|
158
|
+
const json = join(espace, `lot-${i}.json`);
|
|
159
|
+
const debutLot = Date.now();
|
|
160
|
+
const p = spawn(process.execPath, [fileURLToPath(import.meta.url), ...(rejouer ? ["rejouer", rejouer] : []), ...g, `--json=${json}`, `--lot=${i}`, `--espace=${dir}`, ...transmis],
|
|
161
|
+
{ env: { ...process.env, TMPDIR: dir }, stdio: ["ignore", "pipe", "pipe"] });
|
|
162
|
+
let sortie = ""; p.stdout.on("data", (d) => { sortie += d; }); p.stderr.on("data", (d) => { sortie += d; });
|
|
163
|
+
p.on("close", (code) => ok({ i, g, code, sortie, json, dureeMs: Date.now() - debutLot }));
|
|
164
|
+
})));
|
|
165
|
+
for (const l of lots) {
|
|
166
|
+
process.stdout.write(`\n── lot ${l.i} (${l.g.length} fichier(s), ${Math.round(l.dureeMs / 1000)} s) ──${l.sortie.startsWith("\n") ? "" : "\n"}${l.sortie}`);
|
|
167
|
+
let rap = null; try { rap = JSON.parse(readFileSync(l.json, "utf8")); } catch {}
|
|
168
|
+
if (!rap) { console.error(`\n✗ lot ${l.i} : aucun rapport (code ${l.code}) — ${l.g.join(", ")}`); totalFail++; continue; }
|
|
169
|
+
const res = rap.suites.flatMap((s) => s.results);
|
|
170
|
+
suites.push(...rap.suites);
|
|
171
|
+
const x = rap.execution || {};
|
|
172
|
+
totalDeclares += x.declares || 0; totalExecutes += x.executes || 0;
|
|
173
|
+
const echecs = res.filter((r) => r.status === "fail").length;
|
|
174
|
+
totalFail += echecs; if (l.code !== 0 && !echecs) totalFail++;
|
|
175
|
+
lotsExec.push({ n: l.i, fichiers: l.g, essais: res.filter((r) => !r.hook).length, dureeMs: l.dureeMs });
|
|
176
|
+
parFichier.push(...(x.espace?.parFichier || [])); ajouterJeux(x.espace?.jeux || {});
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
for (const f of lecteur || parallele ? [] : files) {
|
|
180
|
+
const photoAvant = photographier(espace);
|
|
112
181
|
const avant = registered();
|
|
113
182
|
takeRuns(); // rien d'un fichier précédent ne doit être attribué à celui-ci
|
|
114
183
|
await import(pathToFileURL(f).href); // le fichier enregistre ses cas (et peut appeler run() lui-même)
|
|
@@ -130,13 +199,34 @@ for (const f of lecteur ? [] : files) {
|
|
|
130
199
|
}
|
|
131
200
|
totalDeclares += declares; totalExecutes += cas.length;
|
|
132
201
|
suites.push({ file: f, results });
|
|
202
|
+
parFichier.push({ fichier: f, ...releverEntre(photoAvant, photographier(espace)) });
|
|
203
|
+
ajouterJeux(takeJeux());
|
|
204
|
+
}
|
|
205
|
+
// Le bloc `execution` : chrono, gain, lots, espace, jeux de données, empreinte (0.12.0, S1P).
|
|
206
|
+
let execution = null;
|
|
207
|
+
if (!lecteur) {
|
|
208
|
+
if (rejouer && !enfant && !suites.flatMap((s) => s.results).some((r) => r.status !== "skip" && String(r.name).trim().split(/\s+/)[0] === rejouer)) {
|
|
209
|
+
console.error(`\n✗ rejouer : aucun essai « ${rejouer} » dans ces fichiers.`); totalFail++;
|
|
210
|
+
}
|
|
211
|
+
const cas = suites.flatMap((s) => s.results).filter((r) => !r.hook);
|
|
212
|
+
const somme = Math.round(cas.reduce((a, r) => a + (r.durationMs || 0), 0));
|
|
213
|
+
const dureeMs = Date.now() - t0;
|
|
214
|
+
const total = (k) => parFichier.reduce((a, p) => a + (p[k] || 0), 0);
|
|
215
|
+
execution = {
|
|
216
|
+
mode: parallele ? "parallele" : "file", jobs: parallele ? jobs : 1, debut, fin: new Date().toISOString(), dureeMs, sommeEssaisMs: somme,
|
|
217
|
+
gainPourcent: somme ? Math.round((100 * (somme - dureeMs)) / somme) : 0, executes: totalExecutes, declares: totalDeclares,
|
|
218
|
+
lots: parallele ? lotsExec : [{ n: 0, fichiers: files, essais: cas.length, dureeMs }],
|
|
219
|
+
espace: { dossier: espace, garde: garder, bases: total("bases"), fichiers: total("fichiers"), octets: total("octets"), parFichier, jeux },
|
|
220
|
+
empreinte, ...(rejouer ? { rejouer } : {}),
|
|
221
|
+
};
|
|
222
|
+
if (!enfant) console.log(`\n⏱ ${execution.mode === "parallele" ? `S1P — ${lotsExec.length} lots parallèles` : "à la file"} : ${(dureeMs / 1000).toFixed(1)} s (somme des essais ${(somme / 1000).toFixed(1)} s, gain ${execution.gainPourcent} %) — espace : ${execution.espace.bases} base(s), ${execution.espace.fichiers} fichier(s), ${Math.round(execution.espace.octets / 1024)} Ko${garder ? ` gardés dans ${espace}` : ", supprimés"}${jeux.anomalies.length ? ` — ${jeux.anomalies.length} anomalie(s) de jeux de données` : ""}`);
|
|
133
223
|
}
|
|
134
224
|
if (!lecteur) console.log(`\n${totalExecutes === totalDeclares ? "✓" : "✗"} ${totalExecutes}/${totalDeclares} test(s) exécutés sur ${suites.length} fichier(s) — compte relevé auprès du module, pas supposé`);
|
|
135
225
|
|
|
136
226
|
// ── Reporters optionnels ─────────────────────────────────────────────────────
|
|
137
227
|
if (htmlOut !== undefined || jsonOut !== undefined || junitOut !== undefined) {
|
|
138
228
|
const { renderHtmlReport, renderJsonReport, renderJunitReport } = await import("../dist/report.js");
|
|
139
|
-
const report = { suites, generatedAt: genereLe ?? new Date().toISOString(), title: title || undefined, hostname: hostname() };
|
|
229
|
+
const report = { suites, generatedAt: genereLe ?? new Date().toISOString(), title: title || undefined, hostname: hostname(), ...(execution ? { execution } : {}) };
|
|
140
230
|
if (htmlOut !== undefined) {
|
|
141
231
|
const out = htmlOut || "test-report.html";
|
|
142
232
|
writeFileSync(out, renderHtmlReport(report));
|
|
@@ -181,4 +271,6 @@ if (crOut !== undefined || ctrfOut !== undefined || intotoOut !== undefined) {
|
|
|
181
271
|
}
|
|
182
272
|
}
|
|
183
273
|
|
|
274
|
+
// L'espace est supprimé — réussite ou échec — sauf --garder ; l'espace d'un lot, par le parent.
|
|
275
|
+
if (espace && !garder && !enfant) { try { rmSync(espace, { recursive: true, force: true }); } catch {} }
|
|
184
276
|
if (totalFail > 0) process.exitCode = 1;
|
package/dist/d4.d.ts
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export interface Etape {
|
|
2
|
+
titre?: string;
|
|
3
|
+
nom?: string;
|
|
4
|
+
commande: string;
|
|
5
|
+
dossier?: "app" | "racine";
|
|
6
|
+
lignes?: number;
|
|
7
|
+
reporterSi?: string;
|
|
8
|
+
sauterSi?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface Sauvegarde {
|
|
11
|
+
nom: string;
|
|
12
|
+
commande: string;
|
|
13
|
+
fichier: string;
|
|
14
|
+
entete?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface Sante {
|
|
17
|
+
nom: string;
|
|
18
|
+
commande: string;
|
|
19
|
+
champs?: string[];
|
|
20
|
+
}
|
|
21
|
+
export interface ConfigD4 {
|
|
22
|
+
app?: string;
|
|
23
|
+
d4q?: {
|
|
24
|
+
exige?: string[];
|
|
25
|
+
etapes: Etape[];
|
|
26
|
+
};
|
|
27
|
+
d4pf?: {
|
|
28
|
+
branche?: string;
|
|
29
|
+
ignorer?: string[];
|
|
30
|
+
sauvegardes?: Sauvegarde[];
|
|
31
|
+
deploiements?: Etape[];
|
|
32
|
+
sante?: Sante[];
|
|
33
|
+
journaux?: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
/** Remplace les jetons {x} d'une commande. */
|
|
37
|
+
export declare function jetons(texte: string, valeurs: Record<string, string>): string;
|
|
38
|
+
/** D4Q : régénère et publie ce qui sert à juger la version ; ne déploie rien. → code de sortie. */
|
|
39
|
+
export declare function d4q(argv: string[]): number;
|
|
40
|
+
/** D4PF : déploie main sur la production et la formation — SEULEMENT sur feu vert pour CETTE version. → code de sortie. */
|
|
41
|
+
export declare function d4pf(argv: string[]): number;
|
|
42
|
+
/** D4PFQ : D4PF puis D4Q — D4Q seulement si D4PF a réussi. SEULEMENT sur feu vert pour CETTE version. → code de sortie. */
|
|
43
|
+
export declare function d4pfq(argv: string[]): number;
|
|
44
|
+
//# sourceMappingURL=d4.d.ts.map
|
package/dist/d4.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d4.d.ts","sourceRoot":"","sources":["../src/d4.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,KAAK;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE;AAC9J,MAAM,WAAW,UAAU;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE;AAC/F,MAAM,WAAW,KAAK;IAAG,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;AAC3E,MAAM,WAAW,QAAQ;IACvB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,KAAK,EAAE,CAAA;KAAE,CAAC;IAC5C,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;QAAC,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;QAAC,YAAY,CAAC,EAAE,KAAK,EAAE,CAAC;QAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACzI;AAOD,8CAA8C;AAC9C,wBAAgB,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAE7E;AAqBD,mGAAmG;AACnG,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CA4B1C;AAQD,2HAA2H;AAC3H,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CA+D3C;AAED,2HAA2H;AAC3H,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAQ5C"}
|
package/dist/d4.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @mostajs/mjs-unit — D4Q et D4PF (0.13.0) : ce qui suit une version INTÉGRÉE (suite S1P verte, main avancé).
|
|
3
|
+
*
|
|
4
|
+
* mjs-unit d4q [dossier-de-l-app] [--config=d4.config.json] « déploie pour la qualité » : ne déploie RIEN ;
|
|
5
|
+
* mjs-unit d4pfq [--config=…] [--a-blanc] D4PF puis D4Q (D4Q seulement si D4PF réussit) : sur FEU VERT ;
|
|
6
|
+
* mjs-unit d4pf [--config=d4.config.json] [--a-blanc] « déploie pour prod et formation » : sur FEU VERT
|
|
7
|
+
* (--a-blanc : contrôles, puis les commandes, sans rien lancer).
|
|
8
|
+
*
|
|
9
|
+
* L'application décrit ses étapes dans `d4.config.json` (cherché dans le dossier courant) ; mjs-unit les enchaîne avec
|
|
10
|
+
* les mêmes règles partout : arrêt au premier échec, une étape « reportée » sur un motif déclaré (quota d'un service
|
|
11
|
+
* de PDF), une étape sautée par variable d'environnement ; pour D4PF : branche et arbre propre exigés, chaque
|
|
12
|
+
* sauvegarde vérifiée (non vide, en-tête attendu) AVANT tout déploiement, santé = version du package.json ET commit.
|
|
13
|
+
* Jetons des commandes : {racine} (dossier de la config), {app}, {version}, {commit}, {date} (AAAAMMJJ-HHMM).
|
|
14
|
+
* Premier usage : Guerway (outils/d4q.sh, outils/d4pf.sh, 04/11/2026).
|
|
15
|
+
* @author Dr Hamid MADANI <drmdh@msn.com> · AGPL-3.0-or-later
|
|
16
|
+
*/
|
|
17
|
+
import { spawnSync } from "node:child_process";
|
|
18
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, statSync, openSync, readSync, closeSync } from "node:fs";
|
|
19
|
+
import { dirname, join, resolve, basename, isAbsolute } from "node:path";
|
|
20
|
+
const BLEU = (s) => `\x1b[0;36m${s}\x1b[0m`;
|
|
21
|
+
const VERT = (s) => `\x1b[0;32m${s}\x1b[0m`;
|
|
22
|
+
const deuxChiffres = (n) => String(n).padStart(2, "0");
|
|
23
|
+
const dateCourte = (d = new Date()) => `${d.getFullYear()}${deuxChiffres(d.getMonth() + 1)}${deuxChiffres(d.getDate())}-${deuxChiffres(d.getHours())}${deuxChiffres(d.getMinutes())}`;
|
|
24
|
+
/** Remplace les jetons {x} d'une commande. */
|
|
25
|
+
export function jetons(texte, valeurs) {
|
|
26
|
+
return texte.replace(/\{(racine|app|version|commit|date)\}/g, (m, k) => (k in valeurs ? valeurs[k] : m));
|
|
27
|
+
}
|
|
28
|
+
function shell(commande, cwd) {
|
|
29
|
+
const r = spawnSync("bash", ["-c", commande], { cwd, encoding: "utf8", env: process.env, maxBuffer: 256 * 1024 * 1024 });
|
|
30
|
+
return { code: r.status ?? 1, sortie: `${r.stdout ?? ""}${r.stderr ?? ""}` };
|
|
31
|
+
}
|
|
32
|
+
const fin = (s, n = 3) => s.trimEnd().split("\n").slice(-n).join("\n");
|
|
33
|
+
function charger(argv) {
|
|
34
|
+
const opt = argv.find((a) => a.startsWith("--config="));
|
|
35
|
+
const fichier = resolve(opt ? opt.slice(9) : "d4.config.json");
|
|
36
|
+
if (!existsSync(fichier))
|
|
37
|
+
throw Object.assign(new Error(`${fichier} introuvable : décrivez les étapes de l'application dans d4.config.json`), { code: 2 });
|
|
38
|
+
const config = JSON.parse(readFileSync(fichier, "utf8"));
|
|
39
|
+
const racine = dirname(fichier);
|
|
40
|
+
const libres = argv.filter((a) => !a.startsWith("--"));
|
|
41
|
+
const app = libres[0] ? resolve(libres[0]) : resolve(racine, config.app || ".");
|
|
42
|
+
if (!existsSync(join(app, "package.json")))
|
|
43
|
+
throw Object.assign(new Error(`${app} : pas de package.json (dossier de l'application attendu)`), { code: 1 });
|
|
44
|
+
const pkg = JSON.parse(readFileSync(join(app, "package.json"), "utf8"));
|
|
45
|
+
return { config, racine, app, version: String(pkg.version), nom: String(pkg.name || basename(app)), libres };
|
|
46
|
+
}
|
|
47
|
+
/** D4Q : régénère et publie ce qui sert à juger la version ; ne déploie rien. → code de sortie. */
|
|
48
|
+
export function d4q(argv) {
|
|
49
|
+
let c;
|
|
50
|
+
try {
|
|
51
|
+
c = charger(argv);
|
|
52
|
+
}
|
|
53
|
+
catch (e) {
|
|
54
|
+
console.error(`✗ ${e.message}`);
|
|
55
|
+
return e.code ?? 1;
|
|
56
|
+
}
|
|
57
|
+
const q = c.config.d4q;
|
|
58
|
+
if (!q || !q.etapes?.length) {
|
|
59
|
+
console.error("✗ aucune section d4q (etapes) dans d4.config.json");
|
|
60
|
+
return 2;
|
|
61
|
+
}
|
|
62
|
+
const valeurs = { racine: c.racine, app: c.app, version: c.version, commit: "", date: dateCourte() };
|
|
63
|
+
console.log(`D4Q — ${c.nom} ${c.version} (${c.app})`);
|
|
64
|
+
for (const f of q.exige || [])
|
|
65
|
+
if (!existsSync(join(c.app, f))) {
|
|
66
|
+
console.error(`✗ aucune exécution : ${f} manque — lancer d'abord la suite dans ${c.app}`);
|
|
67
|
+
return 1;
|
|
68
|
+
}
|
|
69
|
+
const n = q.etapes.length;
|
|
70
|
+
const reportees = [];
|
|
71
|
+
if (argv.includes("--a-blanc")) {
|
|
72
|
+
for (const [i, e] of q.etapes.entries())
|
|
73
|
+
console.log(` [${i + 1}/${n}] ${e.titre} : ${jetons(e.commande, valeurs)}`);
|
|
74
|
+
console.log(`\n${VERT("✓ D4Q à blanc — rien n'a été lancé")}`);
|
|
75
|
+
return 0;
|
|
76
|
+
}
|
|
77
|
+
for (const [i, e] of q.etapes.entries()) {
|
|
78
|
+
const k = i + 1;
|
|
79
|
+
if (e.sauterSi) {
|
|
80
|
+
const [v, val] = e.sauterSi.split("=");
|
|
81
|
+
if (process.env[v] === val) {
|
|
82
|
+
console.log(`\n${BLEU(`[${k}/${n}] ${e.titre} — sautée (${e.sauterSi})`)}`);
|
|
83
|
+
continue;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
console.log(`\n${BLEU(`[${k}/${n}] ${e.titre}`)}`);
|
|
87
|
+
const r = shell(jetons(e.commande, valeurs), e.dossier === "racine" ? c.racine : c.app);
|
|
88
|
+
if (r.code === 0) {
|
|
89
|
+
if (r.sortie.trim())
|
|
90
|
+
console.log(fin(r.sortie, e.lignes ?? 3));
|
|
91
|
+
continue;
|
|
92
|
+
}
|
|
93
|
+
if (e.reporterSi && r.sortie.includes(e.reporterSi)) {
|
|
94
|
+
console.log(` ⚠ reportée : ${e.reporterSi} (les sources sont à jour ; relancer D4Q plus tard)`);
|
|
95
|
+
reportees.push(k);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
console.log(fin(r.sortie, 15));
|
|
99
|
+
console.error(`✗ étape ${k} en échec`);
|
|
100
|
+
return 1;
|
|
101
|
+
}
|
|
102
|
+
if (reportees.length)
|
|
103
|
+
console.log(`⚠ étapes reportées : ${reportees.join(", ")} ; relancer D4Q pour les produire.`);
|
|
104
|
+
console.log(`\n${VERT(`✓ D4Q terminé — ${c.nom} ${c.version}`)}`);
|
|
105
|
+
return 0;
|
|
106
|
+
}
|
|
107
|
+
/** Les premiers octets d'un fichier. */
|
|
108
|
+
function debut(fichier, n) {
|
|
109
|
+
const fd = openSync(fichier, "r");
|
|
110
|
+
const b = Buffer.alloc(n);
|
|
111
|
+
const lus = readSync(fd, b, 0, n, 0);
|
|
112
|
+
closeSync(fd);
|
|
113
|
+
return b.subarray(0, lus).toString("latin1");
|
|
114
|
+
}
|
|
115
|
+
/** D4PF : déploie main sur la production et la formation — SEULEMENT sur feu vert pour CETTE version. → code de sortie. */
|
|
116
|
+
export function d4pf(argv) {
|
|
117
|
+
let c;
|
|
118
|
+
try {
|
|
119
|
+
c = charger(argv);
|
|
120
|
+
}
|
|
121
|
+
catch (e) {
|
|
122
|
+
console.error(`✗ ${e.message}`);
|
|
123
|
+
return e.code ?? 1;
|
|
124
|
+
}
|
|
125
|
+
const d = c.config.d4pf;
|
|
126
|
+
if (!d) {
|
|
127
|
+
console.error("✗ aucune section d4pf dans d4.config.json");
|
|
128
|
+
return 2;
|
|
129
|
+
}
|
|
130
|
+
const git = (a) => shell(`git ${a}`, c.app).sortie.trim();
|
|
131
|
+
const commit = git("rev-parse --short HEAD");
|
|
132
|
+
const valeurs = { racine: c.racine, app: c.app, version: c.version, commit, date: dateCourte() };
|
|
133
|
+
const pas = (k, t) => console.log(`\n${BLEU(`[${k}/6] ${t}`)}`);
|
|
134
|
+
console.log(`D4PF — ${c.nom} ${c.version} (${commit})`);
|
|
135
|
+
pas(1, "contrôles");
|
|
136
|
+
const branche = d.branche || "main";
|
|
137
|
+
const courante = git("branch --show-current");
|
|
138
|
+
if (courante !== branche) {
|
|
139
|
+
console.error(`✗ branche courante : ${courante} (${branche} attendu)`);
|
|
140
|
+
return 1;
|
|
141
|
+
}
|
|
142
|
+
const ignorer = (d.ignorer || []).map((x) => new RegExp(x));
|
|
143
|
+
const sale = git("status --porcelain --untracked-files=no").split("\n").filter((l) => l.trim() && !ignorer.some((re) => re.test(l)));
|
|
144
|
+
if (sale.length) {
|
|
145
|
+
console.error(`✗ fichiers suivis modifiés :\n${sale.join("\n")}`);
|
|
146
|
+
return 1;
|
|
147
|
+
}
|
|
148
|
+
console.log(` ✓ ${branche}, arbre propre${ignorer.length ? " (hors fichiers ignorés)" : ""}`);
|
|
149
|
+
// --a-blanc : les contrôles seuls, puis les commandes qui seraient lancées (jetons remplacés) ; rien n'est exécuté.
|
|
150
|
+
if (argv.includes("--a-blanc")) {
|
|
151
|
+
const l = (t, x) => console.log(` ${t} : ${jetons(x, valeurs)}`);
|
|
152
|
+
for (const s of d.sauvegardes || [])
|
|
153
|
+
l(`sauvegarde ${s.nom} → ${jetons(s.fichier, valeurs)}`, s.commande);
|
|
154
|
+
for (const e of d.deploiements || [])
|
|
155
|
+
l(`déploiement ${e.titre || e.nom}`, e.commande);
|
|
156
|
+
for (const s of d.sante || [])
|
|
157
|
+
l(`santé ${s.nom}`, s.commande);
|
|
158
|
+
if (d.journaux)
|
|
159
|
+
l("journaux", d.journaux);
|
|
160
|
+
console.log(`\n${VERT(`✓ D4PF à blanc — rien n'a été sauvegardé ni déployé`)}`);
|
|
161
|
+
return 0;
|
|
162
|
+
}
|
|
163
|
+
pas(2, "sauvegardes");
|
|
164
|
+
for (const s of d.sauvegardes || []) {
|
|
165
|
+
const fichier = jetons(s.fichier, valeurs);
|
|
166
|
+
const chemin = isAbsolute(fichier) ? fichier : join(c.app, fichier);
|
|
167
|
+
mkdirSync(dirname(chemin), { recursive: true });
|
|
168
|
+
const r = spawnSync("bash", ["-c", jetons(s.commande, valeurs)], { cwd: c.app, env: process.env, maxBuffer: 4 * 1024 * 1024 * 1024 });
|
|
169
|
+
writeFileSync(chemin, r.stdout ?? Buffer.alloc(0));
|
|
170
|
+
const taille = existsSync(chemin) ? statSync(chemin).size : 0;
|
|
171
|
+
if (r.status !== 0 || !taille || (s.entete && debut(chemin, s.entete.length) !== s.entete)) {
|
|
172
|
+
console.error(`✗ ${basename(chemin)} : copie vide ou illisible (${s.nom})`);
|
|
173
|
+
return 1;
|
|
174
|
+
}
|
|
175
|
+
console.log(` ✓ ${basename(chemin)} — ${taille} octets`);
|
|
176
|
+
}
|
|
177
|
+
for (const [i, e] of (d.deploiements || []).entries()) {
|
|
178
|
+
pas(3 + Math.min(i, 1), String(e.titre || e.nom));
|
|
179
|
+
const r = shell(jetons(e.commande, valeurs), e.dossier === "racine" ? c.racine : c.app);
|
|
180
|
+
console.log(fin(r.sortie, e.lignes ?? 4));
|
|
181
|
+
if (r.code !== 0) {
|
|
182
|
+
console.error(`✗ déploiement « ${e.titre || e.nom} » en échec`);
|
|
183
|
+
return 1;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
pas(5, "santé");
|
|
187
|
+
let malade = false;
|
|
188
|
+
for (const s of d.sante || []) {
|
|
189
|
+
const r = shell(jetons(s.commande, valeurs), c.app);
|
|
190
|
+
let h = null;
|
|
191
|
+
try {
|
|
192
|
+
h = JSON.parse(r.sortie);
|
|
193
|
+
}
|
|
194
|
+
catch { /* réponse illisible */ }
|
|
195
|
+
const bon = Boolean(h && h.ok && h.version === c.version && String(h.commit).startsWith(commit));
|
|
196
|
+
const plus = (s.champs || []).filter((k) => h?.[k] != null).map((k) => ` · ${k} ${h[k]}`).join("");
|
|
197
|
+
console.log(` ${bon ? "✓" : "✗"} ${s.nom} : ${h ? `${h.version} ${h.commit}${plus}` : "réponse illisible"}`);
|
|
198
|
+
if (!bon)
|
|
199
|
+
malade = true;
|
|
200
|
+
}
|
|
201
|
+
if (malade) {
|
|
202
|
+
console.error("✗ santé : version ou commit inattendu");
|
|
203
|
+
return 1;
|
|
204
|
+
}
|
|
205
|
+
pas(6, "journaux (dernières erreurs)");
|
|
206
|
+
if (d.journaux)
|
|
207
|
+
console.log(fin(shell(jetons(d.journaux, valeurs), c.app).sortie, 40));
|
|
208
|
+
console.log(`\n${VERT(`✓ D4PF terminé — ${c.nom} ${c.version} (${commit})`)}`);
|
|
209
|
+
return 0;
|
|
210
|
+
}
|
|
211
|
+
/** D4PFQ : D4PF puis D4Q — D4Q seulement si D4PF a réussi. SEULEMENT sur feu vert pour CETTE version. → code de sortie. */
|
|
212
|
+
export function d4pfq(argv) {
|
|
213
|
+
const a = d4pf(argv);
|
|
214
|
+
if (a !== 0) {
|
|
215
|
+
console.error("✗ D4PF en échec : D4Q non lancé");
|
|
216
|
+
return a;
|
|
217
|
+
}
|
|
218
|
+
// D4Q porte sur l'application déployée (celle de la config), jamais sur un autre dossier.
|
|
219
|
+
const b = d4q(argv.filter((x) => x.startsWith("--")));
|
|
220
|
+
if (b !== 0)
|
|
221
|
+
return b;
|
|
222
|
+
console.log(VERT(argv.includes("--a-blanc") ? "✓ D4PFQ à blanc — rien n'a été lancé" : "✓ D4PFQ terminé — déployé, puis la qualité"));
|
|
223
|
+
return 0;
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=d4.js.map
|
package/dist/d4.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"d4.js","sourceRoot":"","sources":["../src/d4.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -42,6 +42,29 @@ export declare const afterEach: (fn: () => void | Promise<void>) => void;
|
|
|
42
42
|
export declare function setDefaultTimeout(ms: number): void;
|
|
43
43
|
/** Ne jouer que les cas portant l'une de ces étiquettes (les autres sont dits ignorés). Le CLI : `--tag=`. */
|
|
44
44
|
export declare function setTagFilter(tags: string[]): void;
|
|
45
|
+
/** `mjs-unit rejouer <id>` : seuls ces essais (identifiant = premier mot du nom) sont joués ; les autres sont ignorés. */
|
|
46
|
+
export declare function setSeul(ids: string[]): void;
|
|
47
|
+
export interface JeuOptions<T> {
|
|
48
|
+
pour: string[];
|
|
49
|
+
construire: () => T | Promise<T>;
|
|
50
|
+
detruire?: (v: T) => void | Promise<void>;
|
|
51
|
+
}
|
|
52
|
+
export interface Jeu<T> {
|
|
53
|
+
readonly nom: string;
|
|
54
|
+
obtenir(): Promise<T>;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Un JEU DE DONNÉES partagé par plusieurs essais (un compte, puis une autorisation sur ce compte) : construit au premier
|
|
58
|
+
* `obtenir()`, gardé tant qu'un essai de `pour` n'a pas fini, détruit après le DERNIER. Un essai de `pour` qui ne s'exécute
|
|
59
|
+
* jamais est une anomalie relevée ; le jeu est alors détruit en fin de fichier. Un essai ignoré (filtre, rejouer) libère.
|
|
60
|
+
*/
|
|
61
|
+
export declare function jeu<T>(nom: string, o: JeuOptions<T>): Jeu<T>;
|
|
62
|
+
/** Relève — et remet à zéro — le bilan des jeux de données (le CLI le porte au bloc `execution`). */
|
|
63
|
+
export declare function takeJeux(): {
|
|
64
|
+
construits: number;
|
|
65
|
+
detruits: number;
|
|
66
|
+
anomalies: string[];
|
|
67
|
+
};
|
|
45
68
|
export declare function ok(cond: unknown, message?: string): void;
|
|
46
69
|
export declare function equal(actual: unknown, expected: unknown, message?: string): void;
|
|
47
70
|
export declare function deepEqual(actual: unknown, expected: unknown, message?: string): void;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qFAAqF;AACrF,MAAM,WAAW,WAAW;IAAG,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE;AAC3F,KAAK,EAAE,GAAG,CAAC,GAAG,CAAC,EAAE,GAAG,EAAE,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAChD,MAAM,WAAW,QAAQ;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,EAAE,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE;AAoC7J,yHAAyH;AACzH,wBAAgB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAAkC;yBAAtF,IAAI;qBAED,MAAM,OAAM,EAAE,WAAsB,MAAM,KAAG,IAAI;sBAKhD,OAAO,EAAE,MAAM,MAAM,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,WAAW,KAAG,IAAI;;AAUlF;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,IAAI,GAAG,IAAI,CAK9D;AAID,eAAO,MAAM,SAAS,OADoB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAG,IACzB,CAAC;AAC/C,eAAO,MAAM,QAAQ,OAFqB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAG,IAE3B,CAAC;AAC7C,eAAO,MAAM,UAAU,OAHmB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAG,IAGvB,CAAC;AACjD,eAAO,MAAM,SAAS,OAJoB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAG,IAIzB,CAAC;AAC/C,0FAA0F;AAC1F,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAiD;AACpG,8GAA8G;AAC9G,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAA6E;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|