@quenty/cli-output-helpers 1.17.2 → 1.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +4 -0
- package/dist/outputHelper.d.ts +11 -0
- package/dist/outputHelper.d.ts.map +1 -1
- package/dist/outputHelper.js +18 -0
- package/dist/outputHelper.js.map +1 -1
- package/dist/reporting/aggregated-batch-reporter.d.ts +31 -0
- package/dist/reporting/aggregated-batch-reporter.d.ts.map +1 -0
- package/dist/reporting/aggregated-batch-reporter.js +40 -0
- package/dist/reporting/aggregated-batch-reporter.js.map +1 -0
- package/dist/reporting/github/formatting.d.ts.map +1 -1
- package/dist/reporting/github/formatting.js +37 -32
- package/dist/reporting/github/formatting.js.map +1 -1
- package/dist/reporting/grouped-reporter.d.ts.map +1 -1
- package/dist/reporting/grouped-reporter.js +7 -28
- package/dist/reporting/grouped-reporter.js.map +1 -1
- package/dist/reporting/index.d.ts +2 -0
- package/dist/reporting/index.d.ts.map +1 -1
- package/dist/reporting/index.js +2 -0
- package/dist/reporting/index.js.map +1 -1
- package/dist/reporting/reporter.d.ts +17 -0
- package/dist/reporting/reporter.d.ts.map +1 -1
- package/dist/reporting/reporter.js.map +1 -1
- package/dist/reporting/result-status.d.ts +101 -0
- package/dist/reporting/result-status.d.ts.map +1 -0
- package/dist/reporting/result-status.js +138 -0
- package/dist/reporting/result-status.js.map +1 -0
- package/dist/reporting/result-status.test.d.ts +2 -0
- package/dist/reporting/result-status.test.d.ts.map +1 -0
- package/dist/reporting/result-status.test.js +108 -0
- package/dist/reporting/result-status.test.js.map +1 -0
- package/dist/reporting/spinner-reporter.d.ts +1 -0
- package/dist/reporting/spinner-reporter.d.ts.map +1 -1
- package/dist/reporting/spinner-reporter.js +18 -33
- package/dist/reporting/spinner-reporter.js.map +1 -1
- package/dist/reporting/summary-table-reporter.d.ts +7 -2
- package/dist/reporting/summary-table-reporter.d.ts.map +1 -1
- package/dist/reporting/summary-table-reporter.js +16 -27
- package/dist/reporting/summary-table-reporter.js.map +1 -1
- package/package.json +2 -2
- package/src/outputHelper.ts +22 -0
- package/src/reporting/aggregated-batch-reporter.ts +45 -0
- package/src/reporting/github/formatting.ts +52 -41
- package/src/reporting/grouped-reporter.ts +20 -42
- package/src/reporting/index.ts +13 -0
- package/src/reporting/reporter.ts +18 -0
- package/src/reporting/result-status.test.ts +149 -0
- package/src/reporting/result-status.ts +227 -0
- package/src/reporting/spinner-reporter.ts +40 -39
- package/src/reporting/summary-table-reporter.ts +29 -36
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One answer to "how did this turn out", for every place that has to say so.
|
|
3
|
+
*
|
|
4
|
+
* A result's state was worked out independently in four places — the summary
|
|
5
|
+
* table, the grouped reporter, the spinner and the PR comment — and each had its
|
|
6
|
+
* own idea of it. "Ran zero tests" was a warning in three of them and invisible
|
|
7
|
+
* in the fourth; the icon was `⚠` in two and `⚠️` in the others; a pass showed
|
|
8
|
+
* its counts in some and not others; and the run-level tallies at the bottom of
|
|
9
|
+
* each were counted separately, so they could disagree with the rows above them.
|
|
10
|
+
*
|
|
11
|
+
* Adding a fifth state made that untenable: a pass whose log output was dropped
|
|
12
|
+
* is still a pass, but not one that should look like every other green row, and
|
|
13
|
+
* teaching five renderers about it one at a time is how the four drifted in the
|
|
14
|
+
* first place.
|
|
15
|
+
*
|
|
16
|
+
* So state is resolved once, here, and the renderers only choose how to draw it.
|
|
17
|
+
*/
|
|
18
|
+
import { type JobPhase, type ProgressSummary, type ResultCaveat } from './reporter.js';
|
|
19
|
+
/** How a result should read at a glance. */
|
|
20
|
+
export type ResultSeverity = 'success' | 'warning' | 'failure';
|
|
21
|
+
export { type ResultCaveat } from './reporter.js';
|
|
22
|
+
/**
|
|
23
|
+
* The parts of a result that decide its state.
|
|
24
|
+
*
|
|
25
|
+
* Structural rather than `PackageResult` so a caller holding some other shape —
|
|
26
|
+
* the batch log parser's per-package result, say — can resolve state without
|
|
27
|
+
* first building a reporting type it has no other use for.
|
|
28
|
+
*/
|
|
29
|
+
export interface ResultStatusInput {
|
|
30
|
+
success: boolean;
|
|
31
|
+
progressSummary?: ProgressSummary;
|
|
32
|
+
failedPhase?: JobPhase;
|
|
33
|
+
/** Per-result override of the reporter's default failure label. */
|
|
34
|
+
failureLabel?: string;
|
|
35
|
+
/**
|
|
36
|
+
* Caveats the producer knows about and the resolver cannot see. `empty-run`
|
|
37
|
+
* and `no-counts` are derived from the counts themselves and need not be
|
|
38
|
+
* passed; `logs-lost` is a fact about the run that only its parser knows.
|
|
39
|
+
*/
|
|
40
|
+
caveats?: ResultCaveat[];
|
|
41
|
+
}
|
|
42
|
+
export interface ResolveResultStatusOptions {
|
|
43
|
+
/** Verdict word for a pass. Default "Passed". */
|
|
44
|
+
successLabel?: string;
|
|
45
|
+
/** Verdict word for a failure. Default "FAILED". */
|
|
46
|
+
failureLabel?: string;
|
|
47
|
+
/**
|
|
48
|
+
* True when this kind of run should have reported test counts, which makes
|
|
49
|
+
* their absence a caveat rather than simply nothing to show.
|
|
50
|
+
*/
|
|
51
|
+
expectsTestCounts?: boolean;
|
|
52
|
+
}
|
|
53
|
+
export interface ResultStatus {
|
|
54
|
+
severity: ResultSeverity;
|
|
55
|
+
/** The verdict word alone: "Passed", "FAILED", "Unverified". */
|
|
56
|
+
label: string;
|
|
57
|
+
/** Where it failed, when the failure names a phase. */
|
|
58
|
+
failedPhase?: JobPhase;
|
|
59
|
+
/** Counts or bytes as "(68/68)", or empty when there are none. */
|
|
60
|
+
progress: string;
|
|
61
|
+
/** Everything qualifying this result, in the order they are worth reading. */
|
|
62
|
+
caveats: ResultCaveat[];
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Work out how a result should be presented.
|
|
66
|
+
*
|
|
67
|
+
* A failure stays a failure whatever its caveats; a pass carrying any caveat
|
|
68
|
+
* becomes a warning. Caveats are not exclusive — a run can report no counts and
|
|
69
|
+
* have lost its logs — so they are collected rather than ranked, and every
|
|
70
|
+
* renderer shows all of them.
|
|
71
|
+
*/
|
|
72
|
+
export declare function resolveResultStatus(result: ResultStatusInput, options?: ResolveResultStatusOptions): ResultStatus;
|
|
73
|
+
/**
|
|
74
|
+
* The status as one line of plain text: "Passed (35/35) - logs lost".
|
|
75
|
+
*
|
|
76
|
+
* No icon, no duration and no color — those differ between a markdown table, a
|
|
77
|
+
* terminal line and a collapsible group header, and are the renderer's to add.
|
|
78
|
+
*/
|
|
79
|
+
export declare function formatStatusText(status: ResultStatus): string;
|
|
80
|
+
/**
|
|
81
|
+
* The icon for a severity.
|
|
82
|
+
*
|
|
83
|
+
* `emoji` for markdown, where they render as intended; `ascii` for a terminal
|
|
84
|
+
* line, where a variation-selector emoji is two columns wide and breaks column
|
|
85
|
+
* alignment.
|
|
86
|
+
*/
|
|
87
|
+
export declare function statusIcon(severity: ResultSeverity, style: 'emoji' | 'ascii'): string;
|
|
88
|
+
/** Color text by severity, using the shared palette. */
|
|
89
|
+
export declare function colorStatus(text: string, severity: ResultSeverity): string;
|
|
90
|
+
/**
|
|
91
|
+
* Roll up the caveats across a run, for the lines under a summary.
|
|
92
|
+
*
|
|
93
|
+
* Counted off the same statuses the rows were drawn from, so the tally and the
|
|
94
|
+
* rows cannot disagree — which they could when each reporter counted its own.
|
|
95
|
+
*/
|
|
96
|
+
export declare function tallyCaveats(statuses: ResultStatus[]): Array<{
|
|
97
|
+
caveat: ResultCaveat;
|
|
98
|
+
count: number;
|
|
99
|
+
message: string;
|
|
100
|
+
}>;
|
|
101
|
+
//# sourceMappingURL=result-status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-status.d.ts","sourceRoot":"","sources":["../../src/reporting/result-status.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,eAAe,EACpB,KAAK,YAAY,EAClB,MAAM,eAAe,CAAC;AAGvB,4CAA4C;AAC5C,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE/D,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AA0BlD;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,0BAA0B;IACzC,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,cAAc,CAAC;IACzB,gEAAgE;IAChE,KAAK,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,QAAQ,CAAC;IACvB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,8EAA8E;IAC9E,OAAO,EAAE,YAAY,EAAE,CAAC;CACzB;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,iBAAiB,EACzB,OAAO,GAAE,0BAA+B,GACvC,YAAY,CAuCd;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CAY7D;AAED;;;;;;GAMG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,cAAc,EACxB,KAAK,EAAE,OAAO,GAAG,OAAO,GACvB,MAAM,CAMR;AAED,wDAAwD;AACxD,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,MAAM,CAS1E;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,YAAY,EAAE,GACvB,KAAK,CAAC;IAAE,MAAM,EAAE,YAAY,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAgBjE"}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One answer to "how did this turn out", for every place that has to say so.
|
|
3
|
+
*
|
|
4
|
+
* A result's state was worked out independently in four places — the summary
|
|
5
|
+
* table, the grouped reporter, the spinner and the PR comment — and each had its
|
|
6
|
+
* own idea of it. "Ran zero tests" was a warning in three of them and invisible
|
|
7
|
+
* in the fourth; the icon was `⚠` in two and `⚠️` in the others; a pass showed
|
|
8
|
+
* its counts in some and not others; and the run-level tallies at the bottom of
|
|
9
|
+
* each were counted separately, so they could disagree with the rows above them.
|
|
10
|
+
*
|
|
11
|
+
* Adding a fifth state made that untenable: a pass whose log output was dropped
|
|
12
|
+
* is still a pass, but not one that should look like every other green row, and
|
|
13
|
+
* teaching five renderers about it one at a time is how the four drifted in the
|
|
14
|
+
* first place.
|
|
15
|
+
*
|
|
16
|
+
* So state is resolved once, here, and the renderers only choose how to draw it.
|
|
17
|
+
*/
|
|
18
|
+
import { OutputHelper } from '../outputHelper.js';
|
|
19
|
+
import { formatProgressResult, isEmptyTestRun } from './progress-format.js';
|
|
20
|
+
const CAVEAT_COPY = {
|
|
21
|
+
'no-counts': {
|
|
22
|
+
label: 'no test counts reported',
|
|
23
|
+
tally: (count) => `${count} package(s) reported no test counts — a pass here proves nothing about whether tests ran`,
|
|
24
|
+
},
|
|
25
|
+
'logs-lost': {
|
|
26
|
+
label: 'logs lost',
|
|
27
|
+
tally: (count) => `${count} package(s) lost their log output — their counts came back in the run's summary, but nothing could be checked for tracebacks`,
|
|
28
|
+
},
|
|
29
|
+
'empty-run': {
|
|
30
|
+
label: 'ran 0 tests',
|
|
31
|
+
tally: (count) => `${count} package(s) ran 0 tests — check test discovery`,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Work out how a result should be presented.
|
|
36
|
+
*
|
|
37
|
+
* A failure stays a failure whatever its caveats; a pass carrying any caveat
|
|
38
|
+
* becomes a warning. Caveats are not exclusive — a run can report no counts and
|
|
39
|
+
* have lost its logs — so they are collected rather than ranked, and every
|
|
40
|
+
* renderer shows all of them.
|
|
41
|
+
*/
|
|
42
|
+
export function resolveResultStatus(result, options = {}) {
|
|
43
|
+
const caveats = [];
|
|
44
|
+
if ((options.expectsTestCounts ?? false) &&
|
|
45
|
+
result.progressSummary === undefined) {
|
|
46
|
+
caveats.push('no-counts');
|
|
47
|
+
}
|
|
48
|
+
for (const caveat of result.caveats ?? []) {
|
|
49
|
+
if (!caveats.includes(caveat)) {
|
|
50
|
+
caveats.push(caveat);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (isEmptyTestRun(result.progressSummary)) {
|
|
54
|
+
caveats.push('empty-run');
|
|
55
|
+
}
|
|
56
|
+
if (!result.success) {
|
|
57
|
+
return {
|
|
58
|
+
severity: 'failure',
|
|
59
|
+
label: result.failureLabel ?? options.failureLabel ?? 'FAILED',
|
|
60
|
+
failedPhase: result.failedPhase,
|
|
61
|
+
progress: formatProgressResult(result.progressSummary),
|
|
62
|
+
caveats,
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// "Unverified" rather than "Passed": with no counts at all, the run's own
|
|
66
|
+
// account of itself never arrived, and calling that a pass is the claim this
|
|
67
|
+
// is here to avoid making.
|
|
68
|
+
const unverified = caveats.includes('no-counts');
|
|
69
|
+
return {
|
|
70
|
+
severity: caveats.length > 0 ? 'warning' : 'success',
|
|
71
|
+
label: unverified ? 'Unverified' : options.successLabel ?? 'Passed',
|
|
72
|
+
progress: unverified ? '' : formatProgressResult(result.progressSummary),
|
|
73
|
+
caveats,
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The status as one line of plain text: "Passed (35/35) - logs lost".
|
|
78
|
+
*
|
|
79
|
+
* No icon, no duration and no color — those differ between a markdown table, a
|
|
80
|
+
* terminal line and a collapsible group header, and are the renderer's to add.
|
|
81
|
+
*/
|
|
82
|
+
export function formatStatusText(status) {
|
|
83
|
+
const verdict = status.failedPhase
|
|
84
|
+
? `${status.label} at ${status.failedPhase}`
|
|
85
|
+
: status.label;
|
|
86
|
+
const head = [verdict, status.progress].filter(Boolean).join(' ');
|
|
87
|
+
if (status.caveats.length === 0) {
|
|
88
|
+
return head;
|
|
89
|
+
}
|
|
90
|
+
return `${head} - ${status.caveats
|
|
91
|
+
.map((caveat) => CAVEAT_COPY[caveat].label)
|
|
92
|
+
.join(', ')}`;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* The icon for a severity.
|
|
96
|
+
*
|
|
97
|
+
* `emoji` for markdown, where they render as intended; `ascii` for a terminal
|
|
98
|
+
* line, where a variation-selector emoji is two columns wide and breaks column
|
|
99
|
+
* alignment.
|
|
100
|
+
*/
|
|
101
|
+
export function statusIcon(severity, style) {
|
|
102
|
+
if (style === 'emoji') {
|
|
103
|
+
return severity === 'failure' ? '❌' : severity === 'warning' ? '⚠️' : '✅';
|
|
104
|
+
}
|
|
105
|
+
return severity === 'failure' ? '✗' : severity === 'warning' ? '⚠' : '✓';
|
|
106
|
+
}
|
|
107
|
+
/** Color text by severity, using the shared palette. */
|
|
108
|
+
export function colorStatus(text, severity) {
|
|
109
|
+
if (severity === 'failure') {
|
|
110
|
+
return OutputHelper.formatError(text);
|
|
111
|
+
}
|
|
112
|
+
if (severity === 'warning') {
|
|
113
|
+
return OutputHelper.formatWarning(text);
|
|
114
|
+
}
|
|
115
|
+
return OutputHelper.formatSuccess(text);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Roll up the caveats across a run, for the lines under a summary.
|
|
119
|
+
*
|
|
120
|
+
* Counted off the same statuses the rows were drawn from, so the tally and the
|
|
121
|
+
* rows cannot disagree — which they could when each reporter counted its own.
|
|
122
|
+
*/
|
|
123
|
+
export function tallyCaveats(statuses) {
|
|
124
|
+
const counts = new Map();
|
|
125
|
+
for (const status of statuses) {
|
|
126
|
+
for (const caveat of status.caveats) {
|
|
127
|
+
counts.set(caveat, (counts.get(caveat) ?? 0) + 1);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
const order = ['no-counts', 'logs-lost', 'empty-run'];
|
|
131
|
+
return order
|
|
132
|
+
.filter((caveat) => counts.has(caveat))
|
|
133
|
+
.map((caveat) => {
|
|
134
|
+
const count = counts.get(caveat);
|
|
135
|
+
return { caveat, count, message: CAVEAT_COPY[caveat].tally(count) };
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
//# sourceMappingURL=result-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-status.js","sourceRoot":"","sources":["../../src/reporting/result-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-status.test.d.ts","sourceRoot":"","sources":["../../src/reporting/result-status.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { describe, it, expect } from 'vitest';
|
|
2
|
+
import { formatStatusText, resolveResultStatus, statusIcon, tallyCaveats, } from './result-status.js';
|
|
3
|
+
function counts(passed, total) {
|
|
4
|
+
return {
|
|
5
|
+
success: true,
|
|
6
|
+
progressSummary: {
|
|
7
|
+
kind: 'test-counts',
|
|
8
|
+
passed,
|
|
9
|
+
failed: total - passed,
|
|
10
|
+
total,
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
describe('resolveResultStatus', () => {
|
|
15
|
+
it('calls a clean pass a success', () => {
|
|
16
|
+
const status = resolveResultStatus(counts(68, 68));
|
|
17
|
+
expect(status.severity).toBe('success');
|
|
18
|
+
expect(formatStatusText(status)).toBe('Passed (68/68)');
|
|
19
|
+
});
|
|
20
|
+
it('keeps a failure a failure however it is qualified', () => {
|
|
21
|
+
// A caveat narrows what a result proves; it never softens a failure into a
|
|
22
|
+
// warning, or a red row would go amber for having lost its logs.
|
|
23
|
+
const status = resolveResultStatus({
|
|
24
|
+
...counts(3, 4),
|
|
25
|
+
success: false,
|
|
26
|
+
caveats: ['logs-lost'],
|
|
27
|
+
});
|
|
28
|
+
expect(status.severity).toBe('failure');
|
|
29
|
+
expect(formatStatusText(status)).toBe('FAILED (3/4) - logs lost');
|
|
30
|
+
});
|
|
31
|
+
it('demotes a pass that carries a caveat to a warning', () => {
|
|
32
|
+
const status = resolveResultStatus({
|
|
33
|
+
...counts(35, 35),
|
|
34
|
+
caveats: ['logs-lost'],
|
|
35
|
+
});
|
|
36
|
+
expect(status.severity).toBe('warning');
|
|
37
|
+
expect(formatStatusText(status)).toBe('Passed (35/35) - logs lost');
|
|
38
|
+
});
|
|
39
|
+
it('flags a pass that ran no tests', () => {
|
|
40
|
+
const status = resolveResultStatus(counts(0, 0));
|
|
41
|
+
expect(status.severity).toBe('warning');
|
|
42
|
+
expect(status.caveats).toEqual(['empty-run']);
|
|
43
|
+
});
|
|
44
|
+
it('calls a pass with no counts unverified, when counts were expected', () => {
|
|
45
|
+
// The claim being avoided: a green row with nothing behind it is
|
|
46
|
+
// indistinguishable from one that tested something.
|
|
47
|
+
const status = resolveResultStatus({ success: true }, { expectsTestCounts: true });
|
|
48
|
+
expect(status.severity).toBe('warning');
|
|
49
|
+
expect(formatStatusText(status)).toBe('Unverified - no test counts reported');
|
|
50
|
+
});
|
|
51
|
+
it('says nothing about missing counts where none were expected', () => {
|
|
52
|
+
// A deploy has no test counts and is not suspect for lacking them.
|
|
53
|
+
const status = resolveResultStatus({ success: true });
|
|
54
|
+
expect(status.severity).toBe('success');
|
|
55
|
+
expect(status.caveats).toEqual([]);
|
|
56
|
+
});
|
|
57
|
+
it('reports every caveat that applies, not just the first', () => {
|
|
58
|
+
const status = resolveResultStatus({ ...counts(0, 0), caveats: ['logs-lost'] }, { expectsTestCounts: true });
|
|
59
|
+
expect(status.caveats).toEqual(['logs-lost', 'empty-run']);
|
|
60
|
+
expect(formatStatusText(status)).toBe('Passed (0/0) - logs lost, ran 0 tests');
|
|
61
|
+
});
|
|
62
|
+
it('names the phase a failure happened in', () => {
|
|
63
|
+
const status = resolveResultStatus({
|
|
64
|
+
success: false,
|
|
65
|
+
failedPhase: 'uploading',
|
|
66
|
+
});
|
|
67
|
+
expect(formatStatusText(status)).toBe('FAILED at uploading');
|
|
68
|
+
});
|
|
69
|
+
it('takes the labels the caller uses for its own kind of run', () => {
|
|
70
|
+
const status = resolveResultStatus({ success: true }, { successLabel: 'Deployed' });
|
|
71
|
+
expect(formatStatusText(status)).toBe('Deployed');
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
describe('tallyCaveats', () => {
|
|
75
|
+
it('counts each caveat across a run', () => {
|
|
76
|
+
const statuses = [
|
|
77
|
+
resolveResultStatus({ ...counts(5, 5), caveats: ['logs-lost'] }),
|
|
78
|
+
resolveResultStatus({ ...counts(9, 9), caveats: ['logs-lost'] }),
|
|
79
|
+
resolveResultStatus(counts(0, 0)),
|
|
80
|
+
];
|
|
81
|
+
expect(tallyCaveats(statuses)).toEqual([
|
|
82
|
+
{
|
|
83
|
+
caveat: 'logs-lost',
|
|
84
|
+
count: 2,
|
|
85
|
+
message: expect.stringContaining('2 package(s) lost their log output'),
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
caveat: 'empty-run',
|
|
89
|
+
count: 1,
|
|
90
|
+
message: '1 package(s) ran 0 tests — check test discovery',
|
|
91
|
+
},
|
|
92
|
+
]);
|
|
93
|
+
});
|
|
94
|
+
it('says nothing when every result is clean', () => {
|
|
95
|
+
expect(tallyCaveats([resolveResultStatus(counts(3, 3))])).toEqual([]);
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
describe('statusIcon', () => {
|
|
99
|
+
it('uses emoji for markdown and single-width glyphs for a terminal', () => {
|
|
100
|
+
// A variation-selector emoji is two columns wide, which breaks the aligned
|
|
101
|
+
// status column in the summary table.
|
|
102
|
+
expect(statusIcon('warning', 'emoji')).toBe('⚠️');
|
|
103
|
+
expect(statusIcon('warning', 'ascii')).toBe('⚠');
|
|
104
|
+
expect(statusIcon('success', 'ascii')).toBe('✓');
|
|
105
|
+
expect(statusIcon('failure', 'ascii')).toBe('✗');
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=result-status.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result-status.test.js","sourceRoot":"","sources":["../../src/reporting/result-status.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner-reporter.d.ts","sourceRoot":"","sources":["../../src/reporting/spinner-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqC,YAAY,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"spinner-reporter.d.ts","sourceRoot":"","sources":["../../src/reporting/spinner-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAqC,YAAY,EAAE,MAAM,eAAe,CAAC;AAChF,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAS9D,MAAM,WAAW,sBAAsB;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iFAAiF;IACjF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAyBD;;;;;;;;;;;GAWG;AACH,qBAAa,eAAgB,SAAQ,YAAY;IAC/C,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,eAAe,CAAC,CAAiC;IACzD,OAAO,CAAC,aAAa,CAAa;IAClC,OAAO,CAAC,eAAe,CAAc;IACrC,OAAO,CAAC,oBAAoB,CAA0C;IACtE,OAAO,CAAC,oBAAoB,CAA0C;IACtE,OAAO,CAAC,YAAY,CAAS;gBAEjB,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,sBAAsB;IAMlD,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC;IAoD3B,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAkCzC,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,gBAAgB;IA2BxB,OAAO,CAAC,QAAQ;IAShB,OAAO,CAAC,OAAO;CA0EhB"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { OutputHelper } from '../outputHelper.js';
|
|
2
2
|
import { formatDurationMs } from '../cli-utils.js';
|
|
3
3
|
import { BaseReporter } from './reporter.js';
|
|
4
|
-
import { formatProgressInline
|
|
4
|
+
import { formatProgressInline } from './progress-format.js';
|
|
5
|
+
import { colorStatus, formatStatusText, resolveResultStatus, statusIcon, } from './result-status.js';
|
|
5
6
|
const SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
|
|
6
7
|
// Wide enough to fit "⬇ Downloading (12.3 MB/12.3 MB)" without bumping the
|
|
7
8
|
// duration column out of alignment. Bytes progress is the widest case; test
|
|
@@ -134,16 +135,9 @@ export class SpinnerReporter extends BaseReporter {
|
|
|
134
135
|
}
|
|
135
136
|
}
|
|
136
137
|
_printResultLogs(result) {
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const status = result.success
|
|
141
|
-
? this._options.successLabel ?? 'Passed'
|
|
142
|
-
: result.failureLabel ?? this._options.failureLabel ?? 'FAILED';
|
|
143
|
-
const formatted = result.success
|
|
144
|
-
? OutputHelper.formatSuccess(status)
|
|
145
|
-
: OutputHelper.formatError(status);
|
|
146
|
-
console.log(`${icon} ${OutputHelper.formatDim('──')} ${result.packageName} ${OutputHelper.formatDim('──')} ${formatted}`);
|
|
138
|
+
const status = this._resolve(result);
|
|
139
|
+
const icon = colorStatus(statusIcon(status.severity, 'ascii'), status.severity);
|
|
140
|
+
console.log(`${icon} ${OutputHelper.formatDim('──')} ${result.packageName} ${OutputHelper.formatDim('──')} ${colorStatus(formatStatusText(status), status.severity)}`);
|
|
147
141
|
if (result.logs) {
|
|
148
142
|
console.log(result.logs);
|
|
149
143
|
}
|
|
@@ -155,6 +149,12 @@ export class SpinnerReporter extends BaseReporter {
|
|
|
155
149
|
}
|
|
156
150
|
console.log('');
|
|
157
151
|
}
|
|
152
|
+
_resolve(result) {
|
|
153
|
+
return resolveResultStatus(result, {
|
|
154
|
+
successLabel: this._options.successLabel,
|
|
155
|
+
failureLabel: this._options.failureLabel,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
158
|
_render() {
|
|
159
159
|
const lines = [];
|
|
160
160
|
const spinner = SPINNER_FRAMES[this._spinnerFrame];
|
|
@@ -169,28 +169,13 @@ export class SpinnerReporter extends BaseReporter {
|
|
|
169
169
|
const statusText = OutputHelper.formatDim('Queued');
|
|
170
170
|
line = ` ${icon} ${OutputHelper.formatDim(state.name.padEnd(30))} ${statusText}`;
|
|
171
171
|
}
|
|
172
|
-
else if (state.status === 'passed') {
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
plain += ' ⚠';
|
|
180
|
-
const padded = OutputHelper.padVisible(plain, STATUS_COLUMN_WIDTH);
|
|
181
|
-
const statusText = empty
|
|
182
|
-
? OutputHelper.formatWarning(padded)
|
|
183
|
-
: OutputHelper.formatSuccess(padded);
|
|
184
|
-
line = ` ${icon} ${state.name.padEnd(30)} ${statusText} ${OutputHelper.formatDim(time)}`;
|
|
185
|
-
}
|
|
186
|
-
else if (state.status === 'failed') {
|
|
187
|
-
const icon = OutputHelper.formatError('✗');
|
|
188
|
-
const failedPhase = state.result?.failedPhase;
|
|
189
|
-
const failureLabel = state.result?.failureLabel ?? this._options.failureLabel ?? 'FAILED';
|
|
190
|
-
const plain = failedPhase
|
|
191
|
-
? `${failureLabel} at ${failedPhase}`
|
|
192
|
-
: failureLabel;
|
|
193
|
-
const statusText = OutputHelper.formatError(plain.padEnd(STATUS_COLUMN_WIDTH));
|
|
172
|
+
else if (state.status === 'passed' || state.status === 'failed') {
|
|
173
|
+
// Both terminal states through one resolver: a pass that ran no tests
|
|
174
|
+
// and a pass whose logs went missing are warnings, and deciding that
|
|
175
|
+
// here is how the spinner and the table came to disagree about them.
|
|
176
|
+
const status = this._resolve(state.result ?? { success: state.status === 'passed' });
|
|
177
|
+
const icon = colorStatus(statusIcon(status.severity, 'ascii'), status.severity);
|
|
178
|
+
const statusText = colorStatus(OutputHelper.padVisible(formatStatusText(status), STATUS_COLUMN_WIDTH), status.severity);
|
|
194
179
|
line = ` ${icon} ${state.name.padEnd(30)} ${statusText} ${OutputHelper.formatDim(time)}`;
|
|
195
180
|
}
|
|
196
181
|
else {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spinner-reporter.js","sourceRoot":"","sources":["../../src/reporting/spinner-reporter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAqC,YAAY,EAAE,MAAM,eAAe,CAAC;AAEhF,OAAO,
|
|
1
|
+
{"version":3,"file":"spinner-reporter.js","sourceRoot":"","sources":["../../src/reporting/spinner-reporter.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,11 @@ export interface SummaryTableReporterOptions {
|
|
|
7
7
|
failureLabel?: string;
|
|
8
8
|
/** Verb in the footer, e.g. "tested" in "X tested, Y passed, Z failed". Default: "tested" */
|
|
9
9
|
summaryVerb?: string;
|
|
10
|
+
/**
|
|
11
|
+
* True when this kind of run should have reported test counts, so a result
|
|
12
|
+
* with none is flagged rather than shown as a plain pass.
|
|
13
|
+
*/
|
|
14
|
+
expectsTestCounts?: boolean;
|
|
10
15
|
}
|
|
11
16
|
/**
|
|
12
17
|
* Prints a final summary table of all results when jobs complete.
|
|
@@ -17,9 +22,9 @@ export declare class SummaryTableReporter extends BaseReporter {
|
|
|
17
22
|
private _successLabel;
|
|
18
23
|
private _failureLabel;
|
|
19
24
|
private _summaryVerb;
|
|
25
|
+
private _expectsTestCounts;
|
|
20
26
|
constructor(state: IStateTracker, options?: SummaryTableReporterOptions);
|
|
21
27
|
stopAsync(): Promise<void>;
|
|
22
|
-
private
|
|
23
|
-
private _colorStatus;
|
|
28
|
+
private _resolve;
|
|
24
29
|
}
|
|
25
30
|
//# sourceMappingURL=summary-table-reporter.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"summary-table-reporter.d.ts","sourceRoot":"","sources":["../../src/reporting/summary-table-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAsB,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"summary-table-reporter.d.ts","sourceRoot":"","sources":["../../src/reporting/summary-table-reporter.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAsB,MAAM,eAAe,CAAC;AAEjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,0BAA0B,CAAC;AAS9D,MAAM,WAAW,2BAA2B;IAC1C,mEAAmE;IACnE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,6FAA6F;IAC7F,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,YAAY;IACpD,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,kBAAkB,CAAU;gBAExB,KAAK,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE,2BAA2B;IASxD,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA0DzC,OAAO,CAAC,QAAQ;CAOjB"}
|
|
@@ -2,7 +2,7 @@ import { OutputHelper } from '../outputHelper.js';
|
|
|
2
2
|
import { formatDurationMs } from '../cli-utils.js';
|
|
3
3
|
import { BaseReporter } from './reporter.js';
|
|
4
4
|
import { formatTable } from './format-table.js';
|
|
5
|
-
import {
|
|
5
|
+
import { colorStatus, formatStatusText, resolveResultStatus, tallyCaveats, } from './result-status.js';
|
|
6
6
|
/**
|
|
7
7
|
* Prints a final summary table of all results when jobs complete.
|
|
8
8
|
* All output happens in stopAsync().
|
|
@@ -12,12 +12,14 @@ export class SummaryTableReporter extends BaseReporter {
|
|
|
12
12
|
_successLabel;
|
|
13
13
|
_failureLabel;
|
|
14
14
|
_summaryVerb;
|
|
15
|
+
_expectsTestCounts;
|
|
15
16
|
constructor(state, options) {
|
|
16
17
|
super();
|
|
17
18
|
this._state = state;
|
|
18
19
|
this._successLabel = options?.successLabel ?? 'Passed';
|
|
19
20
|
this._failureLabel = options?.failureLabel ?? 'FAILED';
|
|
20
21
|
this._summaryVerb = options?.summaryVerb ?? 'tested';
|
|
22
|
+
this._expectsTestCounts = options?.expectsTestCounts ?? false;
|
|
21
23
|
}
|
|
22
24
|
async stopAsync() {
|
|
23
25
|
const results = this._state
|
|
@@ -29,7 +31,9 @@ export class SummaryTableReporter extends BaseReporter {
|
|
|
29
31
|
const failures = this._state.getFailures();
|
|
30
32
|
const passed = results.length - failures.length;
|
|
31
33
|
const durationMs = Date.now() - this._state.startTimeMs;
|
|
32
|
-
|
|
34
|
+
// Resolved once per result and reused for the row and the footer, so the
|
|
35
|
+
// tally under the table cannot disagree with the rows in it.
|
|
36
|
+
const statuses = new Map(results.map((result) => [result, this._resolve(result)]));
|
|
33
37
|
const columns = [
|
|
34
38
|
{
|
|
35
39
|
header: 'Package',
|
|
@@ -38,8 +42,8 @@ export class SummaryTableReporter extends BaseReporter {
|
|
|
38
42
|
},
|
|
39
43
|
{
|
|
40
44
|
header: 'Status',
|
|
41
|
-
value: (r) =>
|
|
42
|
-
format: (label, r) =>
|
|
45
|
+
value: (r) => formatStatusText(statuses.get(r)),
|
|
46
|
+
format: (label, r) => colorStatus(label, statuses.get(r).severity),
|
|
43
47
|
minWidth: 26,
|
|
44
48
|
},
|
|
45
49
|
{
|
|
@@ -58,31 +62,16 @@ export class SummaryTableReporter extends BaseReporter {
|
|
|
58
62
|
const totalTime = OutputHelper.formatDim(`in ${formatDurationMs(durationMs)}`);
|
|
59
63
|
const unit = results.length === 1 ? 'package' : 'packages';
|
|
60
64
|
console.log(`${results.length} ${unit} ${this._summaryVerb}, ${passedText}, ${failedText} ${totalTime}`);
|
|
61
|
-
|
|
62
|
-
console.log(OutputHelper.formatWarning(`⚠ ${
|
|
65
|
+
for (const { message } of tallyCaveats([...statuses.values()])) {
|
|
66
|
+
console.log(OutputHelper.formatWarning(`⚠ ${message}`));
|
|
63
67
|
}
|
|
64
68
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
const failedPhase = result.failedPhase;
|
|
73
|
-
const failureLabel = result.failureLabel ?? this._failureLabel;
|
|
74
|
-
return failedPhase ? `${failureLabel} at ${failedPhase}` : failureLabel;
|
|
75
|
-
}
|
|
76
|
-
_colorStatus(label, result, countEmpty) {
|
|
77
|
-
if (result.success) {
|
|
78
|
-
const empty = isEmptyTestRun(result.progressSummary);
|
|
79
|
-
if (empty)
|
|
80
|
-
countEmpty();
|
|
81
|
-
return empty
|
|
82
|
-
? OutputHelper.formatWarning(label)
|
|
83
|
-
: OutputHelper.formatSuccess(label);
|
|
84
|
-
}
|
|
85
|
-
return OutputHelper.formatError(label);
|
|
69
|
+
_resolve(result) {
|
|
70
|
+
return resolveResultStatus(result, {
|
|
71
|
+
successLabel: this._successLabel,
|
|
72
|
+
failureLabel: this._failureLabel,
|
|
73
|
+
expectsTestCounts: this._expectsTestCounts,
|
|
74
|
+
});
|
|
86
75
|
}
|
|
87
76
|
}
|
|
88
77
|
//# sourceMappingURL=summary-table-reporter.js.map
|