@eggjs/bin 8.0.0-beta.36 → 8.0.2-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +62 -31
- package/dist/commands/cov.d.ts +12 -8
- package/dist/commands/cov.js +43 -47
- package/dist/commands/test.d.ts +10 -12
- package/dist/commands/test.js +76 -59
- package/package.json +12 -12
package/README.md
CHANGED
|
@@ -108,18 +108,18 @@ Create `.vscode/launch.json` file:
|
|
|
108
108
|
|
|
109
109
|
### test
|
|
110
110
|
|
|
111
|
-
Using [
|
|
111
|
+
Using [vitest] to run test.
|
|
112
112
|
|
|
113
113
|
```bash
|
|
114
114
|
egg-bin test [...files] [options]
|
|
115
115
|
```
|
|
116
116
|
|
|
117
117
|
- `files` is optional, default to `test/**/*.test.ts`
|
|
118
|
-
- `test/fixtures`, `test/node_modules` is always
|
|
118
|
+
- `test/fixtures`, `test/node_modules` is always excluded.
|
|
119
119
|
|
|
120
|
-
#### auto
|
|
120
|
+
#### auto load `test/.setup.ts`
|
|
121
121
|
|
|
122
|
-
If `test/.setup.ts`
|
|
122
|
+
If `test/.setup.ts` (or `.setup.js`) exists, it will be auto-added as the first vitest `setupFile`.
|
|
123
123
|
|
|
124
124
|
```bash
|
|
125
125
|
test
|
|
@@ -127,33 +127,38 @@ test
|
|
|
127
127
|
└── foo.test.ts
|
|
128
128
|
```
|
|
129
129
|
|
|
130
|
-
####
|
|
130
|
+
#### auto-inject `@eggjs/mock/setup_vitest`
|
|
131
131
|
|
|
132
|
-
|
|
132
|
+
For egg applications, `@eggjs/mock/setup_vitest` is automatically registered as a vitest setup file when `@eggjs/mock` is installed, handling app lifecycle (`beforeAll` / `afterEach` / `afterAll`).
|
|
133
133
|
|
|
134
|
-
|
|
135
|
-
- `--changed` / `-c` only test changed test files(test files means files that match `${pwd}/test/**/*.test.(js|ts)`)
|
|
136
|
-
- `--parallel` enable mocha parallel mode, default to `false`.
|
|
137
|
-
- `--auto-agent` auto start agent in mocha master agent.
|
|
138
|
-
- `--jobs` number of jobs to run in parallel, default to `os.cpus().length - 1`.
|
|
134
|
+
#### auto use `@eggjs/tegg-vitest/runner`
|
|
139
135
|
|
|
140
|
-
|
|
136
|
+
If `@eggjs/tegg-vitest` is installed in the project, its runner is automatically detected and injected into the vitest config.
|
|
141
137
|
|
|
142
|
-
|
|
138
|
+
#### test options
|
|
143
139
|
|
|
144
|
-
|
|
140
|
+
- `--timeout` / `-t` milliseconds, default to `60000`
|
|
141
|
+
- `--no-timeout` disable timeout
|
|
142
|
+
- `--grep` / `-g` only run tests matching pattern
|
|
143
|
+
- `--bail` / `-b` stop after first test failure
|
|
144
|
+
- `--changed` / `-c` only run tests for changed files (matches `test/**/*.test.(js|ts)`)
|
|
145
|
+
- `--watch` / `-w` run in watch mode
|
|
146
|
+
|
|
147
|
+
#### test environment
|
|
148
|
+
|
|
149
|
+
You can set `TESTS` env to specify test files, supports comma-separated glob patterns.
|
|
145
150
|
|
|
146
151
|
```bash
|
|
147
152
|
TESTS=test/a.test.ts egg-bin test
|
|
148
153
|
```
|
|
149
154
|
|
|
150
|
-
|
|
155
|
+
The reporter can be set with `TEST_REPORTER` env (any vitest reporter), default is `default`.
|
|
151
156
|
|
|
152
157
|
```bash
|
|
153
|
-
TEST_REPORTER=
|
|
158
|
+
TEST_REPORTER=verbose egg-bin test
|
|
154
159
|
```
|
|
155
160
|
|
|
156
|
-
The test timeout can set
|
|
161
|
+
The test timeout can be set with `TEST_TIMEOUT` env, default is `60000` ms.
|
|
157
162
|
|
|
158
163
|
```bash
|
|
159
164
|
TEST_TIMEOUT=2000 egg-bin test
|
|
@@ -161,30 +166,56 @@ TEST_TIMEOUT=2000 egg-bin test
|
|
|
161
166
|
|
|
162
167
|
### cov
|
|
163
168
|
|
|
164
|
-
Using [
|
|
169
|
+
Using [vitest] with [v8 coverage] to run code coverage. Supports all `test` options above.
|
|
165
170
|
|
|
166
|
-
Coverage
|
|
171
|
+
Coverage reports are written to `coverage/` and include: `text-summary`, `json-summary`, `json`, `lcov`, `cobertura`.
|
|
167
172
|
|
|
168
173
|
#### cov options
|
|
169
174
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
- `-x` add dir ignore coverage, support multiple argv
|
|
173
|
-
- `--prerequire` prerequire files for coverage instrument, you can use this options if load files slowly when call `mm.app` or `mm.cluster`
|
|
174
|
-
- `--typescript` enable typescript support. If `true`, will auto add `.ts` extension and ignore `typings` and `d.ts`.
|
|
175
|
-
- `--c8` c8 instruments passthrough. you can use this to overwrite egg-bin's default c8 instruments and add additional ones.
|
|
176
|
-
> - egg-bin have some default instruments passed to c8 like `-r` and `--temp-directory`
|
|
177
|
-
> - `egg-bin cov --c8="-r teamcity -r text" --c8-report=true`
|
|
178
|
-
- also support all test params above.
|
|
175
|
+
- `-x` add a glob pattern to exclude from coverage, supports multiple
|
|
176
|
+
- also supports all test options above.
|
|
179
177
|
|
|
180
178
|
#### cov environment
|
|
181
179
|
|
|
182
|
-
You can set `COV_EXCLUDES` env to add
|
|
180
|
+
You can set `COV_EXCLUDES` env to add glob patterns to exclude from coverage (comma-separated).
|
|
183
181
|
|
|
184
182
|
```bash
|
|
185
183
|
COV_EXCLUDES="app/plugins/c*,app/autocreate/**" egg-bin cov
|
|
186
184
|
```
|
|
187
185
|
|
|
186
|
+
## Breaking Changes (v8)
|
|
187
|
+
|
|
188
|
+
### Migrated from Mocha to Vitest
|
|
189
|
+
|
|
190
|
+
The `test` and `cov` commands now use [vitest] instead of [Mocha](https://mochajs.org). This brings native TypeScript support, faster execution, and built-in watch mode, but removes some Mocha-specific options:
|
|
191
|
+
|
|
192
|
+
**Removed flags:**
|
|
193
|
+
|
|
194
|
+
| Old flag | Reason |
|
|
195
|
+
| ------------------- | --------------------------------------------------------------- |
|
|
196
|
+
| `--parallel` / `-p` | Vitest handles parallelism natively via worker pools |
|
|
197
|
+
| `--jobs` / `-j` | Replaced by vitest's built-in pool configuration |
|
|
198
|
+
| `--auto-agent` | Mocha-specific, no equivalent needed in vitest |
|
|
199
|
+
| `--prerequire` | Use `test/.setup.ts` setupFile instead |
|
|
200
|
+
| `--c8` | Coverage is now configured inside vitest, use `-x` for excludes |
|
|
201
|
+
|
|
202
|
+
**Removed environment variables:**
|
|
203
|
+
|
|
204
|
+
| Old env var | Reason |
|
|
205
|
+
| ------------ | ---------------------------------------------- |
|
|
206
|
+
| `MOCHA_FILE` | Mocha-specific, vitest runner is auto-detected |
|
|
207
|
+
|
|
208
|
+
**Changed output format:**
|
|
209
|
+
|
|
210
|
+
Test output now follows vitest's format. Assertions in test scripts that match mocha output (e.g. `"N passing"`) should be updated to vitest output (e.g. `"N passed"`).
|
|
211
|
+
|
|
212
|
+
**Migration guide:**
|
|
213
|
+
|
|
214
|
+
1. Replace `before()` / `after()` hooks with `beforeAll()` / `afterAll()` (vitest naming)
|
|
215
|
+
2. Import vitest globals explicitly in `.ts` setup files: `import { beforeAll, afterEach } from 'vitest'`
|
|
216
|
+
3. Plain `.js` test files can use globals directly (vitest `globals: true` is enabled by default)
|
|
217
|
+
4. Remove `--parallel` / `--jobs` flags from your npm scripts
|
|
218
|
+
|
|
188
219
|
## Custom egg-bin for your team
|
|
189
220
|
|
|
190
221
|
See <https://oclif.io/docs/configuring_your_cli/>
|
|
@@ -199,5 +230,5 @@ See <https://oclif.io/docs/configuring_your_cli/>
|
|
|
199
230
|
|
|
200
231
|
Made with [contributors-img](https://contrib.rocks).
|
|
201
232
|
|
|
202
|
-
[
|
|
203
|
-
[
|
|
233
|
+
[vitest]: https://vitest.dev
|
|
234
|
+
[v8 coverage]: https://vitest.dev/guide/coverage
|
package/dist/commands/cov.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { ForkNodeOptions } from "../baseCommand.js";
|
|
2
1
|
import Test from "./test.js";
|
|
2
|
+
import { InlineConfig } from "vitest/node";
|
|
3
3
|
import * as _oclif_core_interfaces6 from "@oclif/core/interfaces";
|
|
4
4
|
|
|
5
5
|
//#region src/commands/cov.d.ts
|
|
@@ -7,20 +7,24 @@ declare class Cov<T extends typeof Cov> extends Test<T> {
|
|
|
7
7
|
static description: string;
|
|
8
8
|
static examples: string[];
|
|
9
9
|
static flags: {
|
|
10
|
-
prerequire: _oclif_core_interfaces6.BooleanFlag<boolean>;
|
|
11
10
|
exclude: _oclif_core_interfaces6.OptionFlag<string[] | undefined, _oclif_core_interfaces6.CustomOptions>;
|
|
12
|
-
c8: _oclif_core_interfaces6.OptionFlag<string, _oclif_core_interfaces6.CustomOptions>;
|
|
13
11
|
bail: _oclif_core_interfaces6.BooleanFlag<boolean>;
|
|
14
12
|
timeout: _oclif_core_interfaces6.OptionFlag<number, _oclif_core_interfaces6.CustomOptions>;
|
|
15
13
|
'no-timeout': _oclif_core_interfaces6.BooleanFlag<boolean>;
|
|
16
14
|
grep: _oclif_core_interfaces6.OptionFlag<string | undefined, _oclif_core_interfaces6.CustomOptions>;
|
|
17
15
|
changed: _oclif_core_interfaces6.BooleanFlag<boolean>;
|
|
18
|
-
|
|
19
|
-
jobs: _oclif_core_interfaces6.OptionFlag<number, _oclif_core_interfaces6.CustomOptions>;
|
|
20
|
-
'auto-agent': _oclif_core_interfaces6.BooleanFlag<boolean>;
|
|
16
|
+
watch: _oclif_core_interfaces6.BooleanFlag<boolean>;
|
|
21
17
|
};
|
|
22
|
-
protected get
|
|
23
|
-
|
|
18
|
+
protected get defaultCoverageExcludes(): string[];
|
|
19
|
+
/**
|
|
20
|
+
* Convert a relative exclude pattern to an absolute path pattern.
|
|
21
|
+
* This prevents vitest's picomatch (with contains:true) from matching
|
|
22
|
+
* files in parent directories that happen to share path segments.
|
|
23
|
+
* e.g. 'test/**' should only exclude the project's own test/ dir,
|
|
24
|
+
* not files whose absolute path contains 'test/' from parent dirs.
|
|
25
|
+
*/
|
|
26
|
+
protected toAbsoluteExclude(pat: string, base: string): string;
|
|
27
|
+
protected buildVitestConfig(files: string[]): Promise<InlineConfig>;
|
|
24
28
|
}
|
|
25
29
|
//#endregion
|
|
26
30
|
export { Cov as default };
|
package/dist/commands/cov.js
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
import "../baseCommand.js";
|
|
2
1
|
import Test from "./test.js";
|
|
3
2
|
import path from "node:path";
|
|
4
|
-
import { importResolve } from "@eggjs/utils";
|
|
5
3
|
import { Flags } from "@oclif/core";
|
|
6
|
-
import fs from "node:fs/promises";
|
|
7
4
|
|
|
8
5
|
//#region src/commands/cov.ts
|
|
9
6
|
var Cov = class extends Test {
|
|
@@ -15,22 +12,17 @@ var Cov = class extends Test {
|
|
|
15
12
|
];
|
|
16
13
|
static flags = {
|
|
17
14
|
...Test.flags,
|
|
18
|
-
prerequire: Flags.boolean({ description: "prerequire files for coverage instrument" }),
|
|
19
15
|
exclude: Flags.string({
|
|
20
|
-
description: "coverage ignore, one or more files patterns
|
|
16
|
+
description: "coverage ignore, one or more files patterns",
|
|
21
17
|
multiple: true,
|
|
22
18
|
char: "x"
|
|
23
|
-
}),
|
|
24
|
-
c8: Flags.string({
|
|
25
|
-
description: "c8 instruments passthrough`",
|
|
26
|
-
default: "--temp-directory node_modules/.c8_output -r text-summary -r json-summary -r json -r lcov -r cobertura"
|
|
27
19
|
})
|
|
28
20
|
};
|
|
29
|
-
get
|
|
21
|
+
get defaultCoverageExcludes() {
|
|
30
22
|
return [
|
|
31
23
|
"example/",
|
|
32
24
|
"examples/",
|
|
33
|
-
"mocks
|
|
25
|
+
"**/mocks*/**",
|
|
34
26
|
"docs/",
|
|
35
27
|
"test/**",
|
|
36
28
|
"test{,-*}.js",
|
|
@@ -41,44 +33,48 @@ var Cov = class extends Test {
|
|
|
41
33
|
"**/*.d.ts"
|
|
42
34
|
];
|
|
43
35
|
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
]);
|
|
58
|
-
for (const exclude of excludes) {
|
|
59
|
-
c8Args.push("-x");
|
|
60
|
-
c8Args.push(exclude);
|
|
36
|
+
/**
|
|
37
|
+
* Convert a relative exclude pattern to an absolute path pattern.
|
|
38
|
+
* This prevents vitest's picomatch (with contains:true) from matching
|
|
39
|
+
* files in parent directories that happen to share path segments.
|
|
40
|
+
* e.g. 'test/**' should only exclude the project's own test/ dir,
|
|
41
|
+
* not files whose absolute path contains 'test/' from parent dirs.
|
|
42
|
+
*/
|
|
43
|
+
toAbsoluteExclude(pat, base) {
|
|
44
|
+
const isNegated = pat.startsWith("!");
|
|
45
|
+
const rawPattern = isNegated ? pat.slice(1) : pat;
|
|
46
|
+
if (path.isAbsolute(rawPattern) || rawPattern.startsWith("**")) {
|
|
47
|
+
const normalized = rawPattern.replace(/\\/g, "/");
|
|
48
|
+
return isNegated ? `!${normalized}` : normalized;
|
|
61
49
|
}
|
|
62
|
-
const
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
const execArgv = [...this.globalExecArgv, ...options.execArgv || []];
|
|
74
|
-
this.globalExecArgv = [];
|
|
75
|
-
await super.forkNode(c8File, [
|
|
76
|
-
...c8Args,
|
|
77
|
-
process.execPath,
|
|
78
|
-
...execArgv,
|
|
79
|
-
modulePath,
|
|
80
|
-
...forkArgs
|
|
50
|
+
const joined = path.join(base, rawPattern).replace(/\\/g, "/");
|
|
51
|
+
return isNegated ? `!${joined}` : joined;
|
|
52
|
+
}
|
|
53
|
+
async buildVitestConfig(files) {
|
|
54
|
+
const { flags } = this;
|
|
55
|
+
const baseConfig = await super.buildVitestConfig(files);
|
|
56
|
+
const base = flags.base.replace(/\\/g, "/");
|
|
57
|
+
const coverageExcludes = new Set([
|
|
58
|
+
...(process.env.COV_EXCLUDES?.split(",") ?? []).map((p) => this.toAbsoluteExclude(p, base)),
|
|
59
|
+
...this.defaultCoverageExcludes.map((p) => this.toAbsoluteExclude(p, base)),
|
|
60
|
+
...Array.from(flags.exclude ?? []).map((p) => this.toAbsoluteExclude(p, base))
|
|
81
61
|
]);
|
|
62
|
+
return {
|
|
63
|
+
...baseConfig,
|
|
64
|
+
coverage: {
|
|
65
|
+
enabled: true,
|
|
66
|
+
provider: "v8",
|
|
67
|
+
reporter: [
|
|
68
|
+
"text-summary",
|
|
69
|
+
"json-summary",
|
|
70
|
+
"json",
|
|
71
|
+
"lcov",
|
|
72
|
+
"cobertura"
|
|
73
|
+
],
|
|
74
|
+
exclude: Array.from(coverageExcludes),
|
|
75
|
+
reportsDirectory: path.join(base, "coverage")
|
|
76
|
+
}
|
|
77
|
+
};
|
|
82
78
|
}
|
|
83
79
|
};
|
|
84
80
|
|
package/dist/commands/test.d.ts
CHANGED
|
@@ -1,26 +1,24 @@
|
|
|
1
1
|
import { BaseCommand } from "../baseCommand.js";
|
|
2
|
-
import
|
|
2
|
+
import { InlineConfig } from "vitest/node";
|
|
3
|
+
import * as _oclif_core_interfaces16 from "@oclif/core/interfaces";
|
|
3
4
|
|
|
4
5
|
//#region src/commands/test.d.ts
|
|
5
6
|
declare class Test<T extends typeof Test> extends BaseCommand<T> {
|
|
6
7
|
static args: {
|
|
7
|
-
file:
|
|
8
|
+
file: _oclif_core_interfaces16.Arg<string | undefined, Record<string, unknown>>;
|
|
8
9
|
};
|
|
9
10
|
static description: string;
|
|
10
11
|
static examples: string[];
|
|
11
12
|
static flags: {
|
|
12
|
-
bail:
|
|
13
|
-
timeout:
|
|
14
|
-
'no-timeout':
|
|
15
|
-
grep:
|
|
16
|
-
changed:
|
|
17
|
-
|
|
18
|
-
jobs: _oclif_core_interfaces22.OptionFlag<number, _oclif_core_interfaces22.CustomOptions>;
|
|
19
|
-
'auto-agent': _oclif_core_interfaces22.BooleanFlag<boolean>;
|
|
13
|
+
bail: _oclif_core_interfaces16.BooleanFlag<boolean>;
|
|
14
|
+
timeout: _oclif_core_interfaces16.OptionFlag<number, _oclif_core_interfaces16.CustomOptions>;
|
|
15
|
+
'no-timeout': _oclif_core_interfaces16.BooleanFlag<boolean>;
|
|
16
|
+
grep: _oclif_core_interfaces16.OptionFlag<string | undefined, _oclif_core_interfaces16.CustomOptions>;
|
|
17
|
+
changed: _oclif_core_interfaces16.BooleanFlag<boolean>;
|
|
18
|
+
watch: _oclif_core_interfaces16.BooleanFlag<boolean>;
|
|
20
19
|
};
|
|
21
20
|
run(): Promise<void>;
|
|
22
|
-
protected
|
|
23
|
-
protected formatMochaArgs(): Promise<string[] | undefined>;
|
|
21
|
+
protected buildVitestConfig(files: string[]): Promise<InlineConfig>;
|
|
24
22
|
protected getChangedTestFiles(dir: string, ext: string): Promise<string[]>;
|
|
25
23
|
}
|
|
26
24
|
//#endregion
|
package/dist/commands/test.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { BaseCommand } from "../baseCommand.js";
|
|
2
|
-
import os from "node:os";
|
|
1
|
+
import { BaseCommand, ForkError } from "../baseCommand.js";
|
|
3
2
|
import path from "node:path";
|
|
4
3
|
import { debuglog } from "node:util";
|
|
5
|
-
import { EggType, detectType, importResolve } from "@eggjs/utils";
|
|
4
|
+
import { EggType, ImportResolveError, detectType, importResolve } from "@eggjs/utils";
|
|
6
5
|
import { Args, Flags } from "@oclif/core";
|
|
7
6
|
import fs from "node:fs/promises";
|
|
8
7
|
import ciParallelVars from "ci-parallel-vars";
|
|
9
8
|
import globby from "globby";
|
|
10
9
|
import { getChangedFilesForRoots } from "jest-changed-files";
|
|
10
|
+
import { startVitest } from "vitest/node";
|
|
11
11
|
|
|
12
12
|
//#region src/commands/test.ts
|
|
13
13
|
const debug = debuglog("egg/bin/commands/test");
|
|
@@ -23,7 +23,7 @@ var Test = class extends BaseCommand {
|
|
|
23
23
|
];
|
|
24
24
|
static flags = {
|
|
25
25
|
bail: Flags.boolean({
|
|
26
|
-
description: "
|
|
26
|
+
description: "abort (\"bail\") after first test failure",
|
|
27
27
|
default: false,
|
|
28
28
|
char: "b"
|
|
29
29
|
}),
|
|
@@ -41,20 +41,10 @@ var Test = class extends BaseCommand {
|
|
|
41
41
|
description: "only test with changed files and match test/**/*.test.(js|ts)",
|
|
42
42
|
char: "c"
|
|
43
43
|
}),
|
|
44
|
-
|
|
45
|
-
description: "
|
|
44
|
+
watch: Flags.boolean({
|
|
45
|
+
description: "run tests in watch mode",
|
|
46
46
|
default: false,
|
|
47
|
-
char: "
|
|
48
|
-
}),
|
|
49
|
-
jobs: Flags.integer({
|
|
50
|
-
char: "t",
|
|
51
|
-
description: "number of jobs to run in parallel",
|
|
52
|
-
default: os.cpus().length - 1
|
|
53
|
-
}),
|
|
54
|
-
"auto-agent": Flags.boolean({
|
|
55
|
-
description: "[default: true] auto bootstrap agent in mocha master process",
|
|
56
|
-
default: true,
|
|
57
|
-
allowNo: true
|
|
47
|
+
char: "w"
|
|
58
48
|
})
|
|
59
49
|
};
|
|
60
50
|
async run() {
|
|
@@ -65,35 +55,10 @@ var Test = class extends BaseCommand {
|
|
|
65
55
|
console.error("baseDir: %o not exists", flags.base);
|
|
66
56
|
throw err;
|
|
67
57
|
}
|
|
68
|
-
|
|
69
|
-
if (flags.parallel) {
|
|
70
|
-
this.env.ENABLE_MOCHA_PARALLEL = "true";
|
|
71
|
-
if (flags["auto-agent"]) this.env.AUTO_AGENT = "true";
|
|
72
|
-
}
|
|
73
|
-
this.env.NODE_ENV = "test";
|
|
58
|
+
process.env.NODE_ENV = "test";
|
|
74
59
|
if (flags["no-timeout"]) flags.timeout = 0;
|
|
75
|
-
debug("run test: %s %o flags: %o", mochaFile, this.args, flags);
|
|
76
|
-
const mochaArgs = await this.formatMochaArgs();
|
|
77
|
-
if (!mochaArgs) return;
|
|
78
|
-
await this.runMocha(mochaFile, mochaArgs);
|
|
79
|
-
}
|
|
80
|
-
async runMocha(mochaFile, mochaArgs) {
|
|
81
|
-
await this.forkNode(mochaFile, mochaArgs, { execArgv: [...process.execArgv, "--unhandled-rejections=strict"] });
|
|
82
|
-
}
|
|
83
|
-
async formatMochaArgs() {
|
|
84
|
-
const { args, flags } = this;
|
|
85
|
-
const requires = await this.formatRequires();
|
|
86
|
-
const eggType = await detectType(flags.base);
|
|
87
|
-
debug("eggType: %s", eggType);
|
|
88
|
-
if (eggType === EggType.application) try {
|
|
89
|
-
const eggMockRegister = importResolve("@eggjs/mock/register", { paths: [flags.base] });
|
|
90
|
-
requires.push(eggMockRegister);
|
|
91
|
-
debug("auto register @eggjs/mock/register: %o", eggMockRegister);
|
|
92
|
-
} catch (err) {
|
|
93
|
-
debug("auto register @eggjs/mock fail, can not require @eggjs/mock on %o, error: %s", flags.base, err.message);
|
|
94
|
-
}
|
|
95
60
|
const ext = flags.typescript ? "ts" : "js";
|
|
96
|
-
let pattern = args.file ? args.file.split(",") : [];
|
|
61
|
+
let pattern = this.args.file ? this.args.file.split(",") : [];
|
|
97
62
|
if (flags.changed) {
|
|
98
63
|
pattern = await this.getChangedTestFiles(flags.base, ext);
|
|
99
64
|
if (!pattern.length) {
|
|
@@ -104,7 +69,6 @@ var Test = class extends BaseCommand {
|
|
|
104
69
|
}
|
|
105
70
|
if (!pattern.length && process.env.TESTS) pattern = process.env.TESTS.split(",");
|
|
106
71
|
if (!pattern.length) pattern = [`test/**/*.test.${ext}`];
|
|
107
|
-
pattern = pattern.concat(["!test/fixtures", "!test/node_modules"]);
|
|
108
72
|
let files = globby.sync(pattern, { cwd: flags.base });
|
|
109
73
|
files.sort();
|
|
110
74
|
if (files.length === 0) {
|
|
@@ -121,24 +85,77 @@ var Test = class extends BaseCommand {
|
|
|
121
85
|
files = files.slice(offset, offset + currentFileCount);
|
|
122
86
|
console.log("# Split test files in parallel CI jobs: %d/%d, files: %d/%d", currentIndex + 1, totalRuns, files.length, fileCount);
|
|
123
87
|
}
|
|
88
|
+
files = files.map((f) => {
|
|
89
|
+
return (path.isAbsolute(f) ? f : path.join(flags.base, f)).replace(/\\/g, "/");
|
|
90
|
+
});
|
|
91
|
+
process.env.EGG_BIN_TIMEOUT = String(flags.timeout);
|
|
92
|
+
debug("run test with vitest, files: %o, flags: %o", files, flags);
|
|
93
|
+
const config = await this.buildVitestConfig(files);
|
|
94
|
+
if (flags["dry-run"]) {
|
|
95
|
+
console.log("vitest config: %o", config);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
if (this.env.NODE_OPTIONS) {
|
|
99
|
+
let nodeOptions = this.env.NODE_OPTIONS;
|
|
100
|
+
if (flags.typescript && !nodeOptions.includes("--no-experimental-strip-types")) nodeOptions = `--no-experimental-strip-types ${nodeOptions}`;
|
|
101
|
+
process.env.NODE_OPTIONS = nodeOptions;
|
|
102
|
+
}
|
|
103
|
+
const vitest = await startVitest("test", [], config, { configFile: false });
|
|
104
|
+
if (!vitest) throw new ForkError("vitest failed to start", 1);
|
|
105
|
+
if (flags.watch) return;
|
|
106
|
+
const failed = vitest.state.getCountOfFailedTests() ?? 0;
|
|
107
|
+
await vitest.close();
|
|
108
|
+
if (failed > 0) throw new ForkError("tests failed", 1);
|
|
109
|
+
}
|
|
110
|
+
async buildVitestConfig(files) {
|
|
111
|
+
const { flags } = this;
|
|
112
|
+
const ext = flags.typescript ? "ts" : "js";
|
|
113
|
+
const setupFiles = [];
|
|
124
114
|
const setupFile = path.join(flags.base, `test/.setup.${ext}`);
|
|
125
115
|
try {
|
|
126
116
|
await fs.access(setupFile);
|
|
127
|
-
|
|
117
|
+
setupFiles.push(setupFile.replace(/\\/g, "/"));
|
|
128
118
|
} catch {}
|
|
129
|
-
const
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
119
|
+
const requires = await this.formatRequires();
|
|
120
|
+
setupFiles.push(...requires);
|
|
121
|
+
const eggType = await detectType(flags.base);
|
|
122
|
+
debug("eggType: %s", eggType);
|
|
123
|
+
if (eggType === EggType.application) try {
|
|
124
|
+
const mockSetup = importResolve("@eggjs/mock/setup_vitest", { paths: [flags.base] });
|
|
125
|
+
setupFiles.push(mockSetup);
|
|
126
|
+
debug("auto add @eggjs/mock/setup_vitest: %o", mockSetup);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
if (!(err instanceof ImportResolveError)) throw err;
|
|
129
|
+
debug("skip @eggjs/mock/setup_vitest: @eggjs/mock not installed");
|
|
130
|
+
}
|
|
131
|
+
let runner;
|
|
132
|
+
try {
|
|
133
|
+
runner = importResolve("@eggjs/tegg-vitest/runner", { paths: [flags.base] });
|
|
134
|
+
debug("auto use @eggjs/tegg-vitest/runner: %o", runner);
|
|
135
|
+
} catch (err) {
|
|
136
|
+
if (!(err instanceof ImportResolveError)) throw err;
|
|
137
|
+
debug("skip @eggjs/tegg-vitest/runner: @eggjs/tegg-vitest not installed");
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
root: flags.base,
|
|
141
|
+
include: files,
|
|
142
|
+
exclude: [
|
|
143
|
+
"**/test/fixtures/**",
|
|
144
|
+
"**/test/node_modules/**",
|
|
145
|
+
"**/node_modules/**"
|
|
146
|
+
],
|
|
147
|
+
testTimeout: flags.timeout,
|
|
148
|
+
testNamePattern: flags.grep,
|
|
149
|
+
bail: flags.bail ? 1 : 0,
|
|
150
|
+
setupFiles,
|
|
151
|
+
runner,
|
|
152
|
+
reporters: [process.env.TEST_REPORTER ?? "default"],
|
|
153
|
+
pool: "forks",
|
|
154
|
+
execArgv: [...this.globalExecArgv],
|
|
155
|
+
watch: flags.watch,
|
|
156
|
+
globals: true,
|
|
157
|
+
server: { deps: { inline: [/^(?!.*@vitest)/] } }
|
|
158
|
+
};
|
|
142
159
|
}
|
|
143
160
|
async getChangedTestFiles(dir, ext) {
|
|
144
161
|
const changedFiles = (await getChangedFilesForRoots([path.join(dir, "test")], {})).changedFiles;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eggjs/bin",
|
|
3
|
-
"version": "8.0.
|
|
3
|
+
"version": "8.0.2-beta.0",
|
|
4
4
|
"description": "egg developer tool",
|
|
5
5
|
"homepage": "https://github.com/eggjs/egg/tree/next/tools/egg-bin",
|
|
6
6
|
"bugs": {
|
|
@@ -40,21 +40,20 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@oclif/core": "^4.2.0",
|
|
43
|
-
"
|
|
43
|
+
"@vitest/coverage-v8": "^4.0.15",
|
|
44
44
|
"ci-parallel-vars": "^1.0.1",
|
|
45
45
|
"detect-port": "^2.1.0",
|
|
46
46
|
"globby": "^11.0.2",
|
|
47
47
|
"jest-changed-files": "^30.0.0",
|
|
48
|
-
"mocha": "^11.7.5",
|
|
49
48
|
"ts-node": "^10.9.2",
|
|
50
49
|
"tsconfig-paths": "^4.2.0",
|
|
51
50
|
"utility": "^2.5.0",
|
|
52
|
-
"
|
|
51
|
+
"vitest": "^4.0.15",
|
|
52
|
+
"@eggjs/utils": "5.0.2-beta.0"
|
|
53
53
|
},
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@swc-node/register": "^1.11.1",
|
|
56
56
|
"@swc/core": "^1.15.1",
|
|
57
|
-
"@types/mocha": "^10.0.10",
|
|
58
57
|
"@types/node": "^24.10.2",
|
|
59
58
|
"assert-file": "1",
|
|
60
59
|
"coffee": "5",
|
|
@@ -65,13 +64,13 @@
|
|
|
65
64
|
"rimraf": "^6.1.2",
|
|
66
65
|
"runscript": "^2.0.1",
|
|
67
66
|
"typescript": "^5.9.3",
|
|
68
|
-
"@eggjs/mock": "7.0.
|
|
69
|
-
"@eggjs/supertest": "9.0.
|
|
70
|
-
"@eggjs/tsconfig": "3.1.
|
|
71
|
-
"egg": "4.1.
|
|
67
|
+
"@eggjs/mock": "7.0.2-beta.0",
|
|
68
|
+
"@eggjs/supertest": "9.0.2-beta.0",
|
|
69
|
+
"@eggjs/tsconfig": "3.1.2-beta.0",
|
|
70
|
+
"egg": "4.1.2-beta.0"
|
|
72
71
|
},
|
|
73
72
|
"peerDependencies": {
|
|
74
|
-
"@eggjs/mock": "7.0.
|
|
73
|
+
"@eggjs/mock": "7.0.2-beta.0"
|
|
75
74
|
},
|
|
76
75
|
"peerDependenciesMeta": {
|
|
77
76
|
"@eggjs/mock": {
|
|
@@ -92,8 +91,9 @@
|
|
|
92
91
|
},
|
|
93
92
|
"scripts": {
|
|
94
93
|
"typecheck": "tsgo --noEmit",
|
|
95
|
-
"
|
|
96
|
-
"
|
|
94
|
+
"pretest": "tsdown",
|
|
95
|
+
"test": "vitest run",
|
|
96
|
+
"cov": "vitest run --coverage",
|
|
97
97
|
"ci": "npm run cov"
|
|
98
98
|
}
|
|
99
99
|
}
|