forked from nodejs/node-api-cts
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrun-tests.ts
More file actions
116 lines (98 loc) · 2.78 KB
/
run-tests.ts
File metadata and controls
116 lines (98 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import { spawn } from "node:child_process";
import { promises as fs } from "node:fs";
import path from "node:path";
import { test, type TestContext } from "node:test";
const ROOT_PATH = path.resolve(import.meta.dirname, "..", "..");
const TESTS_ROOT_PATH = path.join(ROOT_PATH, "tests");
const ASSERT_MODULE_PATH = path.join(
ROOT_PATH,
"implementors",
"node",
"assert.js"
);
const LOAD_ADDON_MODULE_PATH = path.join(
ROOT_PATH,
"implementors",
"node",
"load-addon.js"
);
async function listDirectoryEntries(dir: string) {
const entries = await fs.readdir(dir, { withFileTypes: true });
const directories: string[] = [];
const files: string[] = [];
for (const entry of entries) {
if (entry.isDirectory()) {
directories.push(entry.name);
} else if (entry.isFile() && entry.name.endsWith(".js")) {
files.push(entry.name);
}
}
directories.sort();
files.sort();
return { directories, files };
}
function runFileInSubprocess(cwd: string, filePath: string): Promise<void> {
return new Promise((resolve, reject) => {
const child = spawn(
process.execPath,
[
"--import",
ASSERT_MODULE_PATH,
"--import",
LOAD_ADDON_MODULE_PATH,
filePath,
],
{ cwd }
);
let stderrOutput = "";
child.stderr.setEncoding("utf8");
child.stderr.on("data", (chunk) => {
stderrOutput += chunk;
});
child.stdout.pipe(process.stdout);
child.on("error", reject);
child.on("close", (code, signal) => {
if (code === 0) {
resolve();
return;
}
const reason =
code !== null ? `exit code ${code}` : `signal ${signal ?? "unknown"}`;
const trimmedStderr = stderrOutput.trim();
const stderrSuffix = trimmedStderr
? `\n--- stderr ---\n${trimmedStderr}\n--- end stderr ---`
: "";
reject(
new Error(
`Test file ${path.relative(
TESTS_ROOT_PATH,
filePath
)} failed (${reason})${stderrSuffix}`
)
);
});
});
}
async function populateSuite(
testContext: TestContext,
dir: string
): Promise<void> {
const { directories, files } = await listDirectoryEntries(dir);
for (const file of files) {
await testContext.test(file, () => runFileInSubprocess(dir, file));
}
for (const directory of directories) {
await testContext.test(directory, async (subTest) => {
await populateSuite(subTest, path.join(dir, directory));
});
}
}
test("harness", async (t) => {
await populateSuite(t, path.join(TESTS_ROOT_PATH, "harness"));
});
test("js-native-api", async (t) => {
await populateSuite(t, path.join(TESTS_ROOT_PATH, "js-native-api"));
});
test("node-api", async (t) => {
await populateSuite(t, path.join(TESTS_ROOT_PATH, "node-api"));
});