@rstest/core 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023-present Bytedance, Inc. and its affiliates.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,11 @@
1
+ <picture>
2
+ <img alt="Rstest Banner" src="https://assets.rspack.rs/rstest/rstest-banner.png">
3
+ </picture>
4
+
5
+ # Rstest
6
+
7
+ Rstest is a testing framework powered by Rspack.
8
+
9
+ ## 📖 License
10
+
11
+ Rstest is licensed under the [MIT License](https://github.com/web-infra-dev/rstest/blob/main/LICENSE).
package/bin/rstest.js ADDED
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import nodeModule from 'node:module';
3
+
4
+ // enable on-disk code caching of all modules loaded by Node.js
5
+ // requires Nodejs >= 22.8.0
6
+ const { enableCompileCache } = nodeModule;
7
+ if (enableCompileCache) {
8
+ try {
9
+ enableCompileCache();
10
+ } catch {
11
+ // ignore errors
12
+ }
13
+ }
14
+
15
+ async function main() {
16
+ const { runCLI } = await import('../dist/cli.js');
17
+ runCLI();
18
+ }
19
+
20
+ main();
package/dist/285.js ADDED
@@ -0,0 +1,98 @@
1
+ export const __webpack_ids__ = [
2
+ "285"
3
+ ];
4
+ export const __webpack_modules__ = {
5
+ "./src/core/listTests.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
6
+ __webpack_require__.d(__webpack_exports__, {
7
+ listTests: ()=>listTests
8
+ });
9
+ var node_fs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("node:fs");
10
+ var node_path__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__("node:path");
11
+ var _pool__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__("./src/pool/index.ts");
12
+ var _utils__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__("./src/utils/index.ts");
13
+ var _rsbuild__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__("./src/core/rsbuild.ts");
14
+ async function listTests(context, fileFilters, { filesOnly, json }) {
15
+ const { normalizedConfig: { include, exclude, root, name, setupFiles: setups, includeSource }, rootPath } = context;
16
+ const testEntries = await (0, _utils__WEBPACK_IMPORTED_MODULE_3__.GL)({
17
+ include,
18
+ exclude,
19
+ root,
20
+ fileFilters,
21
+ includeSource
22
+ });
23
+ const globTestSourceEntries = async ()=>testEntries;
24
+ const setupFiles = (0, _utils__WEBPACK_IMPORTED_MODULE_3__.aA)(setups, rootPath);
25
+ const rsbuildInstance = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.z)(context, globTestSourceEntries, setupFiles);
26
+ const getRsbuildStats = await (0, _rsbuild__WEBPACK_IMPORTED_MODULE_4__.r)({
27
+ name,
28
+ globTestSourceEntries,
29
+ setupFiles,
30
+ rsbuildInstance,
31
+ rootPath
32
+ });
33
+ const { entries, setupEntries, assetFiles, sourceMaps, close, getSourcemap } = await getRsbuildStats();
34
+ const pool = await (0, _pool__WEBPACK_IMPORTED_MODULE_2__.K)({
35
+ entries,
36
+ sourceMaps,
37
+ setupEntries,
38
+ assetFiles,
39
+ context
40
+ });
41
+ const list = await pool.collectTests();
42
+ const tests = [];
43
+ const traverseTests = (test)=>{
44
+ if ([
45
+ 'skip',
46
+ 'todo'
47
+ ].includes(test.runMode)) return;
48
+ if ('case' === test.type) tests.push({
49
+ file: test.testPath,
50
+ name: (0, _utils__WEBPACK_IMPORTED_MODULE_3__.Yz)(test)
51
+ });
52
+ else for (const child of test.tests)traverseTests(child);
53
+ };
54
+ const hasError = list.some((file)=>file.errors?.length);
55
+ if (hasError) {
56
+ const { printError } = await Promise.all([
57
+ __webpack_require__.e("973"),
58
+ __webpack_require__.e("355")
59
+ ]).then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
60
+ process.exitCode = 1;
61
+ for (const file of list){
62
+ const relativePath = (0, node_path__WEBPACK_IMPORTED_MODULE_1__.relative)(rootPath, file.testPath);
63
+ if (file.errors?.length) {
64
+ _utils__WEBPACK_IMPORTED_MODULE_3__.kg.log(`${_utils__WEBPACK_IMPORTED_MODULE_3__.$_.bgRed(' FAIL ')} ${relativePath}`);
65
+ for (const error of file.errors)await printError(error, getSourcemap, rootPath);
66
+ }
67
+ }
68
+ await close();
69
+ await pool.close();
70
+ return;
71
+ }
72
+ for (const file of list){
73
+ if (filesOnly) {
74
+ tests.push({
75
+ file: file.testPath
76
+ });
77
+ continue;
78
+ }
79
+ for (const test of file.tests)traverseTests(test);
80
+ }
81
+ if (json && 'false' !== json) {
82
+ const content = JSON.stringify(tests, null, 2);
83
+ if (true !== json && 'true' !== json) {
84
+ const jsonPath = (0, node_path__WEBPACK_IMPORTED_MODULE_1__.isAbsolute)(json) ? json : (0, node_path__WEBPACK_IMPORTED_MODULE_1__.join)(rootPath, json);
85
+ (0, node_fs__WEBPACK_IMPORTED_MODULE_0__.mkdirSync)((0, node_path__WEBPACK_IMPORTED_MODULE_1__.dirname)(jsonPath), {
86
+ recursive: true
87
+ });
88
+ (0, node_fs__WEBPACK_IMPORTED_MODULE_0__.writeFileSync)(jsonPath, content);
89
+ } else _utils__WEBPACK_IMPORTED_MODULE_3__.kg.log(content);
90
+ } else for (const test of tests){
91
+ const shortPath = (0, node_path__WEBPACK_IMPORTED_MODULE_1__.relative)(rootPath, test.file);
92
+ _utils__WEBPACK_IMPORTED_MODULE_3__.kg.log(test.name ? `${_utils__WEBPACK_IMPORTED_MODULE_3__.$_.dim(`${shortPath} > `)}${test.name}` : (0, _utils__WEBPACK_IMPORTED_MODULE_3__.aj)(shortPath));
93
+ }
94
+ await close();
95
+ await pool.close();
96
+ }
97
+ }
98
+ };
package/dist/353.js ADDED
@@ -0,0 +1,488 @@
1
+ export const __webpack_ids__ = [
2
+ "353"
3
+ ];
4
+ export const __webpack_modules__ = {
5
+ "../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
6
+ __webpack_require__.d(__webpack_exports__, {
7
+ Q: ()=>parse
8
+ });
9
+ var UNKNOWN_FUNCTION = '<unknown>';
10
+ function parse(stackString) {
11
+ var lines = stackString.split('\n');
12
+ return lines.reduce(function(stack, line) {
13
+ var parseResult = parseChrome(line) || parseWinjs(line) || parseGecko(line) || parseNode(line) || parseJSC(line);
14
+ if (parseResult) stack.push(parseResult);
15
+ return stack;
16
+ }, []);
17
+ }
18
+ var chromeRe = /^\s*at (.*?) ?\(((?:file|https?|blob|chrome-extension|native|eval|webpack|rsc|<anonymous>|\/|[a-z]:\\|\\\\).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i;
19
+ var chromeEvalRe = /\((\S*)(?::(\d+))(?::(\d+))\)/;
20
+ function parseChrome(line) {
21
+ var parts = chromeRe.exec(line);
22
+ if (!parts) return null;
23
+ var isNative = parts[2] && 0 === parts[2].indexOf('native');
24
+ var isEval = parts[2] && 0 === parts[2].indexOf('eval');
25
+ var submatch = chromeEvalRe.exec(parts[2]);
26
+ if (isEval && null != submatch) {
27
+ parts[2] = submatch[1];
28
+ parts[3] = submatch[2];
29
+ parts[4] = submatch[3];
30
+ }
31
+ return {
32
+ file: isNative ? null : parts[2],
33
+ methodName: parts[1] || UNKNOWN_FUNCTION,
34
+ arguments: isNative ? [
35
+ parts[2]
36
+ ] : [],
37
+ lineNumber: parts[3] ? +parts[3] : null,
38
+ column: parts[4] ? +parts[4] : null
39
+ };
40
+ }
41
+ var winjsRe = /^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|rsc|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i;
42
+ function parseWinjs(line) {
43
+ var parts = winjsRe.exec(line);
44
+ if (!parts) return null;
45
+ return {
46
+ file: parts[2],
47
+ methodName: parts[1] || UNKNOWN_FUNCTION,
48
+ arguments: [],
49
+ lineNumber: +parts[3],
50
+ column: parts[4] ? +parts[4] : null
51
+ };
52
+ }
53
+ var geckoRe = /^\s*(.*?)(?:\((.*?)\))?(?:^|@)((?:file|https?|blob|chrome|webpack|rsc|resource|\[native).*?|[^@]*bundle)(?::(\d+))?(?::(\d+))?\s*$/i;
54
+ var geckoEvalRe = /(\S+) line (\d+)(?: > eval line \d+)* > eval/i;
55
+ function parseGecko(line) {
56
+ var parts = geckoRe.exec(line);
57
+ if (!parts) return null;
58
+ var isEval = parts[3] && parts[3].indexOf(' > eval') > -1;
59
+ var submatch = geckoEvalRe.exec(parts[3]);
60
+ if (isEval && null != submatch) {
61
+ parts[3] = submatch[1];
62
+ parts[4] = submatch[2];
63
+ parts[5] = null;
64
+ }
65
+ return {
66
+ file: parts[3],
67
+ methodName: parts[1] || UNKNOWN_FUNCTION,
68
+ arguments: parts[2] ? parts[2].split(',') : [],
69
+ lineNumber: parts[4] ? +parts[4] : null,
70
+ column: parts[5] ? +parts[5] : null
71
+ };
72
+ }
73
+ var javaScriptCoreRe = /^\s*(?:([^@]*)(?:\((.*?)\))?@)?(\S.*?):(\d+)(?::(\d+))?\s*$/i;
74
+ function parseJSC(line) {
75
+ var parts = javaScriptCoreRe.exec(line);
76
+ if (!parts) return null;
77
+ return {
78
+ file: parts[3],
79
+ methodName: parts[1] || UNKNOWN_FUNCTION,
80
+ arguments: [],
81
+ lineNumber: +parts[4],
82
+ column: parts[5] ? +parts[5] : null
83
+ };
84
+ }
85
+ var nodeRe = /^\s*at (?:((?:\[object object\])?[^\\/]+(?: \[as \S+\])?) )?\(?(.*?):(\d+)(?::(\d+))?\)?\s*$/i;
86
+ function parseNode(line) {
87
+ var parts = nodeRe.exec(line);
88
+ if (!parts) return null;
89
+ return {
90
+ file: parts[2],
91
+ methodName: parts[1] || UNKNOWN_FUNCTION,
92
+ arguments: [],
93
+ lineNumber: +parts[3],
94
+ column: parts[4] ? +parts[4] : null
95
+ };
96
+ }
97
+ },
98
+ "./src/core/index.ts": function(__unused_webpack_module, __webpack_exports__, __webpack_require__) {
99
+ __webpack_require__.d(__webpack_exports__, {
100
+ createRstest: ()=>createRstest
101
+ });
102
+ var manager_ = __webpack_require__("@vitest/snapshot/manager");
103
+ var external_std_env_ = __webpack_require__("std-env");
104
+ var src_config = __webpack_require__("./src/config.ts");
105
+ var external_pathe_ = __webpack_require__("pathe");
106
+ var stack_trace_parser_esm = __webpack_require__("../../node_modules/.pnpm/stacktrace-parser@0.1.11/node_modules/stacktrace-parser/dist/stack-trace-parser.esm.js");
107
+ var utils = __webpack_require__("./src/utils/index.ts");
108
+ var external_node_util_ = __webpack_require__("node:util");
109
+ const DEFAULT_RENDER_INTERVAL_MS = 1000;
110
+ const ESC = '\x1B[';
111
+ const CLEAR_LINE = `${ESC}K`;
112
+ const MOVE_CURSOR_ONE_ROW_UP = `${ESC}1A`;
113
+ const SYNC_START = `${ESC}?2026h`;
114
+ const SYNC_END = `${ESC}?2026l`;
115
+ class WindowRenderer {
116
+ options;
117
+ streams;
118
+ buffer = [];
119
+ renderInterval = void 0;
120
+ renderScheduled = false;
121
+ windowHeight = 0;
122
+ finished = false;
123
+ cleanups = [];
124
+ constructor(options){
125
+ this.options = {
126
+ interval: DEFAULT_RENDER_INTERVAL_MS,
127
+ ...options
128
+ };
129
+ this.streams = {
130
+ output: options.logger.outputStream.write.bind(options.logger.outputStream),
131
+ error: options.logger.errorStream.write.bind(options.logger.errorStream)
132
+ };
133
+ this.cleanups.push(this.interceptStream(process.stdout, 'output'), this.interceptStream(process.stderr, 'error'));
134
+ this.start();
135
+ }
136
+ start() {
137
+ this.finished = false;
138
+ this.renderInterval = setInterval(()=>this.schedule(), this.options.interval).unref();
139
+ }
140
+ stop() {
141
+ this.cleanups.splice(0).map((fn)=>fn());
142
+ clearInterval(this.renderInterval);
143
+ }
144
+ finish() {
145
+ this.finished = true;
146
+ this.flushBuffer();
147
+ clearInterval(this.renderInterval);
148
+ }
149
+ schedule() {
150
+ if (!this.renderScheduled) {
151
+ this.renderScheduled = true;
152
+ this.flushBuffer();
153
+ setTimeout(()=>{
154
+ this.renderScheduled = false;
155
+ }, 100).unref();
156
+ }
157
+ }
158
+ flushBuffer() {
159
+ if (0 === this.buffer.length) return this.render();
160
+ let current;
161
+ for (const next of this.buffer.splice(0)){
162
+ if (!current) {
163
+ current = next;
164
+ continue;
165
+ }
166
+ if (current.type !== next.type) {
167
+ this.render(current.message, current.type);
168
+ current = next;
169
+ continue;
170
+ }
171
+ current.message += next.message;
172
+ }
173
+ if (current) this.render(current?.message, current?.type);
174
+ }
175
+ render(message, type = 'output') {
176
+ if (this.finished) {
177
+ this.clearWindow();
178
+ return this.write(message || '', type);
179
+ }
180
+ const windowContent = this.options.getWindow();
181
+ const rowCount = getRenderedRowCount(windowContent, this.options.logger.getColumns());
182
+ let padding = this.windowHeight - rowCount;
183
+ if (padding > 0 && message) padding -= getRenderedRowCount([
184
+ message
185
+ ], this.options.logger.getColumns());
186
+ this.write(SYNC_START);
187
+ this.clearWindow();
188
+ if (message) this.write(message, type);
189
+ if (padding > 0) this.write('\n'.repeat(padding));
190
+ this.write(windowContent.join('\n'));
191
+ this.write(SYNC_END);
192
+ this.windowHeight = rowCount + Math.max(0, padding);
193
+ }
194
+ clearWindow() {
195
+ if (0 === this.windowHeight) return;
196
+ this.write(CLEAR_LINE);
197
+ for(let i = 1; i < this.windowHeight; i++)this.write(`${MOVE_CURSOR_ONE_ROW_UP}${CLEAR_LINE}`);
198
+ this.windowHeight = 0;
199
+ }
200
+ interceptStream(stream, type) {
201
+ const original = stream.write;
202
+ stream.write = (chunk, _, callback)=>{
203
+ if (chunk) if (this.finished) this.write(chunk.toString(), type);
204
+ else this.buffer.push({
205
+ type,
206
+ message: chunk.toString()
207
+ });
208
+ callback?.();
209
+ };
210
+ return function restore() {
211
+ stream.write = original;
212
+ };
213
+ }
214
+ write(message, type = 'output') {
215
+ this.streams[type](message);
216
+ }
217
+ }
218
+ function getRenderedRowCount(rows, columns) {
219
+ let count = 0;
220
+ for (const row of rows){
221
+ const text = (0, external_node_util_.stripVTControlCharacters)(row);
222
+ count += Math.max(1, Math.ceil(text.length / columns));
223
+ }
224
+ return count;
225
+ }
226
+ class StatusRenderer {
227
+ rootPath;
228
+ renderer;
229
+ runningModules = new Set();
230
+ constructor(rootPath){
231
+ this.rootPath = rootPath;
232
+ this.renderer = new WindowRenderer({
233
+ getWindow: ()=>this.getContent(),
234
+ logger: {
235
+ outputStream: process.stdout,
236
+ errorStream: process.stderr,
237
+ getColumns: ()=>'columns' in process.stdout ? process.stdout.columns : 80
238
+ }
239
+ });
240
+ }
241
+ getContent() {
242
+ const summary = [];
243
+ for (const module of this.runningModules){
244
+ const relativePath = (0, external_pathe_.relative)(this.rootPath, module);
245
+ summary.push(`${utils.$_.bgYellow(utils.$_.bold(' RUNS '))} ${(0, utils.aj)(relativePath)}`);
246
+ }
247
+ summary.push('');
248
+ return summary;
249
+ }
250
+ addRunningModule(testPath) {
251
+ this.runningModules.add(testPath);
252
+ this.renderer?.schedule();
253
+ }
254
+ removeRunningModule(testPath) {
255
+ this.runningModules.delete(testPath);
256
+ this.renderer?.schedule();
257
+ }
258
+ clear() {
259
+ this.runningModules.clear();
260
+ this.renderer?.finish();
261
+ }
262
+ }
263
+ const getSummaryStatusString = (tasks, name = 'tests', showTotal = true)=>{
264
+ if (0 === tasks.length) return utils.$_.dim(`no ${name}`);
265
+ const passed = tasks.filter((result)=>'pass' === result.status);
266
+ const failed = tasks.filter((result)=>'fail' === result.status);
267
+ const skipped = tasks.filter((result)=>'skip' === result.status);
268
+ const todo = tasks.filter((result)=>'todo' === result.status);
269
+ const status = [
270
+ failed.length ? utils.$_.bold(utils.$_.red(`${failed.length} failed`)) : null,
271
+ passed.length ? utils.$_.bold(utils.$_.green(`${passed.length} passed`)) : null,
272
+ skipped.length ? utils.$_.yellow(`${skipped.length} skipped`) : null,
273
+ todo.length ? utils.$_.gray(`${todo.length} todo`) : null
274
+ ].filter(Boolean);
275
+ return status.join(utils.$_.dim(' | ')) + (showTotal && status.length > 1 ? utils.$_.gray(` (${tasks.length})`) : '');
276
+ };
277
+ const printSnapshotSummaryLog = (snapshots, rootDir)=>{
278
+ const summary = [];
279
+ if (snapshots.added) summary.push(utils.$_.bold(utils.$_.green(`${snapshots.added} written`)));
280
+ if (snapshots.unmatched) summary.push(utils.$_.bold(utils.$_.red(`${snapshots.unmatched} failed`)));
281
+ if (snapshots.updated) summary.push(utils.$_.bold(utils.$_.green(`${snapshots.updated} updated `)));
282
+ if (snapshots.filesRemoved) if (snapshots.didUpdate) summary.push(utils.$_.bold(utils.$_.green(`${snapshots.filesRemoved} files removed `)));
283
+ else summary.push(utils.$_.bold(utils.$_.yellow(`${snapshots.filesRemoved} files obsolete `)));
284
+ const POINTER = "\u279C";
285
+ if (snapshots.filesRemovedList?.length) {
286
+ const [head, ...tail] = snapshots.filesRemovedList;
287
+ summary.push(`${utils.$_.gray(POINTER)} ${(0, utils.Ps)(rootDir, head)}`);
288
+ for (const key of tail)summary.push(` ${(0, utils.Ps)(rootDir, key)}`);
289
+ }
290
+ if (snapshots.unchecked) {
291
+ if (snapshots.didUpdate) summary.push(utils.$_.bold(utils.$_.green(`${snapshots.unchecked} removed`)));
292
+ else summary.push(utils.$_.bold(utils.$_.yellow(`${snapshots.unchecked} obsolete`)));
293
+ for (const uncheckedFile of snapshots.uncheckedKeysByFile){
294
+ summary.push(`${utils.$_.gray(POINTER)} ${(0, utils.Ps)(rootDir, uncheckedFile.filePath)}`);
295
+ for (const key of uncheckedFile.keys)summary.push(` ${key}`);
296
+ }
297
+ }
298
+ for (const [index, snapshot] of summary.entries()){
299
+ const title = 0 === index ? 'Snapshots' : '';
300
+ utils.kg.log(`${utils.$_.gray(title.padStart(12))} ${snapshot}`);
301
+ }
302
+ };
303
+ const printSummaryLog = ({ results, testResults, snapshotSummary, duration, rootPath })=>{
304
+ utils.kg.log('');
305
+ printSnapshotSummaryLog(snapshotSummary, rootPath);
306
+ utils.kg.log(`${utils.$_.gray('Test Files'.padStart(11))} ${getSummaryStatusString(results)}`);
307
+ utils.kg.log(`${utils.$_.gray('Tests'.padStart(11))} ${getSummaryStatusString(testResults)}`);
308
+ utils.kg.log(`${utils.$_.gray('Duration'.padStart(11))} ${(0, utils.AS)(duration.totalTime)} ${utils.$_.gray(`(build ${(0, utils.AS)(duration.buildTime)}, tests ${(0, utils.AS)(duration.testTime)})`)}`);
309
+ utils.kg.log('');
310
+ };
311
+ const printSummaryErrorLogs = async ({ testResults, results, rootPath, getSourcemap })=>{
312
+ const failedTests = [
313
+ ...results.filter((i)=>'fail' === i.status && i.errors?.length),
314
+ ...testResults.filter((i)=>'fail' === i.status)
315
+ ];
316
+ if (0 === failedTests.length) return;
317
+ utils.kg.log('');
318
+ utils.kg.log(utils.$_.bold('Summary of all failing tests:'));
319
+ utils.kg.log('');
320
+ for (const test of failedTests){
321
+ const relativePath = external_pathe_["default"].relative(rootPath, test.testPath);
322
+ const nameStr = (0, utils.Yz)(test);
323
+ utils.kg.log(`${utils.$_.bgRed(' FAIL ')} ${(0, utils.aj)(relativePath)} ${nameStr.length ? `${utils.$_.dim(utils.Qd)} ${nameStr}` : ''}`);
324
+ if (test.errors) {
325
+ const { printError } = await Promise.all([
326
+ __webpack_require__.e("973"),
327
+ __webpack_require__.e("355")
328
+ ]).then(__webpack_require__.bind(__webpack_require__, "./src/utils/error.ts"));
329
+ for (const error of test.errors)await printError(error, getSourcemap, rootPath);
330
+ }
331
+ }
332
+ };
333
+ const statusStr = {
334
+ fail: "\u2717",
335
+ pass: "\u2713",
336
+ todo: '-',
337
+ skip: '-'
338
+ };
339
+ const statusColorfulStr = {
340
+ fail: utils.$_.red(statusStr.fail),
341
+ pass: utils.$_.green(statusStr.pass),
342
+ todo: utils.$_.gray(statusStr.todo),
343
+ skip: utils.$_.gray(statusStr.skip)
344
+ };
345
+ class DefaultReporter {
346
+ rootPath;
347
+ config;
348
+ options = {};
349
+ statusRenderer;
350
+ constructor({ rootPath, options, config }){
351
+ this.rootPath = rootPath;
352
+ this.config = config;
353
+ this.options = options;
354
+ if (!external_std_env_.isCI) this.statusRenderer = new StatusRenderer(rootPath);
355
+ }
356
+ onTestFileStart(test) {
357
+ this.statusRenderer?.addRunningModule(test.testPath);
358
+ }
359
+ onTestFileResult(test) {
360
+ this.statusRenderer?.removeRunningModule(test.testPath);
361
+ const relativePath = (0, external_pathe_.relative)(this.rootPath, test.testPath);
362
+ const { slowTestThreshold } = this.config;
363
+ let title = ` ${utils.$_.bold(statusColorfulStr[test.status])} ${(0, utils.aj)(relativePath)}`;
364
+ const formatDuration = (duration)=>utils.$_[duration > slowTestThreshold ? 'yellow' : 'green'](`${(0, utils.AS)(duration, false)}`);
365
+ title += ` ${utils.$_.gray(`(${test.results.length})`)}`;
366
+ const isTooSlow = test.duration && test.duration > slowTestThreshold;
367
+ if (isTooSlow) title += ` ${formatDuration(test.duration)}`;
368
+ utils.kg.log(title);
369
+ if ('fail' !== test.status && !isTooSlow) return;
370
+ const showAllCases = isTooSlow && !test.results.some((result)=>(result.duration || 0) > slowTestThreshold);
371
+ for (const result of test.results){
372
+ const isSlowCase = (result.duration || 0) > slowTestThreshold;
373
+ if (!showAllCases && 'fail' !== result.status && !isSlowCase) continue;
374
+ const icon = isSlowCase && 'pass' === result.status ? utils.$_.yellow(statusStr[result.status]) : statusColorfulStr[result.status];
375
+ const nameStr = (0, utils.Yz)(result);
376
+ const duration = void 0 !== result.duration ? ` (${(0, utils.AS)(result.duration, false)})` : '';
377
+ console.log(` ${icon} ${nameStr}${utils.$_.gray(duration)}`);
378
+ if (result.errors) for (const error of result.errors)console.error(utils.$_.red(` ${error.message}`));
379
+ }
380
+ }
381
+ onTestCaseResult(_result) {}
382
+ onUserConsoleLog(log) {
383
+ const shouldLog = this.config.onConsoleLog?.(log.content) ?? true;
384
+ if (!shouldLog) return;
385
+ const titles = [
386
+ log.name
387
+ ];
388
+ const testPath = (0, external_pathe_.relative)(this.rootPath, log.testPath);
389
+ if (log.trace) {
390
+ const [frame] = (0, stack_trace_parser_esm.Q)(log.trace);
391
+ const filePath = (0, external_pathe_.relative)(this.rootPath, frame.file || '');
392
+ if (filePath !== testPath) titles.push((0, utils.aj)(testPath));
393
+ titles.push((0, utils.aj)(filePath) + utils.$_.gray(`:${frame.lineNumber}:${frame.column}`));
394
+ } else titles.push((0, utils.aj)(testPath));
395
+ utils.kg.log(titles.join(utils.$_.gray(' | ')));
396
+ utils.kg.log(log.content);
397
+ utils.kg.log('');
398
+ }
399
+ async onExit() {
400
+ this.statusRenderer?.clear();
401
+ }
402
+ async onTestRunEnd({ results, testResults, duration, getSourcemap, snapshotSummary }) {
403
+ this.statusRenderer?.clear();
404
+ if (false === this.options.summary) return;
405
+ await printSummaryErrorLogs({
406
+ testResults,
407
+ results,
408
+ rootPath: this.rootPath,
409
+ getSourcemap
410
+ });
411
+ printSummaryLog({
412
+ results,
413
+ testResults,
414
+ duration,
415
+ rootPath: this.rootPath,
416
+ snapshotSummary
417
+ });
418
+ }
419
+ }
420
+ var helper = __webpack_require__("./src/utils/helper.ts");
421
+ const reportersMap = {
422
+ default: DefaultReporter
423
+ };
424
+ function createReporters(reporters, initOptions = {}) {
425
+ const result = (0, helper.XQ)(reporters).map((reporter)=>{
426
+ if ('string' == typeof reporter || Array.isArray(reporter)) {
427
+ const [name, options = {}] = (0, helper.XQ)(reporter);
428
+ if (name in reportersMap) {
429
+ const Reporter = reportersMap[name];
430
+ return new Reporter({
431
+ ...initOptions,
432
+ options
433
+ });
434
+ }
435
+ throw new Error(`Reporter ${reporter} not found. Please install it or use a built-in reporter.`);
436
+ }
437
+ return reporter;
438
+ });
439
+ return result;
440
+ }
441
+ function createContext(options, userConfig) {
442
+ const { cwd, command } = options;
443
+ const rootPath = userConfig.root ? (0, helper.ZY)(cwd, userConfig.root) : cwd;
444
+ const rstestConfig = (0, src_config.hY)(userConfig);
445
+ const reporters = 'list' !== command ? createReporters(rstestConfig.reporters, {
446
+ rootPath,
447
+ config: rstestConfig
448
+ }) : [];
449
+ const snapshotManager = new manager_.SnapshotManager({
450
+ updateSnapshot: rstestConfig.update ? 'all' : external_std_env_.isCI ? 'none' : 'new'
451
+ });
452
+ return {
453
+ command,
454
+ version: "0.0.1",
455
+ rootPath,
456
+ reporters,
457
+ snapshotManager,
458
+ originalConfig: userConfig,
459
+ normalizedConfig: rstestConfig
460
+ };
461
+ }
462
+ function createRstest(config, command, fileFilters) {
463
+ const context = createContext({
464
+ cwd: process.cwd(),
465
+ command
466
+ }, config);
467
+ const runTests = async ()=>{
468
+ const { runTests } = await Promise.all([
469
+ __webpack_require__.e("992"),
470
+ __webpack_require__.e("629")
471
+ ]).then(__webpack_require__.bind(__webpack_require__, "./src/core/runTests.ts"));
472
+ await runTests(context, fileFilters);
473
+ };
474
+ const listTests = async (options)=>{
475
+ const { listTests } = await Promise.all([
476
+ __webpack_require__.e("992"),
477
+ __webpack_require__.e("285")
478
+ ]).then(__webpack_require__.bind(__webpack_require__, "./src/core/listTests.ts"));
479
+ await listTests(context, fileFilters, options);
480
+ };
481
+ return {
482
+ context,
483
+ runTests,
484
+ listTests
485
+ };
486
+ }
487
+ }
488
+ };