sxy-test-runner 2.5.0 → 2.5.2
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/AGENTS.md +9 -1
- package/dist/cli/cliTypes.d.ts +1 -0
- package/dist/cli/cliTypes.js.map +1 -1
- package/dist/cli/init.js +3 -0
- package/dist/cli/init.js.map +1 -1
- package/dist/cli/lib/addBasePath.js +1 -1
- package/dist/cli/lib/addBasePath.js.map +1 -1
- package/dist/cli/lib/buildDependencyTrees.d.ts +1 -1
- package/dist/cli/lib/buildDependencyTrees.js +2 -2
- package/dist/cli/lib/buildDependencyTrees.js.map +1 -1
- package/dist/cli/lib/defaultConfig.js +1 -0
- package/dist/cli/lib/defaultConfig.js.map +1 -1
- package/dist/cli/lib/failureEntries.js +6 -3
- package/dist/cli/lib/failureEntries.js.map +1 -1
- package/dist/cli/lib/filter.js +2 -2
- package/dist/cli/lib/filter.js.map +1 -1
- package/dist/cli/lib/findTestFiles.js +1 -1
- package/dist/cli/lib/findTestFiles.js.map +1 -1
- package/dist/cli/lib/parseCommandLineArguments.js +20 -8
- package/dist/cli/lib/parseCommandLineArguments.js.map +1 -1
- package/dist/cli/lib/parseDescribe.js +1 -1
- package/dist/cli/lib/parseDescribe.js.map +1 -1
- package/dist/cli/lib/runDescribe.js +1 -1
- package/dist/cli/lib/runDescribe.js.map +1 -1
- package/dist/cli/lib/runDescribeRun.js +1 -1
- package/dist/cli/lib/runDescribeRun.js.map +1 -1
- package/dist/cli/lib/runIt.js +1 -1
- package/dist/cli/lib/runIt.js.map +1 -1
- package/dist/cli/lib/runTests.js +9 -188
- package/dist/cli/lib/runTests.js.map +1 -1
- package/dist/cli/lib/showFailuresColorized.d.ts +2 -0
- package/dist/cli/lib/showFailuresColorized.js +52 -0
- package/dist/cli/lib/showFailuresColorized.js.map +1 -0
- package/dist/cli/lib/showTestFileResult.d.ts +7 -0
- package/dist/cli/lib/{showTestResult.js → showTestFileResult.js} +15 -9
- package/dist/cli/lib/showTestFileResult.js.map +1 -0
- package/dist/cli/lib/showTestResultsSummary.d.ts +8 -0
- package/dist/cli/lib/showTestResultsSummary.js +213 -0
- package/dist/cli/lib/showTestResultsSummary.js.map +1 -0
- package/dist/cli/lib/timeProfiler.d.ts +3 -0
- package/dist/cli/lib/{timeProfier.js → timeProfiler.js} +1 -1
- package/dist/cli/lib/timeProfiler.js.map +1 -0
- package/dist/cli/lib/validateConfig.js +3 -0
- package/dist/cli/lib/validateConfig.js.map +1 -1
- package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.js +3 -3
- package/dist/cli/lib/watchFilesAndRunTestsNodeWatch.js.map +1 -1
- package/dist/cli/lib/watchFilesNodeWatch.js +3 -3
- package/dist/cli/lib/watchFilesNodeWatch.js.map +1 -1
- package/dist/cli/once.js +4 -2
- package/dist/cli/once.js.map +1 -1
- package/dist/cli/watch.d.ts +1 -1
- package/dist/cli/watch.js +8 -5
- package/dist/cli/watch.js.map +1 -1
- package/dist/packages/timeProfiler.d.ts +1 -1
- package/dist/packages/timeProfiler.js.map +1 -1
- package/dist/types.d.ts +1 -0
- package/dist/types.js.map +1 -1
- package/package.json +2 -3
- package/dist/cli/lib/showTestResult.d.ts +0 -4
- package/dist/cli/lib/showTestResult.js.map +0 -1
- package/dist/cli/lib/timeProfier.d.ts +0 -3
- package/dist/cli/lib/timeProfier.js.map +0 -1
package/dist/cli/lib/runTests.js
CHANGED
|
@@ -1,31 +1,16 @@
|
|
|
1
|
-
import { count } from 'sxy-lib/objects.js';
|
|
2
1
|
import { allObj as promiseAllObj } from 'sxy-lib/promises.js';
|
|
3
2
|
import { createTimeProfiler } from '../../packages/timeProfiler.js';
|
|
4
|
-
import figures from '../../packages/figures.js';
|
|
5
|
-
import chalk from '../../packages/chalk.js';
|
|
6
3
|
import { showTimeProfiling } from '../../config.js';
|
|
7
|
-
import { out as mainOut } from '../../output.js';
|
|
8
4
|
import { loadTestFile } from './loadTestFile.js';
|
|
9
5
|
import { runTest } from './runTest.js';
|
|
10
6
|
import { showTestLoadingError } from './showTestLoadingError.js';
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { failureEntries } from './failureEntries.js';
|
|
14
|
-
import { agentDone, agentFailure, agentRunStart } from './agentReport.js';
|
|
7
|
+
import { showTestFileResult } from './showTestFileResult.js';
|
|
8
|
+
import { agentRunStart } from './agentReport.js';
|
|
15
9
|
import { makeStopSignal, stopIfFailFast } from './stopSignal.js';
|
|
16
|
-
import { statusCodes, writeStatusFile } from './statusFile.js';
|
|
17
10
|
import { makeRunManagerState } from './makeWatchRunState.js';
|
|
11
|
+
import { showTestResultsSummary } from './showTestResultsSummary.js';
|
|
18
12
|
const { timeProfileAsync } = createTimeProfiler(showTimeProfiling);
|
|
19
|
-
|
|
20
|
-
function joinPlain(...parts) {
|
|
21
|
-
return parts.filter(part => part !== '').join(' ');
|
|
22
|
-
}
|
|
23
|
-
function plural(count, noun, verb) {
|
|
24
|
-
if (count < 1)
|
|
25
|
-
return '';
|
|
26
|
-
return `${count} ${noun}${count === 1 ? '' : 's'} ${verb}`;
|
|
27
|
-
}
|
|
28
|
-
function recordWithoutTests(state, testFile, testResult) {
|
|
13
|
+
function recordEntitiesWithoutTests(state, testFile, testResult) {
|
|
29
14
|
const describes = testResult.describeResults
|
|
30
15
|
.filter(describeResult => describeResult.success === null)
|
|
31
16
|
.map(describeResult => describeResult.thing);
|
|
@@ -48,7 +33,7 @@ refresh = 'refresh', customOut, filters = {}) {
|
|
|
48
33
|
}
|
|
49
34
|
const state = reRunManager?.state || makeRunManagerState();
|
|
50
35
|
const runStartTime = new Date().getTime();
|
|
51
|
-
const
|
|
36
|
+
const runNumber = agentRunStart(config, testFiles.size);
|
|
52
37
|
const stop = makeStopSignal();
|
|
53
38
|
//console.log('new runTests:', watchRunState?.activeRuns)
|
|
54
39
|
//console.log(inspect(testFiles))
|
|
@@ -74,7 +59,7 @@ refresh = 'refresh', customOut, filters = {}) {
|
|
|
74
59
|
else {
|
|
75
60
|
const testRunPromise = runTest(config, test, filters, stop);
|
|
76
61
|
testRunPromises[testFile] = testRunPromise;
|
|
77
|
-
testRunOutPromises[testFile] = testRunPromise.then(
|
|
62
|
+
testRunOutPromises[testFile] = testRunPromise.then(testResult => {
|
|
78
63
|
if (testResult.success === true || testResult.success === null) {
|
|
79
64
|
state.failedTestFiles.delete(testResult.file);
|
|
80
65
|
}
|
|
@@ -84,9 +69,9 @@ refresh = 'refresh', customOut, filters = {}) {
|
|
|
84
69
|
const executionFilterActive = filters.describe !== undefined || filters.it !== undefined;
|
|
85
70
|
// a filter makes files and describes look empty when they are not
|
|
86
71
|
if (!executionFilterActive)
|
|
87
|
-
|
|
72
|
+
recordEntitiesWithoutTests(state, testFile, testResult);
|
|
88
73
|
if (!executionFilterActive || testResult.describeResultsSummary.itsTotal > 0) {
|
|
89
|
-
|
|
74
|
+
showTestFileResult(config, testResult, customOut);
|
|
90
75
|
}
|
|
91
76
|
});
|
|
92
77
|
// wait for the test to complete before proceeding if we are in 'sequential' mode
|
|
@@ -102,171 +87,7 @@ refresh = 'refresh', customOut, filters = {}) {
|
|
|
102
87
|
// wait for the output to complete
|
|
103
88
|
await promiseAllObj(testRunOutPromises);
|
|
104
89
|
});
|
|
105
|
-
return
|
|
106
|
-
const out = customOut ?? mainOut;
|
|
107
|
-
const testsResultsSummary = {
|
|
108
|
-
total: 0,
|
|
109
|
-
passes: 0,
|
|
110
|
-
invalid: 0,
|
|
111
|
-
describesTotal: 0,
|
|
112
|
-
describesPasses: 0,
|
|
113
|
-
describesInvalid: 0,
|
|
114
|
-
itsTotal: 0,
|
|
115
|
-
itsPasses: 0
|
|
116
|
-
// itsInvalid: 0 // we don't check whether tests run any asserts (we don't control the assertion lib)
|
|
117
|
-
};
|
|
118
|
-
let describesThrownCount = 0;
|
|
119
|
-
for (const testFile in runTestResults) {
|
|
120
|
-
const runTestResult = runTestResults[testFile];
|
|
121
|
-
if (!runTestResult)
|
|
122
|
-
continue;
|
|
123
|
-
testsResultsSummary.total += +(runTestResult.success !== null);
|
|
124
|
-
testsResultsSummary.passes += +(runTestResult.success ?? false);
|
|
125
|
-
testsResultsSummary.invalid += +(runTestResult.success === null);
|
|
126
|
-
testsResultsSummary.describesTotal += runTestResult.describeResultsSummary.total;
|
|
127
|
-
testsResultsSummary.describesPasses += runTestResult.describeResultsSummary.passes;
|
|
128
|
-
testsResultsSummary.describesInvalid += runTestResult.describeResultsSummary.invalid;
|
|
129
|
-
testsResultsSummary.itsTotal += runTestResult.describeResultsSummary.itsTotal;
|
|
130
|
-
testsResultsSummary.itsPasses += runTestResult.describeResultsSummary.itsPasses;
|
|
131
|
-
describesThrownCount += runTestResult.describeResults
|
|
132
|
-
.filter(describeResult => describeResult.error !== undefined)
|
|
133
|
-
.length;
|
|
134
|
-
}
|
|
135
|
-
const failedToLoadCount = count(erroringTests);
|
|
136
|
-
testsResultsSummary.total += failedToLoadCount;
|
|
137
|
-
if ((filters.describe !== undefined || filters.it !== undefined)
|
|
138
|
-
&& testsResultsSummary.itsTotal === 0
|
|
139
|
-
&& failedToLoadCount === 0
|
|
140
|
-
&& describesThrownCount === 0) {
|
|
141
|
-
out(chalk.orange('No tests matched the describe/test filters.'));
|
|
142
|
-
const durationMs = new Date().getTime() - runStartTime;
|
|
143
|
-
writeStatusFile(config, statusCodes.couldNotRun, 'no tests matched the describe/test filters', [], durationMs);
|
|
144
|
-
agentDone(config, agentRun, statusCodes.couldNotRun, 'no tests matched the describe/test filters', testsResultsSummary, durationMs, state.failedTestFiles.size);
|
|
145
|
-
return null;
|
|
146
|
-
}
|
|
147
|
-
out(config.compact ? '' : '\n');
|
|
148
|
-
const allPassed = (testsResultsSummary.passes === testsResultsSummary.total
|
|
149
|
-
&& testsResultsSummary.describesPasses === testsResultsSummary.describesTotal
|
|
150
|
-
&& testsResultsSummary.itsPasses === testsResultsSummary.itsTotal);
|
|
151
|
-
if (allPassed) {
|
|
152
|
-
out(chalk.mediumgreen(`${figures.tick}`));
|
|
153
|
-
}
|
|
154
|
-
else {
|
|
155
|
-
out(chalk.mediumred(`${figures.cross}`));
|
|
156
|
-
}
|
|
157
|
-
// number of tests successful
|
|
158
|
-
const testsText = `Tests: ${testsResultsSummary.itsPasses}/${testsResultsSummary.itsTotal}`;
|
|
159
|
-
if (testsResultsSummary.itsPasses === testsResultsSummary.itsTotal) {
|
|
160
|
-
if (testsResultsSummary.itsTotal === 0) {
|
|
161
|
-
out(chalk.grey(`${testsText}`));
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
out(chalk.mediumgreen(`${testsText}`));
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
else {
|
|
168
|
-
out(chalk.mediumred(`${testsText}`));
|
|
169
|
-
}
|
|
170
|
-
// number of items successful
|
|
171
|
-
const describesText = `Items: ${testsResultsSummary.describesPasses}/${testsResultsSummary.describesTotal}`;
|
|
172
|
-
const invalidDescribesPlain = (testsResultsSummary.describesInvalid >= 1)
|
|
173
|
-
? (testsResultsSummary.describesInvalid === 1)
|
|
174
|
-
? '(+1 describe without tests)'
|
|
175
|
-
: `(+${testsResultsSummary.describesInvalid} describes without tests)`
|
|
176
|
-
: '';
|
|
177
|
-
const describesThrownPlain = (describesThrownCount >= 1)
|
|
178
|
-
? (describesThrownCount === 1)
|
|
179
|
-
? '(1 describe errored)'
|
|
180
|
-
: `(${describesThrownCount} describes errored)`
|
|
181
|
-
: '';
|
|
182
|
-
const describesDetailsText = [
|
|
183
|
-
chalk.mediumred(describesThrownPlain), chalk.grey(invalidDescribesPlain)
|
|
184
|
-
]
|
|
185
|
-
.filter(text => text !== '')
|
|
186
|
-
.join(' ');
|
|
187
|
-
const describesDetailsSuffix = describesDetailsText === '' ? '' : ` ${describesDetailsText}`;
|
|
188
|
-
if (testsResultsSummary.describesPasses === testsResultsSummary.describesTotal) {
|
|
189
|
-
if (testsResultsSummary.describesTotal === 0) {
|
|
190
|
-
out(chalk.grey(`${describesText}`) + describesDetailsSuffix);
|
|
191
|
-
}
|
|
192
|
-
else {
|
|
193
|
-
out(chalk.mediumgreen(`${describesText}`) + describesDetailsSuffix);
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
out(chalk.mediumred(`${describesText}`) + describesDetailsSuffix);
|
|
198
|
-
}
|
|
199
|
-
// number of test files successful
|
|
200
|
-
const testFilesText = `Test Files: ${testsResultsSummary.passes}/${testsResultsSummary.total}`;
|
|
201
|
-
const invalidTestFilesPlain = (testsResultsSummary.invalid >= 1)
|
|
202
|
-
? (testsResultsSummary.invalid === 1)
|
|
203
|
-
? '(+1 file without tests)'
|
|
204
|
-
: `(+${testsResultsSummary.invalid} files without tests)`
|
|
205
|
-
: '';
|
|
206
|
-
const failedToLoadPlain = (failedToLoadCount >= 1)
|
|
207
|
-
? (failedToLoadCount === 1)
|
|
208
|
-
? '(1 file failed to load, or errored)'
|
|
209
|
-
: `(${failedToLoadCount} files failed to load, or errored)`
|
|
210
|
-
: '';
|
|
211
|
-
const testFilesDetailsText = [
|
|
212
|
-
chalk.mediumred(failedToLoadPlain), chalk.grey(invalidTestFilesPlain)
|
|
213
|
-
]
|
|
214
|
-
.filter(text => text !== '')
|
|
215
|
-
.join(' ');
|
|
216
|
-
const testFilesDetailsSuffix = testFilesDetailsText === '' ? '' : ` ${testFilesDetailsText}`;
|
|
217
|
-
if (testsResultsSummary.passes === testsResultsSummary.total) {
|
|
218
|
-
if (testsResultsSummary.describesTotal === 0) {
|
|
219
|
-
out(chalk.grey(`${testFilesText}`) + testFilesDetailsSuffix);
|
|
220
|
-
}
|
|
221
|
-
else {
|
|
222
|
-
out(chalk.mediumgreen(`${testFilesText}`) + testFilesDetailsSuffix);
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
else {
|
|
226
|
-
out(chalk.mediumred(`${testFilesText}`) + testFilesDetailsSuffix);
|
|
227
|
-
}
|
|
228
|
-
// the tallies only cover what ran, so say the run was cut short - otherwise
|
|
229
|
-
// "Tests: 0/1" reads as a one test suite
|
|
230
|
-
const stoppedPlain = (stop.stopped)
|
|
231
|
-
? 'stopped at the first failure (failFast)'
|
|
232
|
-
: '';
|
|
233
|
-
if (stoppedPlain !== '')
|
|
234
|
-
out(chalk.orange(stoppedPlain));
|
|
235
|
-
const summaryLines = [
|
|
236
|
-
testsText,
|
|
237
|
-
joinPlain(describesText, describesThrownPlain, invalidDescribesPlain),
|
|
238
|
-
joinPlain(testFilesText, failedToLoadPlain, invalidTestFilesPlain),
|
|
239
|
-
...(stoppedPlain === '') ? [] : [stoppedPlain]
|
|
240
|
-
];
|
|
241
|
-
const durationMs = new Date().getTime() - runStartTime;
|
|
242
|
-
if (allPassed) {
|
|
243
|
-
writeStatusFile(config, statusCodes.passed, 'all tests passed', summaryLines, durationMs);
|
|
244
|
-
agentDone(config, agentRun, statusCodes.passed, 'all tests passed', testsResultsSummary, durationMs, state.failedTestFiles.size);
|
|
245
|
-
}
|
|
246
|
-
else {
|
|
247
|
-
const abortedFiles = Object.keys(erroringTests);
|
|
248
|
-
// a file that would not load, or a describe that threw, means the run died
|
|
249
|
-
// partway - a different problem from tests that ran and failed
|
|
250
|
-
const aborted = abortedFiles.length > 0 || describesThrownCount > 0;
|
|
251
|
-
const failedTestsCount = testsResultsSummary.itsTotal - testsResultsSummary.itsPasses;
|
|
252
|
-
const description = ([
|
|
253
|
-
plural(abortedFiles.length, 'test file', 'failed to load or errored'),
|
|
254
|
-
plural(describesThrownCount, 'describe', 'errored'),
|
|
255
|
-
plural(failedTestsCount, 'test', 'failed')
|
|
256
|
-
].filter(part => part !== '').join(', ') || 'test run failed')
|
|
257
|
-
+ ((stop.stopped) ? ', stopped at the first failure' : '');
|
|
258
|
-
const code = (aborted) ? statusCodes.aborted : statusCodes.failed;
|
|
259
|
-
const failures = failureEntries(Object.values(runTestResults), erroringTests);
|
|
260
|
-
writeStatusFile(config, code, description, [...summaryLines, ...failureLines(Object.values(runTestResults), erroringTests)], durationMs);
|
|
261
|
-
// failures first, so the done line is a complete end of run marker
|
|
262
|
-
for (const failure of failures)
|
|
263
|
-
agentFailure(config, agentRun, failure);
|
|
264
|
-
agentDone(config, agentRun, code, description, testsResultsSummary, durationMs, state.failedTestFiles.size);
|
|
265
|
-
}
|
|
266
|
-
// full success?
|
|
267
|
-
// true/false gets returned to the caller of runTests()
|
|
268
|
-
return allPassed;
|
|
269
|
-
});
|
|
90
|
+
return showTestResultsSummary(runTestResults, erroringTests, runStartTime, config, runNumber, state, stop, filters, customOut);
|
|
270
91
|
}
|
|
271
92
|
finally {
|
|
272
93
|
if (reRunManager !== undefined)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runTests.js","sourceRoot":"","sources":["../../../src/cli/lib/runTests.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { count } from 'sxy-lib/objects.js'\nimport { allObj as promiseAllObj } from 'sxy-lib/promises.js'\n\nimport type { FinalConfig, OutFn } from '../../types.js'\nimport type { TestExecutionFilters } from '../cliTypes.js'\nimport type { ReRunManager } from './reRunManager.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport figures from '../../packages/figures.js'\nimport chalk from '../../packages/chalk.js'\nimport { showTimeProfiling } from '../../config.js'\nimport { out as mainOut } from '../../output.js'\nimport { loadTestFile, type TestFile } from './loadTestFile.js'\nimport { runTest, type TestResult } from './runTest.js'\nimport { showTestLoadingError } from './showTestLoadingError.js'\nimport { showTestResult } from './showTestResult.js'\nimport { failureLines } from './failureLines.js'\nimport { failureEntries } from './failureEntries.js'\nimport { agentDone, agentFailure, agentRunStart } from './agentReport.js'\nimport { makeStopSignal, stopIfFailFast } from './stopSignal.js'\nimport { statusCodes, writeStatusFile } from './statusFile.js'\nimport { makeRunManagerState, type ReRunManageState } from './makeWatchRunState.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport interface TestsResultsSummary {\n total: number\n passes: number\n invalid: number\n describesTotal: number\n describesPasses: number\n describesInvalid: number\n itsTotal: number\n itsPasses: number\n}\n\nexport type RunTestsPromise = Promise<boolean | null>\n\n// the summary lines, minus the colouring, for the status file\nfunction joinPlain(...parts: string[]): string {\n return parts.filter(part => part !== '').join(' ')\n}\n\nfunction plural(count: number, noun: string, verb: string): string {\n if (count < 1) return ''\n return `${count} ${noun}${count === 1 ? '' : 's'} ${verb}`\n}\n\nexport type Concurrency = {\n limit: number\n}\n\nfunction recordWithoutTests(state: ReRunManageState, testFile: string, testResult: TestResult): void {\n const describes = testResult.describeResults\n .filter(describeResult => describeResult.success === null)\n .map(describeResult => describeResult.thing)\n const fileWithoutTests = testResult.success === null\n if (fileWithoutTests || describes.length > 0) {\n state.withoutTests.set(testFile, {\n file: testResult.sourceFile ?? testResult.file, fileWithoutTests, describes\n })\n } else {\n state.withoutTests.delete(testFile)\n }\n}\n\nexport async function runTests(\n config: FinalConfig,\n testFiles: Set<string>,\n reRunManager: ReRunManager | undefined,\n concurrency: Concurrency = { limit: -1 }, // eslint-disable-line @typescript-eslint/no-unused-vars\n // -- WIP\n refresh: 'refresh' | 'cached' = 'refresh',\n customOut?: OutFn,\n filters: TestExecutionFilters = {}\n): RunTestsPromise {\n if (reRunManager !== undefined) {\n reRunManager.state.lastTestFiles = new Set(testFiles)\n reRunManager.state.activeRuns++ // whatever, obsolete. Can use it to check on things\n }\n\n const state = reRunManager?.state || makeRunManagerState()\n const runStartTime = new Date().getTime()\n const agentRun = agentRunStart(config, testFiles.size)\n const stop = makeStopSignal()\n //console.log('new runTests:', watchRunState?.activeRuns)\n //console.log(inspect(testFiles))\n\n try {\n const testRunPromises: Record<string, Promise<TestResult>> = {}\n const erroringTests: Record<string, TestFile> = {}\n const testRunOutPromises: Record<string, Promise<void>> = {}\n\n await timeProfileAsync('run tests', async () => {\n if (Array.isArray(testFiles) ? testFiles.length > 0 : testFiles.size > 0) {\n for (const testFile of testFiles) {\n //console.log('testFiles', testFiles)\n //console.log('testFile', testFile)\n\n // an earlier file failed under failFast - leave the rest unloaded\n if (stop.stopped) break\n\n const test = await loadTestFile(config, testFile, refresh)\n\n if (test.error !== undefined && test.error !== false) {\n erroringTests[testFile] = test\n state.failedTestFiles.add(testFile)\n showTestLoadingError(config, test, customOut)\n stopIfFailFast(config, stop, true)\n } else {\n const testRunPromise = runTest(config, test, filters, stop)\n testRunPromises[testFile] = testRunPromise\n\n testRunOutPromises[testFile] = testRunPromise.then(async testResult => {\n if (testResult.success === true || testResult.success === null) {\n state.failedTestFiles.delete(testResult.file)\n } else {\n state.failedTestFiles.add(testFile)\n }\n const executionFilterActive = filters.describe !== undefined || filters.it !== undefined\n // a filter makes files and describes look empty when they are not\n if (!executionFilterActive) recordWithoutTests(state, testFile, testResult)\n if (!executionFilterActive || testResult.describeResultsSummary.itsTotal > 0) {\n await showTestResult(config, testResult, customOut)\n }\n })\n\n // wait for the test to complete before proceeding if we are in 'sequential' mode\n if (config.execution.files === 'sequential') await testRunOutPromises[testFile]\n }\n }\n }\n })\n\n let runTestResults: Record<string, TestResult> = {}\n\n await timeProfileAsync('wait for tests to finish', async () => {\n runTestResults = await promiseAllObj(testRunPromises)\n\n // wait for the output to complete\n await promiseAllObj(testRunOutPromises)\n })\n\n return await timeProfileAsync('show initial test run results', () => {\n \n const out = customOut ?? mainOut\n\n const testsResultsSummary: TestsResultsSummary = {\n total: 0,\n passes: 0,\n invalid: 0,\n describesTotal: 0,\n describesPasses: 0,\n describesInvalid: 0,\n itsTotal: 0,\n itsPasses: 0\n // itsInvalid: 0 // we don't check whether tests run any asserts (we don't control the assertion lib)\n }\n let describesThrownCount = 0\n\n for (const testFile in runTestResults) {\n const runTestResult = runTestResults[testFile]\n if (!runTestResult) continue\n\n testsResultsSummary.total += +(runTestResult.success !== null)\n testsResultsSummary.passes += +(runTestResult.success ?? false)\n testsResultsSummary.invalid += +(runTestResult.success === null)\n testsResultsSummary.describesTotal += runTestResult.describeResultsSummary.total\n testsResultsSummary.describesPasses += runTestResult.describeResultsSummary.passes\n testsResultsSummary.describesInvalid += runTestResult.describeResultsSummary.invalid\n testsResultsSummary.itsTotal += runTestResult.describeResultsSummary.itsTotal\n testsResultsSummary.itsPasses += runTestResult.describeResultsSummary.itsPasses\n describesThrownCount += runTestResult.describeResults\n .filter(describeResult => describeResult.error !== undefined)\n .length\n }\n\n const failedToLoadCount = count(erroringTests)\n testsResultsSummary.total += failedToLoadCount\n\n if (\n (filters.describe !== undefined || filters.it !== undefined)\n && testsResultsSummary.itsTotal === 0\n && failedToLoadCount === 0\n && describesThrownCount === 0\n ) {\n out(chalk.orange('No tests matched the describe/test filters.'))\n const durationMs = new Date().getTime() - runStartTime\n writeStatusFile(\n config,\n statusCodes.couldNotRun,\n 'no tests matched the describe/test filters',\n [],\n durationMs\n )\n agentDone(\n config, agentRun, statusCodes.couldNotRun,\n 'no tests matched the describe/test filters', testsResultsSummary, durationMs,\n state.failedTestFiles.size\n )\n return null\n }\n\n out(config.compact ? '' : '\\n')\n\n const allPassed = (\n testsResultsSummary.passes === testsResultsSummary.total\n && testsResultsSummary.describesPasses === testsResultsSummary.describesTotal\n && testsResultsSummary.itsPasses === testsResultsSummary.itsTotal\n )\n\n if (allPassed) {\n out(chalk.mediumgreen(`${figures.tick}`))\n } else {\n out(chalk.mediumred(`${figures.cross}`))\n }\n\n // number of tests successful\n const testsText = `Tests: ${testsResultsSummary.itsPasses}/${testsResultsSummary.itsTotal}`\n if (testsResultsSummary.itsPasses === testsResultsSummary.itsTotal) {\n if (testsResultsSummary.itsTotal === 0) {\n out(chalk.grey(`${testsText}`))\n } else {\n out(chalk.mediumgreen(`${testsText}`))\n }\n } else {\n out(chalk.mediumred(`${testsText}`))\n }\n\n // number of items successful\n const describesText = `Items: ${testsResultsSummary.describesPasses}/${testsResultsSummary.describesTotal}`\n const invalidDescribesPlain = (testsResultsSummary.describesInvalid >= 1)\n ? (testsResultsSummary.describesInvalid === 1)\n ? '(+1 describe without tests)'\n : `(+${testsResultsSummary.describesInvalid} describes without tests)`\n : ''\n const describesThrownPlain = (describesThrownCount >= 1)\n ? (describesThrownCount === 1)\n ? '(1 describe errored)'\n : `(${describesThrownCount} describes errored)`\n : ''\n const describesDetailsText = [\n chalk.mediumred(describesThrownPlain), chalk.grey(invalidDescribesPlain)\n ]\n .filter(text => text !== '')\n .join(' ')\n const describesDetailsSuffix = describesDetailsText === '' ? '' : ` ${describesDetailsText}`\n if (testsResultsSummary.describesPasses === testsResultsSummary.describesTotal) {\n if (testsResultsSummary.describesTotal === 0) {\n out(chalk.grey(`${describesText}`) + describesDetailsSuffix)\n } else {\n out(chalk.mediumgreen(`${describesText}`) + describesDetailsSuffix)\n }\n } else {\n out(chalk.mediumred(`${describesText}`) + describesDetailsSuffix)\n }\n\n // number of test files successful\n const testFilesText = `Test Files: ${testsResultsSummary.passes}/${testsResultsSummary.total}`\n const invalidTestFilesPlain = (testsResultsSummary.invalid >= 1)\n ? (testsResultsSummary.invalid === 1)\n ? '(+1 file without tests)'\n : `(+${testsResultsSummary.invalid} files without tests)`\n : ''\n const failedToLoadPlain = (failedToLoadCount >= 1)\n ? (failedToLoadCount === 1)\n ? '(1 file failed to load, or errored)'\n : `(${failedToLoadCount} files failed to load, or errored)`\n : ''\n const testFilesDetailsText = [\n chalk.mediumred(failedToLoadPlain), chalk.grey(invalidTestFilesPlain)\n ]\n .filter(text => text !== '')\n .join(' ')\n const testFilesDetailsSuffix = testFilesDetailsText === '' ? '' : ` ${testFilesDetailsText}`\n if (testsResultsSummary.passes === testsResultsSummary.total) {\n if (testsResultsSummary.describesTotal === 0) {\n out(chalk.grey(`${testFilesText}`) + testFilesDetailsSuffix)\n } else {\n out(chalk.mediumgreen(`${testFilesText}`) + testFilesDetailsSuffix)\n }\n } else {\n out(chalk.mediumred(`${testFilesText}`) + testFilesDetailsSuffix)\n }\n\n // the tallies only cover what ran, so say the run was cut short - otherwise\n // \"Tests: 0/1\" reads as a one test suite\n const stoppedPlain = (stop.stopped)\n ? 'stopped at the first failure (failFast)'\n : ''\n if (stoppedPlain !== '') out(chalk.orange(stoppedPlain))\n\n const summaryLines = [\n testsText,\n joinPlain(describesText, describesThrownPlain, invalidDescribesPlain),\n joinPlain(testFilesText, failedToLoadPlain, invalidTestFilesPlain),\n ...(stoppedPlain === '') ? [] : [stoppedPlain]\n ]\n\n const durationMs = new Date().getTime() - runStartTime\n\n if (allPassed) {\n writeStatusFile(\n config, statusCodes.passed, 'all tests passed', summaryLines, durationMs\n )\n agentDone(\n config, agentRun, statusCodes.passed, 'all tests passed',\n testsResultsSummary, durationMs, state.failedTestFiles.size\n )\n } else {\n const abortedFiles = Object.keys(erroringTests)\n\n // a file that would not load, or a describe that threw, means the run died\n // partway - a different problem from tests that ran and failed\n const aborted = abortedFiles.length > 0 || describesThrownCount > 0\n const failedTestsCount = testsResultsSummary.itsTotal - testsResultsSummary.itsPasses\n\n const description = ([\n plural(abortedFiles.length, 'test file', 'failed to load or errored'),\n plural(describesThrownCount, 'describe', 'errored'),\n plural(failedTestsCount, 'test', 'failed')\n ].filter(part => part !== '').join(', ') || 'test run failed')\n + ((stop.stopped) ? ', stopped at the first failure' : '')\n\n const code = (aborted) ? statusCodes.aborted : statusCodes.failed\n const failures = failureEntries(Object.values(runTestResults), erroringTests)\n\n writeStatusFile(\n config,\n code,\n description,\n [...summaryLines, ...failureLines(Object.values(runTestResults), erroringTests)],\n durationMs\n )\n\n // failures first, so the done line is a complete end of run marker\n for (const failure of failures) agentFailure(config, agentRun, failure)\n agentDone(\n config, agentRun, code, description, testsResultsSummary, durationMs,\n state.failedTestFiles.size\n )\n }\n\n // full success?\n // true/false gets returned to the caller of runTests()\n return allPassed\n })\n } finally {\n if (reRunManager !== undefined) reRunManager.state.activeRuns--\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"runTests.js","sourceRoot":"","sources":["../../../src/cli/lib/runTests.ts"],"names":[],"mappings":"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","sourcesContent":["\nimport { allObj as promiseAllObj } from 'sxy-lib/promises.js'\n\nimport type { FinalConfig, OutFn } from '../../types.js'\nimport type { TestExecutionFilters } from '../cliTypes.js'\nimport type { ReRunManager } from './reRunManager.js'\nimport { createTimeProfiler } from '../../packages/timeProfiler.js'\nimport { showTimeProfiling } from '../../config.js'\nimport { loadTestFile, type TestFile } from './loadTestFile.js'\nimport { runTest, type TestResult } from './runTest.js'\nimport { showTestLoadingError } from './showTestLoadingError.js'\nimport { showTestFileResult } from './showTestFileResult.js'\nimport { agentRunStart } from './agentReport.js'\nimport { makeStopSignal, stopIfFailFast } from './stopSignal.js'\nimport { makeRunManagerState, type ReRunManageState } from './makeWatchRunState.js'\nimport { showTestResultsSummary } from './showTestResultsSummary.js'\n\n\nconst { timeProfileAsync } = createTimeProfiler(showTimeProfiling)\n\nexport interface TestsResultsSummary {\n total: number\n passes: number\n invalid: number\n describesTotal: number\n describesPasses: number\n describesInvalid: number\n itsTotal: number\n itsPasses: number\n}\n\nexport type RunTestsPromise = Promise<boolean | null>\n\n\nexport type Concurrency = {\n limit: number\n}\n\nfunction recordEntitiesWithoutTests(state: ReRunManageState, testFile: string, testResult: TestResult): void {\n const describes = testResult.describeResults\n .filter(describeResult => describeResult.success === null)\n .map(describeResult => describeResult.thing)\n const fileWithoutTests = testResult.success === null\n if (fileWithoutTests || describes.length > 0) {\n state.withoutTests.set(testFile, {\n file: testResult.sourceFile ?? testResult.file, fileWithoutTests, describes\n })\n } else {\n state.withoutTests.delete(testFile)\n }\n}\n\nexport async function runTests(\n config: FinalConfig,\n testFiles: Set<string>,\n reRunManager: ReRunManager | undefined,\n concurrency: Concurrency = { limit: -1 }, // eslint-disable-line @typescript-eslint/no-unused-vars\n // -- WIP\n refresh: 'refresh' | 'cached' = 'refresh',\n customOut?: OutFn,\n filters: TestExecutionFilters = {}\n): RunTestsPromise {\n if (reRunManager !== undefined) {\n reRunManager.state.lastTestFiles = new Set(testFiles)\n reRunManager.state.activeRuns++ // whatever, obsolete. Can use it to check on things\n }\n\n const state = reRunManager?.state || makeRunManagerState()\n const runStartTime = new Date().getTime()\n const runNumber = agentRunStart(config, testFiles.size)\n const stop = makeStopSignal()\n //console.log('new runTests:', watchRunState?.activeRuns)\n //console.log(inspect(testFiles))\n\n try {\n const testRunPromises: Record<string, Promise<TestResult>> = {}\n const erroringTests: Record<string, TestFile> = {}\n const testRunOutPromises: Record<string, Promise<void>> = {}\n\n await timeProfileAsync('run tests', async () => {\n if (Array.isArray(testFiles) ? testFiles.length > 0 : testFiles.size > 0) {\n for (const testFile of testFiles) {\n //console.log('testFiles', testFiles)\n //console.log('testFile', testFile)\n\n // an earlier file failed under failFast - leave the rest unloaded\n if (stop.stopped) break\n\n const test = await loadTestFile(config, testFile, refresh)\n\n if (test.error !== undefined && test.error !== false) {\n erroringTests[testFile] = test\n state.failedTestFiles.add(testFile)\n showTestLoadingError(config, test, customOut)\n stopIfFailFast(config, stop, true)\n } else {\n const testRunPromise = runTest(config, test, filters, stop)\n testRunPromises[testFile] = testRunPromise\n\n testRunOutPromises[testFile] = testRunPromise.then(testResult => {\n if (testResult.success === true || testResult.success === null) {\n state.failedTestFiles.delete(testResult.file)\n } else {\n state.failedTestFiles.add(testFile)\n }\n const executionFilterActive = filters.describe !== undefined || filters.it !== undefined\n // a filter makes files and describes look empty when they are not\n if (!executionFilterActive) recordEntitiesWithoutTests(state, testFile, testResult)\n if (!executionFilterActive || testResult.describeResultsSummary.itsTotal > 0) {\n showTestFileResult(config, testResult, customOut)\n }\n })\n\n // wait for the test to complete before proceeding if we are in 'sequential' mode\n if (config.execution.files === 'sequential') await testRunOutPromises[testFile]\n }\n }\n }\n })\n\n let runTestResults: Record<string, TestResult> = {}\n\n await timeProfileAsync('wait for tests to finish', async () => {\n runTestResults = await promiseAllObj(testRunPromises)\n\n // wait for the output to complete\n await promiseAllObj(testRunOutPromises)\n })\n\n return showTestResultsSummary(\n runTestResults, erroringTests, runStartTime,\n config, runNumber, state, stop, filters, customOut\n )\n \n } finally {\n if (reRunManager !== undefined) reRunManager.state.activeRuns--\n }\n}\n"]}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
// import type { OutFn } from '../../types.js'
|
|
2
|
+
// import type { TestFile } from './loadTestFile.js'
|
|
3
|
+
// import type { TestResult } from './runTest.js'
|
|
4
|
+
// import chalk from '../../packages/chalk.js'
|
|
5
|
+
// import figures from '../../packages/figures.js'
|
|
6
|
+
// import { failureEntries } from './failureEntries.js'
|
|
7
|
+
export {};
|
|
8
|
+
// // The run's failures gathered in one place ahead of the tallies, one line per error. The full
|
|
9
|
+
// // diff, logs and trace stay in each file's own output above.
|
|
10
|
+
// export function showFailuresColorized(
|
|
11
|
+
// out: OutFn,
|
|
12
|
+
// testResults: TestResult[],
|
|
13
|
+
// erroringTests: Record<string, TestFile>
|
|
14
|
+
// ): void {
|
|
15
|
+
// const entries = failureEntries(testResults, erroringTests)
|
|
16
|
+
// if (entries.length === 0) return
|
|
17
|
+
// const displayNames = new Map<string, string>()
|
|
18
|
+
// for (const testResult of testResults) {
|
|
19
|
+
// displayNames.set(testResult.file, testResult.sourceFile ?? testResult.file)
|
|
20
|
+
// }
|
|
21
|
+
// for (const [file, test] of Object.entries(erroringTests)) {
|
|
22
|
+
// displayNames.set(file, test.sourceFile ?? file)
|
|
23
|
+
// }
|
|
24
|
+
// out(chalk.mediumred('Failures:'))
|
|
25
|
+
// let currentFile: string | undefined
|
|
26
|
+
// let currentDescribe: string | undefined
|
|
27
|
+
// // entries arrive in tree order, so a heading is needed only when its value changes
|
|
28
|
+
// for (const entry of entries) {
|
|
29
|
+
// if (entry.file !== currentFile) {
|
|
30
|
+
// out(chalk.grey(` ${displayNames.get(entry.file) ?? entry.file}`))
|
|
31
|
+
// currentFile = entry.file
|
|
32
|
+
// currentDescribe = undefined
|
|
33
|
+
// }
|
|
34
|
+
// if (entry.describe === undefined) {
|
|
35
|
+
// out(chalk.mediumred(` ${entry.error}`))
|
|
36
|
+
// continue
|
|
37
|
+
// }
|
|
38
|
+
// if (entry.describe !== currentDescribe) {
|
|
39
|
+
// const number = (entry.describeNumber === undefined) ? '' : `${entry.describeNumber}) `
|
|
40
|
+
// out(chalk.lightgrey(` ${number}`) + chalk.brightblue(entry.describe))
|
|
41
|
+
// currentDescribe = entry.describe
|
|
42
|
+
// }
|
|
43
|
+
// if (entry.test === undefined) {
|
|
44
|
+
// out(chalk.mediumred(` ${entry.error}`))
|
|
45
|
+
// } else {
|
|
46
|
+
// const letter = (entry.testLetter === undefined) ? '' : `${entry.testLetter}) `
|
|
47
|
+
// out(chalk.lightgrey(` ${letter}`) + chalk.mediumred(`${figures.cross} ${entry.test}`))
|
|
48
|
+
// out(chalk.mediumred(` ${entry.error}`))
|
|
49
|
+
// }
|
|
50
|
+
// }
|
|
51
|
+
// }
|
|
52
|
+
//# sourceMappingURL=showFailuresColorized.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"showFailuresColorized.js","sourceRoot":"","sources":["../../../src/cli/lib/showFailuresColorized.ts"],"names":[],"mappings":"AACA,8CAA8C;AAC9C,oDAAoD;AACpD,iDAAiD;AACjD,8CAA8C;AAC9C,kDAAkD;AAClD,uDAAuD;;AAGvD,iGAAiG;AACjG,gEAAgE;AAChE,yCAAyC;AACzC,kBAAkB;AAClB,iCAAiC;AACjC,8CAA8C;AAC9C,YAAY;AACZ,iEAAiE;AACjE,uCAAuC;AAEvC,qDAAqD;AACrD,8CAA8C;AAC9C,sFAAsF;AACtF,QAAQ;AACR,kEAAkE;AAClE,0DAA0D;AAC1D,QAAQ;AAER,wCAAwC;AAExC,0CAA0C;AAC1C,8CAA8C;AAE9C,0FAA0F;AAC1F,qCAAqC;AACrC,4CAA4C;AAC5C,iFAAiF;AACjF,uCAAuC;AACvC,0CAA0C;AAC1C,YAAY;AAEZ,8CAA8C;AAC9C,yDAAyD;AACzD,uBAAuB;AACvB,YAAY;AAEZ,oDAAoD;AACpD,qGAAqG;AACrG,uFAAuF;AACvF,+CAA+C;AAC/C,YAAY;AAEZ,0CAA0C;AAC1C,2DAA2D;AAC3D,mBAAmB;AACnB,6FAA6F;AAC7F,0GAA0G;AAC1G,6DAA6D;AAC7D,YAAY;AACZ,QAAQ;AACR,IAAI","sourcesContent":["\n// import type { OutFn } from '../../types.js'\n// import type { TestFile } from './loadTestFile.js'\n// import type { TestResult } from './runTest.js'\n// import chalk from '../../packages/chalk.js'\n// import figures from '../../packages/figures.js'\n// import { failureEntries } from './failureEntries.js'\n\n\n// // The run's failures gathered in one place ahead of the tallies, one line per error. The full\n// // diff, logs and trace stay in each file's own output above.\n// export function showFailuresColorized(\n// out: OutFn,\n// testResults: TestResult[],\n// erroringTests: Record<string, TestFile>\n// ): void {\n// const entries = failureEntries(testResults, erroringTests)\n// if (entries.length === 0) return\n\n// const displayNames = new Map<string, string>()\n// for (const testResult of testResults) {\n// displayNames.set(testResult.file, testResult.sourceFile ?? testResult.file)\n// }\n// for (const [file, test] of Object.entries(erroringTests)) {\n// displayNames.set(file, test.sourceFile ?? file)\n// }\n\n// out(chalk.mediumred('Failures:'))\n\n// let currentFile: string | undefined\n// let currentDescribe: string | undefined\n\n// // entries arrive in tree order, so a heading is needed only when its value changes\n// for (const entry of entries) {\n// if (entry.file !== currentFile) {\n// out(chalk.grey(` ${displayNames.get(entry.file) ?? entry.file}`))\n// currentFile = entry.file\n// currentDescribe = undefined\n// }\n\n// if (entry.describe === undefined) {\n// out(chalk.mediumred(` ${entry.error}`))\n// continue\n// }\n\n// if (entry.describe !== currentDescribe) {\n// const number = (entry.describeNumber === undefined) ? '' : `${entry.describeNumber}) `\n// out(chalk.lightgrey(` ${number}`) + chalk.brightblue(entry.describe))\n// currentDescribe = entry.describe\n// }\n\n// if (entry.test === undefined) {\n// out(chalk.mediumred(` ${entry.error}`))\n// } else {\n// const letter = (entry.testLetter === undefined) ? '' : `${entry.testLetter}) `\n// out(chalk.lightgrey(` ${letter}`) + chalk.mediumred(`${figures.cross} ${entry.test}`))\n// out(chalk.mediumred(` ${entry.error}`))\n// }\n// }\n// }\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { FinalConfig, OutFn } from '../../types.js';
|
|
2
|
+
import type { TestResult } from './runTest.js';
|
|
3
|
+
export interface ShowTestFileResultOptions {
|
|
4
|
+
failuresOnly?: boolean;
|
|
5
|
+
}
|
|
6
|
+
export declare function showTestFileResult(config: FinalConfig, testResult: TestResult, customOut?: OutFn, { failuresOnly }?: ShowTestFileResultOptions): void;
|
|
7
|
+
//# sourceMappingURL=showTestFileResult.d.ts.map
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import { inspect } from 'node:util';
|
|
2
2
|
import chalk from '../../packages/chalk.js';
|
|
3
3
|
import figures from '../../packages/figures.js';
|
|
4
|
-
import { createTimeProfiler } from '../../packages/timeProfiler.js';
|
|
5
|
-
import { showTimeProfiling } from '../../config.js';
|
|
6
4
|
import { out as mainOut } from '../../output.js';
|
|
7
5
|
import { indexNumberToLetters } from '../../indexNumberToLetters.js';
|
|
8
|
-
|
|
6
|
+
import { timeProfile } from './timeProfiler.js';
|
|
9
7
|
function IsErrorLike(v) {
|
|
10
8
|
return typeof v === 'object' && v !== null
|
|
11
9
|
&& 'name' in v && typeof v.name === 'string'
|
|
@@ -38,16 +36,20 @@ function showExpected(err, column) {
|
|
|
38
36
|
}
|
|
39
37
|
return showValue(err.expected, column);
|
|
40
38
|
}
|
|
39
|
+
function describeFailed(describeResult) {
|
|
40
|
+
return describeResult.error !== undefined
|
|
41
|
+
|| describeResult.itResults.some(itResult => itResult.success === false);
|
|
42
|
+
}
|
|
41
43
|
function display(u) {
|
|
42
44
|
if (typeof u === 'string')
|
|
43
45
|
return u;
|
|
44
46
|
return inspect(u);
|
|
45
47
|
}
|
|
46
|
-
export
|
|
48
|
+
export function showTestFileResult(config, testResult, customOut, { failuresOnly = false } = {}) {
|
|
47
49
|
const out = customOut ?? mainOut;
|
|
48
50
|
// compact keeps only the blank line that separates files
|
|
49
51
|
const gap = config.compact ? () => { } : () => { out(); };
|
|
50
|
-
|
|
52
|
+
timeProfile('show test result', () => {
|
|
51
53
|
out();
|
|
52
54
|
const fileTime = (testResult.time === undefined) ? '' : ` ${testResult.time.toLocaleString()}ms`
|
|
53
55
|
+ ((testResult.loadTime === undefined)
|
|
@@ -55,7 +57,7 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
55
57
|
: ` (${testResult.loadTime.toLocaleString()}ms module re-loading)`);
|
|
56
58
|
out(chalk.grey `File ${testResult.sourceFile ?? testResult.file}${fileTime}`);
|
|
57
59
|
const indent = ' ';
|
|
58
|
-
if (testResult.logs.length > 0) {
|
|
60
|
+
if (!failuresOnly && testResult.logs.length > 0) {
|
|
59
61
|
gap();
|
|
60
62
|
out(chalk.grey `console.logs:`);
|
|
61
63
|
testResult.logs.forEach(log => {
|
|
@@ -63,12 +65,14 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
63
65
|
});
|
|
64
66
|
gap();
|
|
65
67
|
}
|
|
66
|
-
if (testResult.describeResults.length === 0) {
|
|
68
|
+
if (!failuresOnly && testResult.describeResults.length === 0) {
|
|
67
69
|
out('No describes');
|
|
68
70
|
gap();
|
|
69
71
|
}
|
|
70
72
|
let first = true;
|
|
71
73
|
for (const describeResult of testResult.describeResults) {
|
|
74
|
+
if (failuresOnly && !describeFailed(describeResult))
|
|
75
|
+
continue;
|
|
72
76
|
if (!first)
|
|
73
77
|
gap();
|
|
74
78
|
first = false;
|
|
@@ -77,7 +81,7 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
77
81
|
if (describeResult.itResults.length === 0 && !('error' in describeResult))
|
|
78
82
|
out(`${indent}No tests`);
|
|
79
83
|
gap();
|
|
80
|
-
if (describeResult.logs && describeResult.logs.length > 0) {
|
|
84
|
+
if (!failuresOnly && describeResult.logs && describeResult.logs.length > 0) {
|
|
81
85
|
out(chalk.grey `console.logs:`);
|
|
82
86
|
describeResult.logs.forEach(log => {
|
|
83
87
|
out(...log);
|
|
@@ -100,6 +104,8 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
100
104
|
gap();
|
|
101
105
|
}
|
|
102
106
|
for (const itResult of describeResult.itResults) {
|
|
107
|
+
if (failuresOnly && itResult.success !== false)
|
|
108
|
+
continue;
|
|
103
109
|
const letters = indexNumberToLetters(itResult.counter) ?? '';
|
|
104
110
|
const itTime = chalk.grey ` ${itResult.time.toLocaleString()}ms`;
|
|
105
111
|
if (itResult.success === true) {
|
|
@@ -150,4 +156,4 @@ export async function showTestResult(config, testResult, customOut) {
|
|
|
150
156
|
}
|
|
151
157
|
});
|
|
152
158
|
}
|
|
153
|
-
//# sourceMappingURL=
|
|
159
|
+
//# sourceMappingURL=showTestFileResult.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"showTestFileResult.js","sourceRoot":"","sources":["../../../src/cli/lib/showTestFileResult.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAKnC,OAAO,KAAK,MAAM,yBAAyB,CAAA;AAC3C,OAAO,OAAO,MAAM,2BAA2B,CAAA;AAC/C,OAAO,EAAE,GAAG,IAAI,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAE,oBAAoB,EAAE,MAAM,+BAA+B,CAAA;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAmB/C,SAAS,WAAW,CAAC,CAAU;IAC3B,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI;WACnC,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ;WACzC,SAAS,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,OAAO,KAAK,QAAQ,CAAA;AAC1D,CAAC;AACD,SAAS,wBAAwB,CAAC,CAAY;IAC1C,OAAO,CAAC,QAAQ,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,CAAA;AAC7C,CAAC;AAGD,0FAA0F;AAC1F,iFAAiF;AACjF,SAAS,YAAY,CAAC,OAAe,EAAE,MAAc;IACjD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAC7B,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC;QACvC,CAAC,CAAC,CAAC,IAAI,CAAC;QACR,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,EAC7D,EAAE,CACL,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AAChB,CAAC;AAED,4FAA4F;AAC5F,wFAAwF;AACxF,4FAA4F;AAC5F,0CAA0C;AAC1C,SAAS,SAAS,CAAC,KAAc,EAAE,MAAc;IAC7C,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACrD,OAAO,OAAO,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAA;IACvC,CAAC;IACD,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,MAAM,EAAE,CAAC,CAAA;AAChD,CAAC;AAED,2GAA2G;AAC3G,SAAS,YAAY,CAAC,GAAkB,EAAE,MAAc;IACpD,IAAI,CAAC,CAAC,UAAU,IAAI,GAAG,CAAC,IAAI,qBAAqB,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,mBAAmB,KAAK,QAAQ,EAAE,CAAC;QACtG,OAAO,GAAG,CAAC,mBAAmB,CAAA;IAClC,CAAC;IACD,OAAO,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AAC1C,CAAC;AAED,SAAS,cAAc,CAAC,cAA8B;IAClD,OAAO,cAAc,CAAC,KAAK,KAAK,SAAS;WAClC,cAAc,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,KAAK,KAAK,CAAC,CAAA;AAChF,CAAC;AAED,SAAS,OAAO,CAAC,CAAU;IACvB,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAA;IACnC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAA;AACrB,CAAC;AAOD,MAAM,UAAU,kBAAkB,CAC9B,MAAmB,EACnB,UAAsB,EACtB,SAAiB,EACjB,EAAE,YAAY,GAAG,KAAK,KAAgC,EAAE;IAExD,MAAM,GAAG,GAAG,SAAS,IAAI,OAAO,CAAA;IAChC,yDAAyD;IACzD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,GAAG,EAAE,CAAA,CAAC,CAAC,CAAA;IAEvD,WAAW,CAAC,kBAAkB,EAAE,GAAG,EAAE;QACjC,GAAG,EAAE,CAAA;QACL,MAAM,QAAQ,GAAG,CAAC,UAAU,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI;cAC3F,CAAC,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS,CAAC;gBAClC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,KAAK,UAAU,CAAC,QAAQ,CAAC,cAAc,EAAE,uBAAuB,CAAC,CAAA;QAC3E,GAAG,CAAC,KAAK,CAAC,IAAI,CAAA,QAAQ,UAAU,CAAC,UAAU,IAAI,UAAU,CAAC,IAAI,GAAG,QAAQ,EAAE,CAAC,CAAA;QAE5E,MAAM,MAAM,GAAG,MAAM,CAAA;QAErB,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9C,GAAG,EAAE,CAAA;YACL,GAAG,CAAC,KAAK,CAAC,IAAI,CAAA,eAAe,CAAC,CAAA;YAC9B,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC1B,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;YACf,CAAC,CAAC,CAAA;YACF,GAAG,EAAE,CAAA;QACT,CAAC;QAED,IAAI,CAAC,YAAY,IAAI,UAAU,CAAC,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3D,GAAG,CAAC,cAAc,CAAC,CAAA;YACnB,GAAG,EAAE,CAAA;QACT,CAAC;QAED,IAAI,KAAK,GAAG,IAAI,CAAA;QAEhB,KAAK,MAAM,cAAc,IAAI,UAAU,CAAC,eAAe,EAAE,CAAC;YACtD,IAAI,YAAY,IAAI,CAAC,cAAc,CAAC,cAAc,CAAC;gBAAE,SAAQ;YAE7D,IAAI,CAAC,KAAK;gBAAE,GAAG,EAAE,CAAA;YACjB,KAAK,GAAG,KAAK,CAAA;YAEb,GAAG,CAAC,KAAK,CAAC,SAAS,CAAA,GAAG,cAAc,CAAC,OAAO,eAAe,GAAG,KAAK,CAAC,UAAU,CAAC,cAAc,CAAC,KAAK,CAAC;kBAC9F,KAAK,CAAC,IAAI,CAAA,KAAK,cAAc,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,CAAA;YAC9D,IAAI,cAAc,CAAC,SAAS,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,cAAc,CAAC;gBAAE,GAAG,CAAC,GAAG,MAAM,UAAU,CAAC,CAAA;YACnG,GAAG,EAAE,CAAA;YAEL,IAAI,CAAC,YAAY,IAAI,cAAc,CAAC,IAAI,IAAI,cAAc,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzE,GAAG,CAAC,KAAK,CAAC,IAAI,CAAA,eAAe,CAAC,CAAA;gBAC9B,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;oBAC9B,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;gBACf,CAAC,CAAC,CAAA;gBACF,GAAG,EAAE,CAAA;YACT,CAAC;YAED,IAAI,OAAO,IAAI,cAAc,EAAE,CAAC;gBAC5B,MAAM,aAAa,GAAG,cAAc,CAAC,KAAK,CAAA;gBAE1C,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAA;gBACvC,IAAI,WAAW,CAAC,aAAa,CAAC,EAAE,CAAC;oBAC7B,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,aAAa,CAAC,IAAI,KAAK,aAAa,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;oBAChF,IAAI,MAAM,CAAC,cAAc,IAAI,OAAO,IAAI,aAAa,EAAE,CAAC;wBACpD,GAAG,EAAE,CAAA;wBACL,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;oBACjD,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAA;gBAC9D,CAAC;gBACD,GAAG,EAAE,CAAA;YACT,CAAC;YAED,KAAK,MAAM,QAAQ,IAAI,cAAc,CAAC,SAAS,EAAE,CAAC;gBAC9C,IAAI,YAAY,IAAI,QAAQ,CAAC,OAAO,KAAK,KAAK;oBAAE,SAAQ;gBAExD,MAAM,OAAO,GAAG,oBAAoB,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,CAAA;gBAC5D,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,CAAA,KAAK,QAAQ,CAAC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAA;gBAChE,IAAI,QAAQ,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;oBAC5B,GAAG,CAAC,KAAK,CAAC,SAAS,CAAA,GAAG,MAAM,GAAG,OAAO,GAAG;0BACnC,KAAK,CAAC,WAAW,CAAA,KAAK,OAAO,CAAC,IAAI,KAAK,QAAQ,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAA;gBAC5E,CAAC;qBAAM,CAAC;oBACJ,GAAG,CAAC,KAAK,CAAC,SAAS,CAAA,GAAG,MAAM,GAAG,OAAO,GAAG;0BACnC,KAAK,CAAC,SAAS,CAAA,KAAK,OAAO,CAAC,KAAK,KAAK,QAAQ,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAA;oBACvE,GAAG,EAAE,CAAA;oBACL,MAAM,MAAM,GAAG,GAAG,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAA;oBAC1D,IAAI,OAAO,IAAI,QAAQ,EAAE,CAAC;wBACtB,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAA;wBAC1B,IAAI,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC;4BACnB,IAAI,wBAAwB,CAAC,GAAG,CAAC,EAAE,CAAC;gCAChC,GAAG,CAAC,KAAK,CAAC,SAAS;gCACf,mEAAmE;gCACnE,GAAG,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAC/D,CAAC,CAAA;gCACF,8DAA8D;gCAC9D,sDAAsD;gCACtD,MAAM,WAAW,GAAG,GAAG,MAAM,YAAY,CAAA;gCACzC,GAAG,CACC,KAAK,CAAC,MAAM,CAAA,GAAG,MAAM,aAAa,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,IAAI;sCACtE,KAAK,CAAC,UAAU,CAAA,GAAG,MAAM,aAAa,YAAY,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAC3E,CAAA;4BACL,CAAC;iCAAM,CAAC;gCACJ,GAAG,CAAC,KAAK,CAAC,SAAS,CACf,GAAG,MAAM,GAAG,GAAG,CAAC,IAAI,KAAK,YAAY,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,EAAE,CAC/D,CAAC,CAAA;4BACN,CAAC;4BACD,cAAc;4BACd,IAAI,MAAM,CAAC,cAAc,IAAI,OAAO,IAAI,GAAG,EAAE,CAAC;gCAC1C,GAAG,EAAE,CAAA;gCACL,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;4BACvC,CAAC;wBACL,CAAC;6BAAM,CAAC;4BACJ,GAAG,CAAC,KAAK,CAAC,SAAS,CACf,GAAG,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAC7B,CAAC,CAAA;wBACN,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,GAAG,EAAE,CAAA;gBACL,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;oBAC3B,GAAG,CAAC,KAAK,CAAC,IAAI,CAAA,eAAe,CAAC,CAAA;oBAC9B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;wBACxB,GAAG,CAAC,GAAG,GAAG,CAAC,CAAA;oBACf,CAAC,CAAC,CAAA;oBACF,GAAG,EAAE,CAAA;gBACT,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC,CAAC,CAAA;AACN,CAAC","sourcesContent":["\nimport type { Expand } from 'sxy-lib/types/Expand.js'\nimport { inspect } from 'node:util'\n\nimport type { FinalConfig, OutFn } from '../../types.js'\nimport type { DescribeResult } from './runDescribe.js'\nimport type { TestResult } from './runTest.js'\nimport chalk from '../../packages/chalk.js'\nimport figures from '../../packages/figures.js'\nimport { out as mainOut } from '../../output.js'\nimport { indexNumberToLetters } from '../../indexNumberToLetters.js'\nimport { timeProfile } from './timeProfiler.js'\n\n\n// Assertion failures are recognised by shape, not by where they came from. Importing an\n// assertion library to test `instanceof` against cannot work here: the runner would need it\n// as a dependency, and the copy a test file throws from is a separate ESM instance anyway,\n// so the check fails for the very errors it is meant to catch.\n\n\ninterface ErrorLike {\n name: string\n message: string\n stack?: unknown\n cause?: unknown\n}\ninterface AssertionLike extends ErrorLike {\n actual?: unknown\n expected?: unknown\n}\nfunction IsErrorLike(v: unknown): v is Expand<ErrorLike> {\n return typeof v === 'object' && v !== null\n && 'name' in v && typeof v.name === 'string'\n && 'message' in v && typeof v.message === 'string'\n}\nfunction ErrorLikeIsAssertionLike(v: ErrorLike): v is Expand<AssertionLike> {\n return ('actual' in v || 'expected' in v)\n}\n\n\n// Node's assertion messages run to several lines. Later lines are indented to the message\n// column and blank ones dropped; a single line message passes through untouched.\nfunction alignMessage(message: string, spacer: string): string {\n return message.split('\\n').reduce<string[]>(\n (previous, line) => (previous.length === 0)\n ? [line]\n : (line.trim()) ? [...previous, spacer + line] : previous,\n []\n ).join('\\n')\n}\n\n// A multi line string is shown as text, indented under its label. inspect() would render it\n// as one quoted chunk per line joined with `+`, which buries the content it is there to\n// show. Everything else - objects, and single line strings, whose quotes reveal padding and\n// emptiness - still goes through inspect.\nfunction showValue(value: unknown, column: string): string {\n if (typeof value !== 'string' || !value.includes('\\n')) {\n return inspect(value, { depth: 5 })\n }\n return value.split('\\n').join(`\\n${column}`)\n}\n\n// sxy-assert describes an expected that is no single value (not null, instanceof) rather than carrying one\nfunction showExpected(err: AssertionLike, column: string): string {\n if (!('expected' in err) && 'expectedDescription' in err && typeof err.expectedDescription === 'string') {\n return err.expectedDescription\n }\n return showValue(err.expected, column)\n}\n\nfunction describeFailed(describeResult: DescribeResult): boolean {\n return describeResult.error !== undefined\n || describeResult.itResults.some(itResult => itResult.success === false)\n}\n\nfunction display(u: unknown): string {\n if (typeof u === 'string') return u\n return inspect(u)\n}\n\nexport interface ShowTestFileResultOptions {\n // for the summary: only what failed, and only the failing tests' own logs\n failuresOnly?: boolean\n}\n\nexport function showTestFileResult(\n config: FinalConfig,\n testResult: TestResult,\n customOut?: OutFn,\n { failuresOnly = false }: ShowTestFileResultOptions = {}\n): void {\n const out = customOut ?? mainOut\n // compact keeps only the blank line that separates files\n const gap = config.compact ? () => {} : () => { out() }\n\n timeProfile('show test result', () => {\n out()\n const fileTime = (testResult.time === undefined) ? '' : ` ${testResult.time.toLocaleString()}ms`\n + ((testResult.loadTime === undefined)\n ? ''\n : ` (${testResult.loadTime.toLocaleString()}ms module re-loading)`)\n out(chalk.grey`File ${testResult.sourceFile ?? testResult.file}${fileTime}`)\n\n const indent = ' '\n\n if (!failuresOnly && testResult.logs.length > 0) {\n gap()\n out(chalk.grey`console.logs:`)\n testResult.logs.forEach(log => {\n out(...log)\n })\n gap()\n }\n\n if (!failuresOnly && testResult.describeResults.length === 0) {\n out('No describes')\n gap()\n }\n\n let first = true\n\n for (const describeResult of testResult.describeResults) {\n if (failuresOnly && !describeFailed(describeResult)) continue\n\n if (!first) gap()\n first = false\n\n out(chalk.lightgrey`${describeResult.counter}) describing ` + chalk.brightblue(describeResult.thing)\n + chalk.grey` ${describeResult.time.toLocaleString()}ms`)\n if (describeResult.itResults.length === 0 && !('error' in describeResult)) out(`${indent}No tests`)\n gap()\n\n if (!failuresOnly && describeResult.logs && describeResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n describeResult.logs.forEach(log => {\n out(...log)\n })\n gap()\n }\n\n if ('error' in describeResult) {\n const describeError = describeResult.error\n\n out(chalk.mediumred(`${indent}Threw:`))\n if (IsErrorLike(describeError)) {\n out(chalk.mediumred(`${indent}${describeError.name}: ${describeError.message}`))\n if (config.showErrorTrace && 'stack' in describeError) {\n gap()\n out(chalk.grey(display(describeError.stack)))\n }\n } else {\n out(chalk.mediumred(`${indent}${display(describeError)}`))\n }\n gap()\n }\n\n for (const itResult of describeResult.itResults) {\n if (failuresOnly && itResult.success !== false) continue\n\n const letters = indexNumberToLetters(itResult.counter) ?? ''\n const itTime = chalk.grey` ${itResult.time.toLocaleString()}ms`\n if (itResult.success === true) {\n out(chalk.lightgrey`${indent}${letters})`\n + chalk.mediumgreen` ${figures.tick} ${itResult.should}` + itTime)\n } else {\n out(chalk.lightgrey`${indent}${letters})`\n + chalk.mediumred` ${figures.cross} ${itResult.should}` + itTime)\n gap()\n const spacer = `${indent}${' '.repeat(letters.length)} `\n if ('error' in itResult) {\n const err = itResult.error\n if (IsErrorLike(err)) {\n if (ErrorLikeIsAssertionLike(err)) {\n out(chalk.mediumred(\n //`${spacer}Assertion Failed: ${alignMessage(err.message, spacer)}`\n `${spacer}${err.name}: ${alignMessage(err.message, spacer)}`\n ))\n // shown whenever the error carries them, so a falsy actual or\n // expected - 0, '', false, null - still gets its diff\n const valueColumn = `${spacer} `\n out(\n chalk.yellow`${spacer}Actual ${showValue(err.actual, valueColumn)}\\n`\n + chalk.brightblue`${spacer}Expected ${showExpected(err, valueColumn)}`\n )\n } else {\n out(chalk.mediumred(\n `${spacer}${err.name}: ${alignMessage(err.message, spacer)}`\n ))\n }\n // stack trace\n if (config.showErrorTrace && 'stack' in err) {\n gap()\n out(chalk.grey(display(err.stack)))\n }\n } else {\n out(chalk.mediumred(\n `${spacer}${display(err)}`\n ))\n }\n }\n }\n\n gap()\n if (itResult.logs.length > 0) {\n out(chalk.grey`console.logs:`)\n itResult.logs.forEach(log => {\n out(...log)\n })\n gap()\n }\n }\n }\n })\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { FinalConfig, OutFn } from '../../types.js';
|
|
2
|
+
import type { TestExecutionFilters } from '../cliTypes.js';
|
|
3
|
+
import type { TestFile } from './loadTestFile.js';
|
|
4
|
+
import type { ReRunManageState } from './makeWatchRunState.js';
|
|
5
|
+
import type { TestResult } from './runTest.js';
|
|
6
|
+
import type { StopSignal } from './stopSignal.js';
|
|
7
|
+
export declare function showTestResultsSummary(runTestResults: Record<string, TestResult>, erroringTests: Record<string, TestFile>, runStartTime: number, config: FinalConfig, runNumber: number, state: ReRunManageState, stop: StopSignal, filters: TestExecutionFilters, customOut?: OutFn): boolean | null;
|
|
8
|
+
//# sourceMappingURL=showTestResultsSummary.d.ts.map
|