Skip to content

Commit 0e2b18b

Browse files
authored
Refactor node implementor for reuse (#22)
1 parent 468d868 commit 0e2b18b

File tree

2 files changed

+98
-71
lines changed

2 files changed

+98
-71
lines changed

implementors/node/run-tests.ts

Lines changed: 3 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import { spawn } from "node:child_process";
2-
import { promises as fs } from "node:fs";
31
import path from "node:path";
42
import { test, type TestContext } from "node:test";
53

4+
import { listDirectoryEntries, runFileInSubprocess } from "./tests.ts";
5+
66
const ROOT_PATH = path.resolve(import.meta.dirname, "..", "..");
77
const TESTS_ROOT_PATH = path.join(ROOT_PATH, "tests");
88

@@ -19,79 +19,11 @@ const LOAD_ADDON_MODULE_PATH = path.join(
1919
"load-addon.js"
2020
);
2121

22-
async function listDirectoryEntries(dir: string) {
23-
const entries = await fs.readdir(dir, { withFileTypes: true });
24-
const directories: string[] = [];
25-
const files: string[] = [];
26-
27-
for (const entry of entries) {
28-
if (entry.isDirectory()) {
29-
directories.push(entry.name);
30-
} else if (entry.isFile() && entry.name.endsWith(".js")) {
31-
files.push(entry.name);
32-
}
33-
}
34-
35-
directories.sort();
36-
files.sort();
37-
38-
return { directories, files };
39-
}
40-
41-
function runFileInSubprocess(cwd: string, filePath: string): Promise<void> {
42-
return new Promise((resolve, reject) => {
43-
const child = spawn(
44-
process.execPath,
45-
[
46-
// Using file scheme prefix when to enable imports on Windows
47-
"--import",
48-
"file://" + ASSERT_MODULE_PATH,
49-
"--import",
50-
"file://" + LOAD_ADDON_MODULE_PATH,
51-
filePath,
52-
],
53-
{ cwd }
54-
);
55-
56-
let stderrOutput = "";
57-
child.stderr.setEncoding("utf8");
58-
child.stderr.on("data", (chunk) => {
59-
stderrOutput += chunk;
60-
});
61-
62-
child.stdout.pipe(process.stdout);
63-
64-
child.on("error", reject);
65-
66-
child.on("close", (code, signal) => {
67-
if (code === 0) {
68-
resolve();
69-
return;
70-
}
71-
72-
const reason =
73-
code !== null ? `exit code ${code}` : `signal ${signal ?? "unknown"}`;
74-
const trimmedStderr = stderrOutput.trim();
75-
const stderrSuffix = trimmedStderr
76-
? `\n--- stderr ---\n${trimmedStderr}\n--- end stderr ---`
77-
: "";
78-
reject(
79-
new Error(
80-
`Test file ${path.relative(
81-
TESTS_ROOT_PATH,
82-
filePath
83-
)} failed (${reason})${stderrSuffix}`
84-
)
85-
);
86-
});
87-
});
88-
}
89-
9022
async function populateSuite(
9123
testContext: TestContext,
9224
dir: string
9325
): Promise<void> {
94-
const { directories, files } = await listDirectoryEntries(dir);
26+
const { directories, files } = listDirectoryEntries(dir);
9527

9628
for (const file of files) {
9729
await testContext.test(file, () => runFileInSubprocess(dir, file));

implementors/node/tests.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
import assert from "node:assert";
2+
import { spawn } from "node:child_process";
3+
import fs from "node:fs";
4+
import path from "node:path";
5+
6+
assert(
7+
typeof import.meta.dirname === "string",
8+
"Expecting a recent Node.js runtime API version"
9+
);
10+
11+
const ROOT_PATH = path.resolve(import.meta.dirname, "..", "..");
12+
const TESTS_ROOT_PATH = path.join(ROOT_PATH, "tests");
13+
const ASSERT_MODULE_PATH = path.join(
14+
ROOT_PATH,
15+
"implementors",
16+
"node",
17+
"assert.js"
18+
);
19+
const LOAD_ADDON_MODULE_PATH = path.join(
20+
ROOT_PATH,
21+
"implementors",
22+
"node",
23+
"load-addon.js"
24+
);
25+
26+
export function listDirectoryEntries(dir: string) {
27+
const entries = fs.readdirSync(dir, { withFileTypes: true });
28+
const directories: string[] = [];
29+
const files: string[] = [];
30+
31+
for (const entry of entries) {
32+
if (entry.isDirectory()) {
33+
directories.push(entry.name);
34+
} else if (entry.isFile() && entry.name.endsWith(".js")) {
35+
files.push(entry.name);
36+
}
37+
}
38+
39+
directories.sort();
40+
files.sort();
41+
42+
return { directories, files };
43+
}
44+
45+
export function runFileInSubprocess(
46+
cwd: string,
47+
filePath: string
48+
): Promise<void> {
49+
return new Promise((resolve, reject) => {
50+
const child = spawn(
51+
process.execPath,
52+
[
53+
// Using file scheme prefix when to enable imports on Windows
54+
"--import",
55+
"file://" + ASSERT_MODULE_PATH,
56+
"--import",
57+
"file://" + LOAD_ADDON_MODULE_PATH,
58+
filePath,
59+
],
60+
{ cwd }
61+
);
62+
63+
let stderrOutput = "";
64+
child.stderr.setEncoding("utf8");
65+
child.stderr.on("data", (chunk) => {
66+
stderrOutput += chunk;
67+
});
68+
69+
child.stdout.pipe(process.stdout);
70+
71+
child.on("error", reject);
72+
73+
child.on("close", (code, signal) => {
74+
if (code === 0) {
75+
resolve();
76+
return;
77+
}
78+
79+
const reason =
80+
code !== null ? `exit code ${code}` : `signal ${signal ?? "unknown"}`;
81+
const trimmedStderr = stderrOutput.trim();
82+
const stderrSuffix = trimmedStderr
83+
? `\n--- stderr ---\n${trimmedStderr}\n--- end stderr ---`
84+
: "";
85+
reject(
86+
new Error(
87+
`Test file ${path.relative(
88+
TESTS_ROOT_PATH,
89+
filePath
90+
)} failed (${reason})${stderrSuffix}`
91+
)
92+
);
93+
});
94+
});
95+
}

0 commit comments

Comments
 (0)