test(frontend): garde-fou sur le transport des bundles construits (#74 Q1)
Vérifie sur les artefacts réels que `dist` résout `tauri` et `dist-web` `http`, en lisant le marqueur `__IDEA_TRANSPORT__` des assets JS émis. La régression de #74 était invisible aux tests unitaires : elle vivait dans la conf de build et de packaging, pas dans le code testé. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@ -8,6 +8,7 @@
|
|||||||
"build": "tsc --noEmit && vite build",
|
"build": "tsc --noEmit && vite build",
|
||||||
"build:web": "tsc --noEmit && vite build --mode web --outDir dist-web --emptyOutDir",
|
"build:web": "tsc --noEmit && vite build --mode web --outDir dist-web --emptyOutDir",
|
||||||
"build:bundle": "npm run typecheck && vite build --outDir dist --emptyOutDir && vite build --mode web --outDir dist-web --emptyOutDir",
|
"build:bundle": "npm run typecheck && vite build --outDir dist --emptyOutDir && vite build --mode web --outDir dist-web --emptyOutDir",
|
||||||
|
"test:bundle-transport": "node scripts/assert-bundle-transport.mjs",
|
||||||
"typecheck": "tsc --noEmit",
|
"typecheck": "tsc --noEmit",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"test": "vitest run",
|
"test": "vitest run",
|
||||||
|
|||||||
78
frontend/scripts/assert-bundle-transport.mjs
Normal file
78
frontend/scripts/assert-bundle-transport.mjs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
import { readdir, readFile } from "node:fs/promises";
|
||||||
|
import { join } from "node:path";
|
||||||
|
|
||||||
|
const EXPECTED_TRANSPORT_BY_DIR = new Map([
|
||||||
|
["dist", "tauri"],
|
||||||
|
["dist-web", "http"],
|
||||||
|
]);
|
||||||
|
|
||||||
|
async function readJavaScriptAssets(buildDir) {
|
||||||
|
const assetsDir = join(process.cwd(), buildDir, "assets");
|
||||||
|
let entries;
|
||||||
|
try {
|
||||||
|
entries = await readdir(assetsDir, { withFileTypes: true });
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(
|
||||||
|
`Cannot read ${assetsDir}. Run npm run build:bundle before this check. ${error.message}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const files = entries
|
||||||
|
.filter((entry) => entry.isFile() && entry.name.endsWith(".js"))
|
||||||
|
.map((entry) => join(assetsDir, entry.name));
|
||||||
|
|
||||||
|
if (files.length === 0) {
|
||||||
|
throw new Error(`No JavaScript assets found in ${assetsDir}.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.all(
|
||||||
|
files.map(async (file) => ({
|
||||||
|
file,
|
||||||
|
source: await readFile(file, "utf8"),
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function transportMarkers(source) {
|
||||||
|
return [...source.matchAll(/__IDEA_TRANSPORT__="([a-z]+)"/g)].map(
|
||||||
|
(match) => match[1],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function assertBundleTransport(buildDir, expectedTransport) {
|
||||||
|
const assets = await readJavaScriptAssets(buildDir);
|
||||||
|
const markers = assets.flatMap(({ file, source }) =>
|
||||||
|
transportMarkers(source).map((transport) => ({ file, transport })),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (markers.length === 0) {
|
||||||
|
throw new Error(
|
||||||
|
`${buildDir} does not publish a __IDEA_TRANSPORT__ marker in its built JavaScript assets.`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const unexpected = markers.filter(
|
||||||
|
({ transport }) => transport !== expectedTransport,
|
||||||
|
);
|
||||||
|
if (unexpected.length > 0) {
|
||||||
|
const details = unexpected
|
||||||
|
.map(({ file, transport }) => `${file}: ${transport}`)
|
||||||
|
.join("\n");
|
||||||
|
throw new Error(
|
||||||
|
`${buildDir} resolves the wrong transport; expected ${expectedTransport}.\n${details}`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`${buildDir}: __IDEA_TRANSPORT__="${expectedTransport}" (${markers.length} marker${markers.length === 1 ? "" : "s"})`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (const [buildDir, expectedTransport] of EXPECTED_TRANSPORT_BY_DIR) {
|
||||||
|
await assertBundleTransport(buildDir, expectedTransport);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error instanceof Error ? error.message : error);
|
||||||
|
process.exitCode = 1;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user