Skip to content

Commit

Permalink
Add tool to write multi-module tests in a single file
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolo-ribaudo committed Jul 25, 2024
1 parent f742eb0 commit ad9f91c
Showing 1 changed file with 85 additions and 0 deletions.
85 changes: 85 additions & 0 deletions tools/misc/explode-bundle.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import fs from "node:fs";
import { resolve, basename, join as joinPaths } from "node:path";
import { fileURLToPath } from "node:url";

async function* walk(dir) {
for await (const d of fs.opendirSync(dir)) {
const entry = joinPaths(dir, d.name);
if (d.isDirectory()) yield* walk(entry);
else if (d.isFile()) yield entry;
}
}

const testsDir = resolve(fileURLToPath(import.meta.url), "../../../test");

for await (const bundleFilename of walk(testsDir)) {
if (/\.multi(?:\.md)$/.test(bundleFilename)) {
const folder = bundleFilename.replace(/\.multi(?:\.md)$/, "__generated");

const bundle = fs.readFileSync(bundleFilename, "utf8");
const allFiles = parse(bundleFilename, bundle);

const fixtureRE = /_FIXTURE\.\w+$/;
if (allFiles.filter((f) => !fixtureRE.test(f.filename)).length !== 1) {
throw new Error(
`Exactly one file must not end in _FIXTURE (in ${bundleFilename})`
);
}

fs.rmSync(folder, { force: true, recursive: true });
fs.mkdirSync(folder);
for (const { filename, code } of allFiles) {
fs.writeFileSync(joinPaths(folder, filename), code);
}
}
}

/**
* @param {string} bundleFilename
* @param {string} bundle
*/
function parse(bundleFilename, bundle) {
let index = 0;

const files = [];
let prefix = null;

while (true) {
let nextTitle = bundle.indexOf("##", index);
let nextCodeStart = bundle.indexOf("```", index);
let nextCodeEnd = bundle.indexOf("```", nextCodeStart + 3);
if (nextCodeStart === -1 && nextTitle === -1) break;

if (nextTitle === -1 || nextTitle > nextCodeStart) {
throw new Error(
`Code blocks must be preceded by a filename, with ## (in ${bundleFilename})`
);
}
if (nextCodeEnd === -1) {
throw new Error(`Unclosed code block (in ${bundleFilename})`);
}

if (prefix === null) {
prefix = bundle.slice(index, nextTitle).trim();
if (prefix !== "") prefix = prefix.replaceAll(/^/gm, "// ") + "\n\n";
prefix =
"// THIS FILE IS AUTOGENERATED. DO NOT EDIT DIRECTLY.\n" +
`// TO MAKE CHANGES, EDIT ../${basename(bundleFilename)}\n\n` +
prefix;
}
const filename = bundle.slice(nextTitle + 2, nextCodeStart).trim();
const code =
(filename.endsWith(".js") ? prefix : "") +
bundle
.slice(nextCodeStart + 3, nextCodeEnd)
.replace(/^\w+/, "")
.trim() +
"\n";

files.push({ filename, code });

index = nextCodeEnd + 3;
}

return files;
}

0 comments on commit ad9f91c

Please sign in to comment.