Skip to content

Commit e0d1567

Browse files
authored
Merge ec5cafe into e538f8a
2 parents e538f8a + ec5cafe commit e0d1567

6 files changed

+270
-45
lines changed

packages/utils/src/lib/reports/__snapshots__/generate-md-report-category-section.unit.test.ts.snap

+18
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,17 @@ exports[`categoriesDetailsSection > should render complete categories details 1`
4545
"
4646
`;
4747

48+
exports[`categoriesDetailsSection > should render filtered categories details > filtered 1`] = `
49+
"## 🏷 Categories
50+
51+
### Bug Prevention
52+
53+
🟢 Score: **100** ✅
54+
55+
- 🟩 [No let](#no-let-eslint) (_Eslint_) - **0**
56+
"
57+
`;
58+
4859
exports[`categoriesOverviewSection > should render complete categories table 1`] = `
4960
"| 🏷 Category | ⭐ Score | 🛡 Audits |
5061
| :-------------------------------- | :-------: | :-------: |
@@ -54,6 +65,13 @@ exports[`categoriesOverviewSection > should render complete categories table 1`]
5465
"
5566
`;
5667

68+
exports[`categoriesOverviewSection > should render filtered categories table 1`] = `
69+
"| 🏷 Category | ⭐ Score | 🛡 Audits |
70+
| :-------------------------------- | :--------: | :-------: |
71+
| [Bug Prevention](#bug-prevention) | 🟢 **100** | 1 |
72+
"
73+
`;
74+
5775
exports[`categoriesOverviewSection > should render targetScore icon "❌" if score fails 1`] = `
5876
"| 🏷 Category | ⭐ Score | 🛡 Audits |
5977
| :-------------------------------- | :---------: | :-------: |

packages/utils/src/lib/reports/generate-md-report-category-section.unit.test.ts

+104
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,48 @@ describe('categoriesOverviewSection', () => {
4949
).toMatchSnapshot();
5050
});
5151

52+
it('should render filtered categories table', () => {
53+
expect(
54+
categoriesOverviewSection(
55+
{
56+
plugins: [
57+
{
58+
slug: 'eslint',
59+
title: 'Eslint',
60+
},
61+
{
62+
slug: 'lighthouse',
63+
title: 'Lighthouse',
64+
},
65+
],
66+
categories: [
67+
{
68+
slug: 'bug-prevention',
69+
title: 'Bug Prevention',
70+
score: 1,
71+
refs: [{ slug: 'no-let', type: 'audit' }],
72+
},
73+
{
74+
slug: 'performance',
75+
title: 'Performance',
76+
score: 0.74,
77+
refs: [{ slug: 'largest-contentful-paint', type: 'audit' }],
78+
},
79+
{
80+
slug: 'typescript',
81+
title: 'Typescript',
82+
score: 0.14,
83+
refs: [{ slug: 'no-any', type: 'audit' }],
84+
},
85+
],
86+
} as Required<Pick<ScoredReport, 'plugins' | 'categories'>>,
87+
{
88+
isScoreListed: score => score === 1,
89+
},
90+
).toString(),
91+
).toMatchSnapshot();
92+
});
93+
5294
it('should render targetScore icon "❌" if score fails', () => {
5395
expect(
5496
categoriesOverviewSection({
@@ -215,6 +257,68 @@ describe('categoriesDetailsSection', () => {
215257
).toMatchSnapshot();
216258
});
217259

260+
it('should render filtered categories details', () => {
261+
expect(
262+
categoriesDetailsSection(
263+
{
264+
plugins: [
265+
{
266+
slug: 'eslint',
267+
title: 'Eslint',
268+
audits: [
269+
{ slug: 'no-let', title: 'No let', score: 1, value: 0 },
270+
{ slug: 'no-any', title: 'No any', score: 0, value: 5 },
271+
],
272+
},
273+
{
274+
slug: 'lighthouse',
275+
title: 'Lighthouse',
276+
audits: [
277+
{
278+
slug: 'largest-contentful-paint',
279+
title: 'Largest Contentful Paint',
280+
score: 0.7,
281+
value: 2905,
282+
},
283+
],
284+
},
285+
],
286+
categories: [
287+
{
288+
slug: 'bug-prevention',
289+
title: 'Bug Prevention',
290+
score: 1,
291+
isBinary: true,
292+
refs: [{ slug: 'no-let', type: 'audit', plugin: 'eslint' }],
293+
},
294+
{
295+
slug: 'performance',
296+
title: 'Performance',
297+
score: 0.74,
298+
refs: [
299+
{
300+
slug: 'largest-contentful-paint',
301+
type: 'audit',
302+
plugin: 'lighthouse',
303+
},
304+
],
305+
},
306+
{
307+
slug: 'typescript',
308+
title: 'Typescript',
309+
score: 0.14,
310+
isBinary: true,
311+
refs: [{ slug: 'no-any', type: 'audit', plugin: 'eslint' }],
312+
},
313+
],
314+
} as Required<Pick<ScoredReport, 'plugins' | 'categories'>>,
315+
{
316+
isScoreListed: score => score === 1,
317+
},
318+
).toString(),
319+
).toMatchSnapshot('filtered');
320+
});
321+
218322
it('should render categories details and add "❌" when isBinary is failing', () => {
219323
expect(
220324
categoriesDetailsSection({

packages/utils/src/lib/reports/generate-md-report-categoy-section.ts

+53-41
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { slugify } from '../formatting.js';
44
import { HIERARCHY } from '../text-formats/index.js';
55
import { metaDescription } from './formatting.js';
66
import { getSortableAuditByRef, getSortableGroupByRef } from './sorting.js';
7-
import type { ScoredGroup, ScoredReport } from './types.js';
7+
import type { ScoreFilter, ScoredGroup, ScoredReport } from './types.js';
88
import {
99
countCategoryAudits,
1010
formatReportScore,
@@ -15,64 +15,76 @@ import {
1515

1616
export function categoriesOverviewSection(
1717
report: Required<Pick<ScoredReport, 'plugins' | 'categories'>>,
18+
options?: ScoreFilter,
1819
): MarkdownDocument {
20+
const { isScoreListed = (_: number) => true } = options ?? {};
1921
const { categories, plugins } = report;
2022
return new MarkdownDocument().table(
2123
[
2224
{ heading: '🏷 Category', alignment: 'left' },
2325
{ heading: '⭐ Score', alignment: 'center' },
2426
{ heading: '🛡 Audits', alignment: 'center' },
2527
],
26-
categories.map(({ title, refs, score, isBinary }) => [
27-
// @TODO refactor `isBinary: boolean` to `targetScore: number` #713
28-
// The heading "ID" is inferred from the heading text in Markdown.
29-
md.link(`#${slugify(title)}`, title),
30-
md`${scoreMarker(score)} ${md.bold(
31-
formatReportScore(score),
32-
)}${binaryIconSuffix(score, isBinary)}`,
33-
countCategoryAudits(refs, plugins).toString(),
34-
]),
28+
categories
29+
.filter(({ score }) => isScoreListed(score))
30+
.map(({ title, refs, score, isBinary }) => [
31+
// @TODO refactor `isBinary: boolean` to `targetScore: number` #713
32+
// The heading "ID" is inferred from the heading text in Markdown.
33+
md.link(`#${slugify(title)}`, title),
34+
md`${scoreMarker(score)} ${md.bold(
35+
formatReportScore(score),
36+
)}${binaryIconSuffix(score, isBinary)}`,
37+
countCategoryAudits(refs, plugins).toString(),
38+
]),
3539
);
3640
}
3741

3842
export function categoriesDetailsSection(
3943
report: Required<Pick<ScoredReport, 'plugins' | 'categories'>>,
44+
options?: ScoreFilter,
4045
): MarkdownDocument {
46+
const { isScoreListed = (_: number) => true } = options ?? {};
4147
const { categories, plugins } = report;
4248

4349
return new MarkdownDocument()
4450
.heading(HIERARCHY.level_2, '🏷 Categories')
45-
.$foreach(categories, (doc, category) =>
46-
doc
47-
.heading(HIERARCHY.level_3, category.title)
48-
.paragraph(metaDescription(category))
49-
.paragraph(
50-
md`${scoreMarker(category.score)} Score: ${md.bold(
51-
formatReportScore(category.score),
52-
)}${binaryIconSuffix(category.score, category.isBinary)}`,
53-
)
54-
.list(
55-
category.refs.map(ref => {
56-
// Add group details
57-
if (ref.type === 'group') {
58-
const group = getSortableGroupByRef(ref, plugins);
59-
const groupAudits = group.refs.map(groupRef =>
60-
getSortableAuditByRef(
61-
{ ...groupRef, plugin: group.plugin, type: 'audit' },
62-
plugins,
63-
),
64-
);
65-
const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins);
66-
return categoryGroupItem(group, groupAudits, pluginTitle);
67-
}
68-
// Add audit details
69-
else {
70-
const audit = getSortableAuditByRef(ref, plugins);
71-
const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins);
72-
return categoryRef(audit, pluginTitle);
73-
}
74-
}),
75-
),
51+
.$foreach(
52+
categories.filter(({ score }) => isScoreListed(score)),
53+
(doc, category) =>
54+
doc
55+
.heading(HIERARCHY.level_3, category.title)
56+
.paragraph(metaDescription(category))
57+
.paragraph(
58+
md`${scoreMarker(category.score)} Score: ${md.bold(
59+
formatReportScore(category.score),
60+
)}${binaryIconSuffix(category.score, category.isBinary)}`,
61+
)
62+
.list(
63+
category.refs.map(ref => {
64+
// Add group details
65+
if (ref.type === 'group') {
66+
const group = getSortableGroupByRef(ref, plugins);
67+
const groupAudits = group.refs.map(groupRef =>
68+
getSortableAuditByRef(
69+
{ ...groupRef, plugin: group.plugin, type: 'audit' },
70+
plugins,
71+
),
72+
);
73+
const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins);
74+
return isScoreListed(group.score)
75+
? categoryGroupItem(group, groupAudits, pluginTitle)
76+
: '';
77+
}
78+
// Add audit details
79+
else {
80+
const audit = getSortableAuditByRef(ref, plugins);
81+
const pluginTitle = getPluginNameFromSlug(ref.plugin, plugins);
82+
return isScoreListed(audit.score)
83+
? categoryRef(audit, pluginTitle)
84+
: '';
85+
}
86+
}),
87+
),
7688
);
7789
}
7890

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

+14-3
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ export function auditDetailsAuditValue({
3030
)} (score: ${formatReportScore(score)})`;
3131
}
3232

33+
/**
34+
* Check if the report has categories.
35+
* @param report
36+
*/
3337
function hasCategories(
3438
report: ScoredReport,
3539
): report is ScoredReport & Required<Pick<ScoredReport, 'categories'>> {
@@ -40,13 +44,17 @@ export function generateMdReport(
4044
report: ScoredReport,
4145
options?: MdReportOptions,
4246
): string {
47+
const { isScoreListed, ...opts } = options ?? {};
4348
return new MarkdownDocument()
4449
.heading(HIERARCHY.level_1, REPORT_HEADLINE_TEXT)
4550
.$concat(
4651
...(hasCategories(report)
47-
? [categoriesOverviewSection(report), categoriesDetailsSection(report)]
52+
? [
53+
categoriesOverviewSection(report, { isScoreListed }),
54+
categoriesDetailsSection(report, { isScoreListed }),
55+
]
4856
: []),
49-
auditsSection(report, options),
57+
auditsSection(report, { isScoreListed, ...opts }),
5058
aboutSection(report),
5159
)
5260
.rule()
@@ -110,11 +118,14 @@ export function auditsSection(
110118
{ plugins }: Pick<ScoredReport, 'plugins'>,
111119
options?: MdReportOptions,
112120
): MarkdownDocument {
121+
const { isScoreListed = (_: number) => true } = options ?? {};
113122
return new MarkdownDocument()
114123
.heading(HIERARCHY.level_2, '🛡️ Audits')
115124
.$foreach(
116125
plugins.flatMap(plugin =>
117-
plugin.audits.map(audit => ({ ...audit, plugin })),
126+
plugin.audits
127+
.filter(audit => isScoreListed(audit.score))
128+
.map(audit => ({ ...audit, plugin })),
118129
),
119130
(doc, { plugin, ...audit }) => {
120131
const auditTitle = `${audit.title} (${plugin.title})`;

0 commit comments

Comments
 (0)