Skip to content

Commit 0dbdfcb

Browse files
9aoyCopilot
andauthored
chore: no need to run files when run list filesOnly (#689)
Co-authored-by: Copilot <[email protected]>
1 parent 86a9c3d commit 0dbdfcb

File tree

3 files changed

+183
-45
lines changed

3 files changed

+183
-45
lines changed

packages/core/src/core/listTests.ts

Lines changed: 101 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import { mkdirSync, writeFileSync } from 'node:fs';
22
import { dirname, isAbsolute, join, relative } from 'node:path';
33
import { createPool } from '../pool';
4-
import type { ListCommandOptions, RstestContext, Test } from '../types';
4+
import type {
5+
FormattedError,
6+
ListCommandOptions,
7+
RstestContext,
8+
Test,
9+
} from '../types';
510
import {
611
color,
712
getSetupFiles,
@@ -12,38 +17,13 @@ import {
1217
} from '../utils';
1318
import { createRsbuildServer, prepareRsbuild } from './rsbuild';
1419

15-
export async function listTests(
16-
context: RstestContext,
17-
{ filesOnly, json }: ListCommandOptions,
18-
): Promise<void> {
19-
const { rootPath } = context;
20-
21-
const testEntries: Record<string, Record<string, string>> = {};
22-
23-
const globTestSourceEntries = async (
24-
name: string,
25-
): Promise<Record<string, string>> => {
26-
if (testEntries[name]) {
27-
return testEntries[name];
28-
}
29-
const { include, exclude, includeSource, root } = context.projects.find(
30-
(p) => p.environmentName === name,
31-
)!.normalizedConfig;
32-
33-
const entries = await getTestEntries({
34-
include,
35-
exclude: exclude.patterns,
36-
rootPath,
37-
projectRoot: root,
38-
fileFilters: context.fileFilters || [],
39-
includeSource,
40-
});
41-
42-
testEntries[name] = entries;
43-
44-
return entries;
45-
};
46-
20+
const collectTests = async ({
21+
context,
22+
globTestSourceEntries,
23+
}: {
24+
context: RstestContext;
25+
globTestSourceEntries: (name: string) => Promise<Record<string, string>>;
26+
}) => {
4727
const setupFiles = Object.fromEntries(
4828
context.projects.map((project) => {
4929
const {
@@ -70,7 +50,7 @@ export async function listTests(
7050
},
7151
setupFiles,
7252
rsbuildInstance,
73-
rootPath,
53+
rootPath: context.rootPath,
7454
});
7555

7656
const pool = await createPool({
@@ -106,7 +86,90 @@ export async function listTests(
10686
}),
10787
);
10888

109-
const list = returns.flatMap((r) => r.list);
89+
return {
90+
list: returns.flatMap((r) => r.list),
91+
getSourceMap: async (name: string) => {
92+
const resource = returns.find((r) => r.assetNames.includes(name));
93+
return (await resource?.getSourceMaps([name]))?.[name];
94+
},
95+
close: async () => {
96+
await closeServer();
97+
await pool.close();
98+
},
99+
};
100+
};
101+
102+
const collectTestFiles = async ({
103+
context,
104+
globTestSourceEntries,
105+
}: {
106+
context: RstestContext;
107+
globTestSourceEntries: (name: string) => Promise<Record<string, string>>;
108+
}) => {
109+
const list: {
110+
tests: Test[];
111+
testPath: string;
112+
project: string;
113+
errors?: FormattedError[];
114+
}[] = [];
115+
for (const project of context.projects) {
116+
const files = await globTestSourceEntries(project.environmentName);
117+
list.push(
118+
...Object.values(files).map((testPath) => ({
119+
testPath,
120+
project: project.name,
121+
tests: [],
122+
})),
123+
);
124+
}
125+
return {
126+
close: async () => {},
127+
list,
128+
getSourceMap: async (_name: string) => null,
129+
};
130+
};
131+
132+
export async function listTests(
133+
context: RstestContext,
134+
{ filesOnly, json }: ListCommandOptions,
135+
): Promise<void> {
136+
const { rootPath } = context;
137+
138+
const testEntries: Record<string, Record<string, string>> = {};
139+
140+
const globTestSourceEntries = async (
141+
name: string,
142+
): Promise<Record<string, string>> => {
143+
if (testEntries[name]) {
144+
return testEntries[name];
145+
}
146+
const { include, exclude, includeSource, root } = context.projects.find(
147+
(p) => p.environmentName === name,
148+
)!.normalizedConfig;
149+
150+
const entries = await getTestEntries({
151+
include,
152+
exclude: exclude.patterns,
153+
rootPath,
154+
projectRoot: root,
155+
fileFilters: context.fileFilters || [],
156+
includeSource,
157+
});
158+
159+
testEntries[name] = entries;
160+
161+
return entries;
162+
};
163+
164+
const { list, close, getSourceMap } = filesOnly
165+
? await collectTestFiles({
166+
context,
167+
globTestSourceEntries,
168+
})
169+
: await collectTests({
170+
context,
171+
globTestSourceEntries,
172+
});
110173

111174
const tests: {
112175
file: string;
@@ -156,9 +219,7 @@ export async function listTests(
156219
await printError(
157220
error,
158221
async (name) => {
159-
const resource = returns.find((r) => r.assetNames.includes(name));
160-
161-
const sourceMap = (await resource?.getSourceMaps([name]))?.[name];
222+
const sourceMap = await getSourceMap(name);
162223
return sourceMap ? JSON.parse(sourceMap) : null;
163224
},
164225
rootPath,
@@ -167,9 +228,7 @@ export async function listTests(
167228
}
168229
}
169230

170-
await closeServer();
171-
172-
await pool.close();
231+
await close();
173232
return;
174233
}
175234

@@ -212,6 +271,5 @@ export async function listTests(
212271
}
213272
}
214273

215-
await closeServer();
216-
await pool.close();
274+
await close();
217275
}

website/docs/en/config/test/include.mdx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
- **Default:** `['**/*.{test,spec}.?(c|m)[jt]s?(x)']`
55
- **CLI:** `--include '**/*.test.ts' --include '**/*.spec.ts'`
66

7-
A list of glob patterns that match your test files.
7+
A list of glob patterns that match your test files. These patterns will be resolved relative to the [root](/config/test/root) (`process.cwd()` by default).
88

99
import { Tab, Tabs } from '@theme';
1010

@@ -24,3 +24,43 @@ export default defineConfig({
2424
```
2525
</Tab>
2626
</Tabs>
27+
28+
You can run `npx rstest list --filesOnly` to see the list of test files that Rstest will include.
29+
30+
```bash
31+
$ npx rstest list --filesOnly
32+
33+
# the output is shown below:
34+
a.test.ts
35+
b.test.ts
36+
```
37+
38+
## Default behavior
39+
40+
By default, Rstest will include all javascript / typescript files with `.test.` or `.spec.` suffix in the filename.
41+
42+
The following is a visualization of the default pattern:
43+
44+
```bash
45+
├── __tests__
46+
│ └── index.test.js # test
47+
│ └── App.spec.tsx # test
48+
│ └── helper.ts # not test
49+
├── src
50+
│ └── component.ts # not test
51+
│ └── component.test.tsx # test
52+
├── bar.spec.jsx # test
53+
├── index.test.js # test
54+
└── index.js # not test
55+
```
56+
57+
It should be noted that if you specify `index.test.ts` as the include pattern, Rstest will only include `index.test.ts` in the root directory. If you want to include `index.test.ts` in all subdirectories, you need to use `**/index.test.ts`.
58+
59+
```diff
60+
import { defineConfig } from '@rstest/core';
61+
62+
export default defineConfig({
63+
- include: ['index.test.ts'],
64+
+ include: ['**/index.test.ts'],
65+
});
66+
```

website/docs/zh/config/test/include.mdx

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
- **默认值:** `['**/*.{test,spec}.?(c|m)[jt]s?(x)']`
55
- **CLI:** `--include '**/*.test.ts' --include '**/*.spec.ts'`
66

7-
匹配 glob 规则的文件将被视为测试文件。
7+
匹配 glob 规则的文件将被视为测试文件。这些规则会相对于 [root](/config/test/root) 解析(默认是 `process.cwd()`)。
88

99
import { Tab, Tabs } from '@theme';
1010

@@ -24,3 +24,43 @@ export default defineConfig({
2424
```
2525
</Tab>
2626
</Tabs>
27+
28+
你可以运行 `npx rstest list --filesOnly` 来查看 Rstest 会包含的测试文件列表。
29+
30+
```bash
31+
$ npx rstest list --filesOnly
32+
33+
# the output is shown below:
34+
a.test.ts
35+
b.test.ts
36+
```
37+
38+
## 默认行为
39+
40+
默认情况下,Rstest 会匹配当前项目下所有文件名带有 `.test.``.spec.` 中缀的 JavaScript / TypeScript 文件。
41+
42+
下面是默认匹配模式的示例:
43+
44+
```bash
45+
├── __tests__
46+
│ └── index.test.js # test
47+
│ └── App.spec.tsx # test
48+
│ └── helper.ts # not test
49+
├── src
50+
│ └── component.ts # not test
51+
│ └── component.test.tsx # test
52+
├── bar.spec.jsx # test
53+
├── index.test.js # test
54+
└── index.js # not test
55+
```
56+
57+
需要注意的是,如果你将 `include` 配置为 `index.test.ts`,Rstest 只会匹配根目录下的 `index.test.ts`。如果要匹配所有子目录中的 `index.test.ts`,需要使用 `**/index.test.ts`
58+
59+
```diff
60+
import { defineConfig } from '@rstest/core';
61+
62+
export default defineConfig({
63+
- include: ['index.test.ts'],
64+
+ include: ['**/index.test.ts'],
65+
});
66+
```

0 commit comments

Comments
 (0)