Skip to content

Commit d8879ee

Browse files
authored
chore: simplify node test script (#29459)
1 parent 1b6736d commit d8879ee

File tree

1 file changed

+34
-193
lines changed

1 file changed

+34
-193
lines changed

tests/node_compat/run_all_test_unmodified.ts

Lines changed: 34 additions & 193 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
// Copyright 2018-2025 the Deno authors. MIT license.
22
// deno-lint-ignore-file no-console
33

4+
// This script runs all Node.js test cases without modification
5+
// It saves the test results in `tests/node_compat/report.json` when
6+
// filtering is not specified.
7+
// The saved results are uploaded to cloud storage bucket `dl.deno.land`
8+
// daily, and can be viewed at the web page:
9+
// https://node-test-viewer.deno.dev/
10+
411
import { deadline } from "@std/async/deadline";
512
import { expandGlob } from "@std/fs/expand-glob";
613
import { toFileUrl } from "@std/path/to-file-url";
7-
import { basename } from "@std/path/basename";
814
import { pooledMap } from "@std/async/pool";
915
import { partition } from "@std/collections/partition";
1016
import { stripAnsiCode } from "@std/fmt/colors";
@@ -61,152 +67,12 @@ const NODE_IGNORED_TEST_DIRS = [
6167
"wpt",
6268
];
6369

64-
// Category names are usually one word, but there are some exceptions.
65-
// This list contains the exceptions.
66-
const multiWordsCategoryNames = [
67-
"async-hooks",
68-
"async-local-storage",
69-
"async-wrap",
70-
"child-process",
71-
"cpu-prof",
72-
"double-tls",
73-
"diagnostics-channel",
74-
"force-repl",
75-
"listen-fd",
76-
"memory-usage",
77-
"next-tick",
78-
"outgoing-message",
79-
"shadow-realm",
80-
"single-executable",
81-
"string-decoder",
82-
];
83-
84-
const categoryMap = {
85-
cjs: "module",
86-
cwd: "process",
87-
diagnostic: "diagnostics-channel",
88-
"double-tls": "net",
89-
event: "events",
90-
eventsource: "events",
91-
eventtarget: "events",
92-
esm: "module",
93-
file: "fs",
94-
filehandle: "fs",
95-
"force-repl": "repl",
96-
inspect: "util",
97-
"listen-fd": "net",
98-
"next-tick": "process",
99-
"outgoing-message": "http",
100-
promises: "promise",
101-
readable: "stream",
102-
require: "module",
103-
socket: "net",
104-
stdin: "stdio",
105-
stdout: "stdio",
106-
stream2: "stream",
107-
stream3: "stream",
108-
tcp: "net",
109-
ttywrap: "tty",
110-
webstream: "webstreams",
111-
} as Record<string, string>;
112-
113-
// These name could appear as category name, but they are actually not.
114-
// If the category name is one of these, it should be categorized as "others".
115-
const otherCategories = [
116-
"common",
117-
"compile",
118-
"corepack",
119-
"disable",
120-
"env",
121-
"error",
122-
"errors",
123-
"eslint",
124-
"eval",
125-
"exception",
126-
"handle",
127-
"heap",
128-
"heapdump",
129-
"heapsnapshot",
130-
"internal",
131-
"memory",
132-
"no",
133-
"queue",
134-
"release",
135-
"set",
136-
"source",
137-
"startup",
138-
"sync",
139-
"trace",
140-
"tick",
141-
"unhandled",
142-
"uv",
143-
"warn",
144-
"windows",
145-
"wrap",
146-
];
147-
148-
/**
149-
* The test files in these dirs seem categorized in the form
150-
* test-[category-name]-test-case.js
151-
*/
152-
const categorizedTestGroups = [
153-
"es-module",
154-
"parallel",
155-
"pummel",
156-
"sequential",
157-
"internet",
158-
];
159-
16070
/** The group is the directory name of the test file.
16171
* e.g. parallel, internet, pummel, sequential, pseudo-tty, etc */
16272
function getGroupRelUrl(str: string) {
16373
return str.split("/")[0];
16474
}
16575

166-
/** Gets the category name from the test path
167-
* e.g.
168-
* - parallel/test-async-hooks-destroyed-context.js -> async-hooks
169-
* - sequential/test-child-process-exec-stderr.js -> child-process
170-
* - internet/test-http-keep-alive.js -> http
171-
* - pseudo-tty/test-stdin.js -> tty
172-
* - module-hooks/test-require.js -> module
173-
*/
174-
function getCategoryFromPath(str: string) {
175-
const group = getGroupRelUrl(str);
176-
if (group === "pseudo-tty") {
177-
return "tty";
178-
} else if (group === "module-hooks") {
179-
return "module";
180-
} else if (categorizedTestGroups.includes(group)) {
181-
const name = basename(str).replace(/\.js/, "");
182-
let category = name.split("-")[1];
183-
for (const multiWord of multiWordsCategoryNames) {
184-
if (name.startsWith("test-" + multiWord)) {
185-
category = multiWord;
186-
}
187-
}
188-
category = categoryMap[category] ?? category;
189-
if (otherCategories.includes(category)) {
190-
return "others";
191-
}
192-
return category;
193-
} else {
194-
return "others";
195-
}
196-
}
197-
198-
/** Collect the items that are not categorized into the "others" category. */
199-
function collectNonCategorizedItems(categories: Record<string, string[]>) {
200-
const others = [] as string[];
201-
for (const [category, items] of Object.entries(categories)) {
202-
if (items.length === 1) {
203-
delete categories[category];
204-
others.push(...items);
205-
}
206-
}
207-
(categories["others"] ??= []).push(...others);
208-
}
209-
21076
function truncateTestOutput(output: string): string {
21177
output = stripAnsiCode(output);
21278
if (output.length > 2000) {
@@ -382,7 +248,6 @@ async function main() {
382248

383249
const start = Date.now();
384250
const tests = [] as string[];
385-
const categories = {} as Record<string, string[]>;
386251
for await (
387252
const test of expandGlob(
388253
"tests/node_compat/runner/suite/**/test-*{.mjs,.cjs.,.js,.ts}",
@@ -392,12 +257,8 @@ async function main() {
392257
const relUrl = toFileUrl(test.path).href.replace(testDirUrl, "");
393258
if (NODE_IGNORED_TEST_DIRS.every((dir) => !relUrl.startsWith(dir))) {
394259
tests.push(relUrl);
395-
(categories[getCategoryFromPath(relUrl)] ??= []).push(relUrl);
396260
}
397261
}
398-
collectNonCategorizedItems(categories);
399-
const categoryList = Object.entries(categories)
400-
.sort(([c0], [c1]) => c0.localeCompare(c1));
401262
const reports = {} as TestReports;
402263
let i = 0;
403264

@@ -420,7 +281,6 @@ async function main() {
420281
(test) => getGroupRelUrl(test) === "sequential",
421282
);
422283

423-
console.log;
424284
if (filterTerm) {
425285
sequential = sequential.filter((term) => {
426286
if (term.includes(filterTerm)) {
@@ -454,54 +314,35 @@ async function main() {
454314
// pass
455315
}
456316

457-
// Reporting to stdout
458-
console.log(`Result by categories (${categoryList.length}):`);
459-
for (const [category, tests] of categoryList) {
460-
if (
461-
tests.every((test) => reports[test].result === NodeTestFileResult.SKIP)
462-
) {
463-
continue;
464-
}
465-
const s = tests.filter((test) =>
466-
reports[test].result === NodeTestFileResult.PASS
467-
).length;
468-
const all = filterTerm
469-
? tests.map((testPath) => reports[testPath].result).filter((result) =>
470-
result !== NodeTestFileResult.SKIP
471-
).length
472-
: tests.length;
473-
console.log(` ${category} ${s}/${all} (${(s / all * 100).toFixed(2)}%)`);
474-
for (const testPath of tests) {
475-
switch (reports[testPath].result) {
476-
case NodeTestFileResult.PASS: {
477-
console.log(` %cPASS`, "color: green", testPath);
478-
break;
479-
}
480-
case NodeTestFileResult.FAIL: {
481-
// deno-lint-ignore no-explicit-any
482-
let elements: any[] = [];
483-
const error = reports[testPath].error!;
484-
if (error.code) {
485-
elements = ["exit code:", error.code, "\n ", error.stderr];
486-
} else if (error.timeout) {
487-
elements = ["timeout out after", error.timeout, "seconds"];
488-
} else {
489-
elements = ["errored with:", error.message];
490-
}
491-
console.log(` %cFAIL`, "color: red", testPath);
492-
console.log(" ", ...elements);
493-
break;
494-
}
495-
case NodeTestFileResult.SKIP: {
496-
// Don't print message for "skip" for now, as it's too noisy
497-
// console.log(` %cSKIP`, "color: yellow", testPath);
498-
break;
317+
for (const [testPath, fileResult] of Object.entries(reports)) {
318+
switch (fileResult.result) {
319+
case NodeTestFileResult.PASS: {
320+
console.log(` %cPASS`, "color: green", testPath);
321+
break;
322+
}
323+
case NodeTestFileResult.FAIL: {
324+
let elements: string[] = [];
325+
const error = fileResult.error!;
326+
if ("code" in error) {
327+
elements = [`exit code: ${error.code}\n `, error.stderr];
328+
} else if ("timeout" in error) {
329+
elements = [`timeout out after ${error.timeout} seconds`];
330+
} else {
331+
elements = ["errored with:", error.message];
499332
}
500-
default:
501-
console.warn(
502-
`Unknown result (${reports[testPath].result}) for ${testPath}`,
503-
);
333+
console.log(` %cFAIL`, "color: red", testPath);
334+
console.log(" ", ...elements);
335+
break;
336+
}
337+
case NodeTestFileResult.SKIP: {
338+
// Don't print message for "skip" for now, as it's too noisy
339+
// console.log(` %cSKIP`, "color: yellow", testPath);
340+
break;
504341
}
342+
default:
343+
console.warn(
344+
`Unknown result (${fileResult.result}) for ${testPath}`,
345+
);
505346
}
506347
}
507348

0 commit comments

Comments
 (0)