Skip to content

Commit 0cdcb9e

Browse files
committed
feat(utils): handle unchanged reports diff
1 parent 41607f2 commit 0cdcb9e

File tree

7 files changed

+177
-22
lines changed

7 files changed

+177
-22
lines changed

packages/utils/src/lib/reports/__snapshots__/report-diff-improved.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Code PushUp
22

3-
🙌 Code PushUp report has **improved** – compared target commit `0123456` with source commit `abcdef0`.
3+
🥳 Code PushUp report has **improved** – compared target commit `0123456` with source commit `abcdef0`.
44

55
## 🏷️ Categories
66

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Code PushUp
2+
3+
😟 Code PushUp report has **regressed** – compared target commit `0123456` with source commit `abcdef0`.
4+
5+
## 🛡️ Audits
6+
7+
<details>
8+
<summary>👎 <strong>1</strong> audit regressed</summary>
9+
10+
|🔌 Plugin|🛡️ Audit|📏 Current value|📏 Previous value|🗠 Value change|
11+
|:--|:--|:--:|:--:|:--:|
12+
|NPM|Check for outdates NPM packages|🟨 **3 packages are out of date**|🟩 1 package is out of date|<span style="color: red">▲ **+200%**</span>|
13+
14+
</details>

packages/utils/src/lib/reports/__snapshots__/report-diff-mixed.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Code PushUp
22

3-
😐 Code PushUp report has both **improved and regressed** – compared target commit `0123456` with source commit `abcdef0`.
3+
🤨 Code PushUp report has both **improvements and regressions** – compared target commit `0123456` with source commit `abcdef0`.
44

55
## 🏷️ Categories
66

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Code PushUp
2+
3+
😐 Code PushUp report is **unchanged** – compared target commit `0123456` with source commit `abcdef0`.
4+
5+
## 🏷️ Categories
6+
7+
<details>
8+
<summary>All of 3 categories are unchanged.</summary>
9+
10+
- Performance: 🟢 **92**
11+
- Bug prevention: 🟡 **68**
12+
- Code style: 🟡 **54**
13+
14+
</details>
15+
16+
17+
## 🎗️ Groups
18+
19+
All of 2 groups are unchanged.
20+
21+
## 🛡️ Audits
22+
23+
All of 52 audits are unchanged.

packages/utils/src/lib/reports/generate-md-reports-diff.integration.test.ts

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
import { reportsDiffAltMock, reportsDiffMock } from '@code-pushup/test-utils';
1+
import {
2+
reportsDiffAltMock,
3+
reportsDiffMock,
4+
reportsDiffUnchangedMock,
5+
} from '@code-pushup/test-utils';
26
import { generateMdReportsDiff } from './generate-md-reports-diff';
37

48
describe('generateMdReportsDiff', () => {
@@ -13,4 +17,38 @@ describe('generateMdReportsDiff', () => {
1317
generateMdReportsDiff(reportsDiffAltMock()),
1418
).toMatchFileSnapshot('__snapshots__/report-diff-mixed.md');
1519
});
20+
21+
it('should format Markdown comment for minimal reports diff', async () => {
22+
await expect(
23+
generateMdReportsDiff({
24+
...reportsDiffMock(),
25+
categories: { changed: [], unchanged: [], added: [], removed: [] },
26+
groups: { changed: [], unchanged: [], added: [], removed: [] },
27+
audits: {
28+
changed: [
29+
{
30+
slug: 'npm-outdated',
31+
title: 'Check for outdates NPM packages',
32+
plugin: { slug: 'npm', title: 'NPM' },
33+
scores: { before: 0.9, after: 0.7, diff: -0.2 },
34+
values: { before: 1, after: 3, diff: 2 },
35+
displayValues: {
36+
before: '1 package is out of date',
37+
after: '3 packages are out of date',
38+
},
39+
},
40+
],
41+
unchanged: [],
42+
added: [],
43+
removed: [],
44+
},
45+
}),
46+
).toMatchFileSnapshot('__snapshots__/report-diff-minimal.md');
47+
});
48+
49+
it('should format Markdown comment for unchanged reports diff', async () => {
50+
await expect(
51+
generateMdReportsDiff(reportsDiffUnchangedMock()),
52+
).toMatchFileSnapshot('__snapshots__/report-diff-unchanged.md');
53+
});
1654
});

packages/utils/src/lib/reports/generate-md-reports-diff.ts

+31-19
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ export function generateMdReportsDiff(diff: ReportsDiff): string {
3434

3535
function formatDiffHeaderSection(diff: ReportsDiff): string {
3636
const outcomeTexts: Record<DiffOutcome, string> = {
37-
positive: `🙌 Code PushUp report has ${style('improved')}`,
37+
positive: `🥳 Code PushUp report has ${style('improved')}`,
3838
negative: `😟 Code PushUp report has ${style('regressed')}`,
39-
neutral: `Code PushUp report is ${style('unchanged')}`,
40-
mixed: `😐 Code PushUp report has both ${style('improved and regressed')}`,
39+
neutral: `😐 Code PushUp report is ${style('unchanged')}`,
40+
mixed: `🤨 Code PushUp report has both ${style(
41+
'improvements and regressions',
42+
)}`,
4143
};
4244
const outcome = mergeDiffOutcomes(
4345
changesToDiffOutcomes([
@@ -64,25 +66,29 @@ function formatDiffHeaderSection(diff: ReportsDiff): string {
6466

6567
function formatDiffCategoriesSection(diff: ReportsDiff): string {
6668
const { changed, unchanged } = diff.categories;
69+
if (changed.length + unchanged.length === 0) {
70+
return '';
71+
}
6772
return paragraphs(
6873
h2('🏷️ Categories'),
69-
tableMd(
70-
[
74+
changed.length > 0 &&
75+
tableMd(
7176
[
72-
'🏷️ Category',
73-
'⭐ Current score',
74-
'⭐ Previous score',
75-
'🗠 Score change',
77+
[
78+
'🏷️ Category',
79+
'⭐ Current score',
80+
'⭐ Previous score',
81+
'🗠 Score change',
82+
],
83+
...changed.map(category => [
84+
category.title,
85+
formatScoreWithColor(category.scores.after),
86+
formatScoreWithColor(category.scores.before, { skipBold: true }),
87+
formatScoreChange(category.scores.diff),
88+
]),
7689
],
77-
...changed.map(category => [
78-
category.title,
79-
formatScoreWithColor(category.scores.after),
80-
formatScoreWithColor(category.scores.before, { skipBold: true }),
81-
formatScoreChange(category.scores.diff),
82-
]),
83-
],
84-
['l', 'c', 'c', 'c'],
85-
),
90+
['l', 'c', 'c', 'c'],
91+
),
8692
unchanged.length > 0 &&
8793
details(
8894
summarizeUnchanged('category', { changed, unchanged }),
@@ -96,6 +102,9 @@ function formatDiffCategoriesSection(diff: ReportsDiff): string {
96102
}
97103

98104
function formatDiffGroupsSection(diff: ReportsDiff): string {
105+
if (diff.groups.changed.length + diff.groups.unchanged.length === 0) {
106+
return '';
107+
}
99108
return paragraphs(
100109
h2('🎗️ Groups'),
101110
formatGroupsOrAuditsDetails('group', diff.groups, {
@@ -201,7 +210,7 @@ function summarizeUnchanged(
201210
changed.length > 0
202211
? pluralizeToken(`other ${token}`, unchanged.length)
203212
: `All of ${pluralizeToken(token, unchanged.length)}`,
204-
unchanged.length > 1 ? 'are' : 'is',
213+
unchanged.length === 1 ? 'is' : 'are',
205214
'unchanged.',
206215
].join(' ');
207216
}
@@ -247,6 +256,9 @@ function changesToDiffOutcomes(
247256
}
248257

249258
function mergeDiffOutcomes(outcomes: DiffOutcome[]): DiffOutcome {
259+
if (outcomes.length === 0) {
260+
return 'neutral';
261+
}
250262
if (
251263
outcomes.every(outcome => outcome === 'positive' || outcome === 'neutral')
252264
) {

testing/test-utils/src/lib/utils/dynamic-mocks/report-diff.mock.ts

+68
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,74 @@ export function reportsDiffAltMock(): ReportsDiff {
247247
};
248248
}
249249

250+
export function reportsDiffUnchangedMock(): ReportsDiff {
251+
return {
252+
...reportsDiffMock(),
253+
categories: {
254+
changed: [],
255+
unchanged: CATEGORY_SLUGS.map(slug => ({
256+
slug,
257+
title: CATEGORIES_MAP[slug].title,
258+
score: categoryScores(slug).before,
259+
})),
260+
added: [],
261+
removed: [],
262+
},
263+
groups: {
264+
changed: [],
265+
unchanged: [
266+
{
267+
slug: ESLINT_PLUGIN_GROUP_MAX_LINES.slug,
268+
title: ESLINT_PLUGIN_GROUP_MAX_LINES.title,
269+
plugin: {
270+
slug: ESLINT_PLUGIN_META.slug,
271+
title: ESLINT_PLUGIN_META.title,
272+
},
273+
score: 0.5,
274+
},
275+
{
276+
slug: LH_PLUGIN_GROUP_PERFORMANCE.slug,
277+
title: LH_PLUGIN_GROUP_PERFORMANCE.title,
278+
plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title },
279+
score: 0.92,
280+
},
281+
],
282+
added: [],
283+
removed: [],
284+
},
285+
audits: {
286+
changed: [],
287+
unchanged: [
288+
...ESLINT_AUDIT_SLUGS.map(
289+
(slug): AuditResult => ({
290+
slug,
291+
title: ESLINT_AUDITS_MAP[slug].title,
292+
plugin: {
293+
slug: ESLINT_PLUGIN_META.slug,
294+
title: ESLINT_PLUGIN_META.title,
295+
},
296+
score: ESLINT_AUDITS_MAP[slug].score,
297+
value: ESLINT_AUDITS_MAP[slug].value,
298+
displayValue: ESLINT_AUDITS_MAP[slug].displayValue,
299+
}),
300+
),
301+
...LIGHTHOUSE_AUDIT_SLUGS.map(
302+
(slug): AuditResult => ({
303+
slug,
304+
title: LIGHTHOUSE_AUDITS_MAP[slug].title,
305+
plugin: { slug: LH_PLUGIN_META.slug, title: LH_PLUGIN_META.title },
306+
score: LIGHTHOUSE_AUDITS_MAP[slug].score,
307+
value: LIGHTHOUSE_AUDITS_MAP[slug].value,
308+
displayValue: LIGHTHOUSE_AUDITS_MAP[slug].displayValue,
309+
}),
310+
),
311+
],
312+
added: [],
313+
removed: [],
314+
},
315+
};
316+
}
317+
250318
function categoryScores(slug: CategorySlug): CategoryDiff['scores'] {
251319
switch (slug) {
252320
case 'performance':

0 commit comments

Comments
 (0)