-
-
Notifications
You must be signed in to change notification settings - Fork 45
/
test.js
75 lines (67 loc) · 2.58 KB
/
test.js
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
import fs from 'node:fs/promises';
import path from 'node:path';
import { run } from 'node:test';
import { spec } from 'node:test/reporters';
import { pathToFileURL } from 'node:url';
import { parseArgs } from 'node:util';
import glob from 'tiny-glob';
const isCI = !!process.env.CI;
const defaultTimeout = isCI ? 1200000 : 600000;
export default async function test() {
const args = parseArgs({
allowPositionals: true,
options: {
// aka --test-name-pattern: https://nodejs.org/api/test.html#filtering-tests-by-name
match: { type: 'string', alias: 'm' },
// aka --test-only: https://nodejs.org/api/test.html#only-tests
only: { type: 'boolean', alias: 'o' },
// aka --test-concurrency: https://nodejs.org/api/test.html#test-runner-execution-model
parallel: { type: 'boolean', alias: 'p' },
// experimental: https://nodejs.org/api/test.html#watch-mode
watch: { type: 'boolean', alias: 'w' },
// Test timeout in milliseconds (default: 30000ms)
timeout: { type: 'string', alias: 't' },
// Test setup file
setup: { type: 'string', alias: 's' },
},
});
const pattern = args.positionals[1];
if (!pattern) throw new Error('Missing test glob pattern');
const files = await glob(pattern, { filesOnly: true, absolute: true });
// For some reason, the `only` option does not work and we need to explicitly set the CLI flag instead.
// Node.js requires opt-in to run .only tests :(
// https://nodejs.org/api/test.html#only-tests
if (args.values.only) {
process.env.NODE_OPTIONS ??= '';
process.env.NODE_OPTIONS += ' --test-only';
}
if (!args.values.parallel) {
// If not parallel, we create a temporary file that imports all the test files
// so that it all runs in a single process.
const tempTestFile = path.resolve('./node_modules/.astro/test.mjs');
await fs.mkdir(path.dirname(tempTestFile), { recursive: true });
await fs.writeFile(
tempTestFile,
files.map((f) => `import ${JSON.stringify(pathToFileURL(f).toString())};`).join('\n')
);
files.length = 0;
files.push(tempTestFile);
}
// https://nodejs.org/api/test.html#runoptions
run({
files,
testNamePatterns: args.values.match,
concurrency: args.values.parallel,
only: args.values.only,
setup: args.values.setup,
watch: args.values.watch,
timeout: args.values.timeout ? Number(args.values.timeout) : defaultTimeout, // Node.js defaults to Infinity, so set better fallback
})
.on('test:fail', () => {
// For some reason, a test fail using the JS API does not set an exit code of 1,
// so we set it here manually
process.exitCode = 1;
})
.pipe(new spec())
.pipe(process.stdout);
}