Skip to content

Commit 76a7636

Browse files
committed
fix(utils): sort groups and category refs correctly in report
1 parent 454cacc commit 76a7636

17 files changed

+143
-83
lines changed

packages/utils/perf/score-report/optimized0.ts

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import {
44
GroupRef,
55
Report,
66
} from '@code-pushup/models';
7-
import { ScoredReport } from '../../src';
8-
import { EnrichedScoredGroup } from '../../src/lib/reports/scoring';
7+
import { EnrichedScoredGroup, ScoredReport } from '../../src/lib/reports/utils';
98

109
function groupRefToScore(audits: AuditReport[]) {
1110
return (ref: GroupRef) => {

packages/utils/perf/score-report/optimized1.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */
22
// Note: The plugins of the ScoredReport are not structured correctly, hence the ESLint disables.
33
import { Report } from '@code-pushup/models';
4-
import { ScoredReport } from '../../src';
4+
import { GroupRefInvalidError } from '../../src/lib/reports/scoring';
55
import {
6-
GroupRefInvalidError,
76
ScoredCategoryConfig,
8-
} from '../../src/lib/reports/scoring';
7+
ScoredReport,
8+
} from '../../src/lib/reports/utils';
99

1010
export function calculateScore<T extends { weight: number }>(
1111
refs: T[],

packages/utils/perf/score-report/optimized2.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-assignment */
22
// Note: The plugins of the ScoredReport are not structured correctly, hence the ESLint disables.
33
import { CategoryRef, GroupRef, Report } from '@code-pushup/models';
4-
import { ScoredReport } from '../../src';
4+
import { GroupRefInvalidError } from '../../src/lib/reports/scoring';
55
import {
6-
GroupRefInvalidError,
76
ScoredCategoryConfig,
8-
} from '../../src/lib/reports/scoring';
7+
ScoredReport,
8+
} from '../../src/lib/reports/utils';
99

1010
export function calculateScore<T extends { weight: number }>(
1111
refs: T[],

packages/utils/perf/score-report/optimized3.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,11 @@ import {
77
Report,
88
} from '@code-pushup/models';
99
import { ScoredReport } from '../../src';
10+
import { GroupRefInvalidError } from '../../src/lib/reports/scoring';
1011
import {
1112
EnrichedScoredGroup,
12-
GroupRefInvalidError,
1313
ScoredCategoryConfig,
14-
} from '../../src/lib/reports/scoring';
14+
} from '../../src/lib/reports/utils';
1515

1616
export function calculateScore<T extends { weight: number }>(
1717
refs: T[],

packages/utils/src/index.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -55,12 +55,13 @@ export { ProgressBar, getProgressBar } from './lib/progress';
5555
export { TERMINAL_WIDTH } from './lib/reports/constants';
5656
export { generateMdReport } from './lib/reports/generate-md-report';
5757
export { generateStdoutSummary } from './lib/reports/generate-stdout-summary';
58-
export { ScoredReport, scoreReport } from './lib/reports/scoring';
58+
export { scoreReport } from './lib/reports/scoring';
5959
export { sortReport } from './lib/reports/sorting';
6060
export {
6161
CODE_PUSHUP_DOMAIN,
6262
FOOTER_PREFIX,
6363
README_LINK,
64+
ScoredReport,
6465
calcDuration,
6566
compareIssueSeverity,
6667
loadReport,

packages/utils/src/lib/reports/__snapshots__/generate-md-report.integration.test.ts.snap

+6-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ exports[`generateMdReport > should contain all sections when using the fixture r
55
66
|🏷 Category|⭐ Score|🛡 Audits|
77
|:--|:--:|:--:|
8-
|[Performance](#performance)|🟢 **92**|6|
8+
|[Performance](#performance)|🟡 **74**|8|
99
|[Bug prevention](#bug-prevention)|🟡 **68**|16|
1010
|[Code style](#code-style)|🟡 **54**|13|
1111
@@ -15,14 +15,18 @@ exports[`generateMdReport > should contain all sections when using the fixture r
1515
1616
Performance metrics [📖 Docs](https://developers.google.com/web/fundamentals/performance)
1717
18-
🟢 Score: **92**
18+
🟡 Score: **74**
1919
- 🟢 Performance (_Lighthouse_)
2020
- 🟩 [Total Blocking Time](#total-blocking-time-lighthouse) - **0 ms**
2121
- 🟨 [Largest Contentful Paint](#largest-contentful-paint-lighthouse) - **1.5 s**
2222
- 🟩 [Cumulative Layout Shift](#cumulative-layout-shift-lighthouse) - **0**
2323
- 🟨 [First Contentful Paint](#first-contentful-paint-lighthouse) - **1.2 s**
2424
- 🟩 [Speed Index](#speed-index-lighthouse) - **1.2 s**
2525
26+
- 🔴 ESLint performance rules (_ESLint_)
27+
- 🟥 [Disallow unused variables](#disallow-unused-variables-eslint) - **1 warning**
28+
- 🟥 [Enforce a maximum number of lines of code in a function](#enforce-a-maximum-number-of-lines-of-code-in-a-function-eslint) - **1 warning**
29+
2630
- 🟥 [Disallow missing \`key\` props in iterators/collection literals](#disallow-missing-key-props-in-iterators-collection-literals-eslint) (_ESLint_) - **1 warning**
2731
2832
### Bug prevention

packages/utils/src/lib/reports/__snapshots__/generate-stdout-summary.integration.test.ts.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ Categories
7878
┌─────────────────────────────────────────────────────────────┬───────┬────────┐
7979
│ Category │ Score │ Audits │
8080
├─────────────────────────────────────────────────────────────┼───────┼────────┤
81-
│ Performance │ 926
81+
│ Performance │ 748
8282
├─────────────────────────────────────────────────────────────┼───────┼────────┤
8383
│ Bug prevention │ 68 │ 16 │
8484
├─────────────────────────────────────────────────────────────┼───────┼────────┤

packages/utils/src/lib/reports/__snapshots__/sorting.integration.test.ts.snap

+18
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,12 @@ exports[`sortReport > should sort the audits and audit groups in categories, plu
4242
"type": "audit",
4343
"weight": 1,
4444
},
45+
{
46+
"plugin": "eslint",
47+
"slug": "typescript-eslint-extra",
48+
"type": "group",
49+
"weight": 0,
50+
},
4551
{
4652
"plugin": "eslint",
4753
"slug": "eslint-cypress",
@@ -207,6 +213,18 @@ exports[`sortReport > should sort the audits and audit groups in categories, plu
207213
"slug": "typescript-eslint",
208214
"title": "TypeScript ESLint",
209215
},
216+
{
217+
"plugin": "eslint",
218+
"refs": [
219+
{
220+
"slug": "typescript-eslint-experimental",
221+
"weight": 1,
222+
},
223+
],
224+
"score": 0,
225+
"slug": "typescript-eslint-extra",
226+
"title": "TypeScript ESLint Extra",
227+
},
210228
],
211229
"icon": "eslint",
212230
"slug": "eslint",

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,10 @@ import {
1515
} from './md';
1616
import {
1717
EnrichedScoredGroupWithAudits,
18-
ScoredReport,
19-
WeighedAuditReport,
20-
} from './scoring';
21-
import {
2218
FOOTER_PREFIX,
2319
README_LINK,
20+
ScoredReport,
21+
WeighedAuditReport,
2422
countCategoryAudits,
2523
detailsTableHeaders,
2624
formatReportScore,
@@ -97,7 +95,7 @@ function reportToCategoriesSection(report: ScoredReport): string {
9795
const categoryDocs = getDocsAndDescription(category);
9896
const categoryMDItems = category.refs.reduce((refAcc, ref) => {
9997
if (ref.type === 'group') {
100-
const group = getGroupWithAudits(ref.slug, ref.plugin, plugins);
98+
const group = getGroupWithAudits(ref, plugins);
10199
const mdGroupItem = groupItemToCategorySection(group, plugins);
102100
return refAcc + mdGroupItem + NEW_LINE;
103101
} else {

packages/utils/src/lib/reports/generate-stdout-summary.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ import cliui from '@isaacs/cliui';
22
import chalk from 'chalk';
33
import CliTable3 from 'cli-table3';
44
import { NEW_LINE, SCORE_COLOR_RANGE, TERMINAL_WIDTH } from './constants';
5-
import { ScoredReport } from './scoring';
65
import {
76
CODE_PUSHUP_DOMAIN,
87
FOOTER_PREFIX,
8+
ScoredReport,
99
countCategoryAudits,
1010
formatReportScore,
1111
reportHeadlineText,

packages/utils/src/lib/reports/scoring.ts

+1-22
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,11 @@
11
import {
22
AuditReport,
3-
CategoryConfig,
43
CategoryRef,
5-
Group,
64
GroupRef,
7-
PluginReport,
85
Report,
96
} from '@code-pushup/models';
107
import { deepClone } from '../transform';
11-
12-
export type WeighedAuditReport = AuditReport & { weight: number };
13-
export type EnrichedScoredGroupWithAudits = EnrichedScoredGroup & {
14-
audits: AuditReport[];
15-
};
16-
export type ScoredCategoryConfig = CategoryConfig & { score: number };
17-
18-
export type EnrichedScoredGroup = Group & {
19-
plugin: string;
20-
score: number;
21-
};
22-
23-
export type ScoredReport = Omit<Report, 'plugins' | 'categories'> & {
24-
plugins: (Omit<PluginReport, 'audits' | 'groups'> & {
25-
audits: AuditReport[];
26-
groups: EnrichedScoredGroup[];
27-
})[];
28-
categories: ScoredCategoryConfig[];
29-
};
8+
import { EnrichedScoredGroup, ScoredReport } from './utils';
309

3110
export class GroupRefInvalidError extends Error {
3211
constructor(auditSlug: string, pluginSlug: string) {

packages/utils/src/lib/reports/sorting.ts

+10-15
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
import { AuditReport, CategoryRef, PluginReport } from '@code-pushup/models';
22
import {
33
EnrichedScoredGroup,
4-
EnrichedScoredGroupWithAudits,
54
ScoredReport,
65
WeighedAuditReport,
7-
} from './scoring';
8-
import {
6+
WeighedScoredGroup,
97
compareAudits,
10-
compareCategoryAudits,
8+
compareCategoryAuditsAndGroups,
119
compareIssues,
1210
getAuditByRef,
1311
getGroupWithAudits,
@@ -20,34 +18,31 @@ export function sortReport(report: ScoredReport): ScoredReport {
2018
(
2119
acc: {
2220
audits: WeighedAuditReport[];
23-
groups: EnrichedScoredGroupWithAudits[];
21+
groups: WeighedScoredGroup[];
2422
},
2523
ref: CategoryRef,
2624
) => ({
2725
...acc,
2826
...(ref.type === 'group'
2927
? {
30-
groups: [
31-
...acc.groups,
32-
getGroupWithAudits(ref.slug, ref.plugin, plugins),
33-
],
28+
groups: [...acc.groups, getGroupWithAudits(ref, plugins)],
3429
}
3530
: {
3631
audits: [...acc.audits, getAuditByRef(ref, plugins)],
3732
}),
3833
}),
3934
{ groups: [], audits: [] },
4035
);
41-
const sortedAuditsAndGroups = [
42-
...groups,
43-
...[...audits].sort(compareCategoryAudits),
44-
];
36+
const sortedAuditsAndGroups = [...audits, ...groups].sort(
37+
compareCategoryAuditsAndGroups,
38+
);
39+
4540
const sortedRefs = [...category.refs].sort((a, b) => {
4641
const aIndex = sortedAuditsAndGroups.findIndex(
47-
ref => ref.slug === a.slug,
42+
ref => ref.slug === a.slug && ref.plugin === a.plugin,
4843
);
4944
const bIndex = sortedAuditsAndGroups.findIndex(
50-
ref => ref.slug === b.slug,
45+
ref => ref.slug === b.slug && ref.plugin === b.plugin,
5146
);
5247
return aIndex - bIndex;
5348
});

packages/utils/src/lib/reports/utils.ts

+44-19
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
import { join } from 'node:path';
22
import {
33
AuditReport,
4+
CategoryConfig,
45
CategoryRef,
56
IssueSeverity as CliIssueSeverity,
67
Format,
78
Group,
89
Issue,
910
PersistConfig,
11+
PluginReport,
1012
Report,
1113
reportSchema,
1214
} from '@code-pushup/models';
@@ -16,11 +18,32 @@ import {
1618
readTextFile,
1719
} from '../file-system';
1820
import { SCORE_COLOR_RANGE } from './constants';
19-
import {
20-
EnrichedScoredGroupWithAudits,
21-
ScoredReport,
22-
WeighedAuditReport,
23-
} from './scoring';
21+
22+
export type WeighedScoredGroup = EnrichedScoredGroupWithAudits & {
23+
weight: number;
24+
};
25+
26+
export type WeighedAuditReport = AuditReport & {
27+
weight: number;
28+
plugin: string;
29+
};
30+
export type EnrichedScoredGroupWithAudits = EnrichedScoredGroup & {
31+
audits: AuditReport[];
32+
};
33+
export type ScoredCategoryConfig = CategoryConfig & { score: number };
34+
35+
export type EnrichedScoredGroup = Group & {
36+
plugin: string;
37+
score: number;
38+
};
39+
40+
export type ScoredReport = Omit<Report, 'plugins' | 'categories'> & {
41+
plugins: (Omit<PluginReport, 'audits' | 'groups'> & {
42+
audits: AuditReport[];
43+
groups: EnrichedScoredGroup[];
44+
})[];
45+
categories: ScoredCategoryConfig[];
46+
};
2447

2548
export const FOOTER_PREFIX = 'Made with ❤ by'; // replace ❤️ with ❤, because of ❤️ has output issues
2649
export const CODE_PUSHUP_DOMAIN = 'code-pushup.dev';
@@ -152,44 +175,46 @@ export function getAuditByRef(
152175
return {
153176
...audit,
154177
weight,
178+
plugin,
155179
};
156180
}
157181

158182
export function getGroupWithAudits(
159-
refSlug: string,
160-
refPlugin: string,
183+
ref: CategoryRef,
161184
plugins: ScoredReport['plugins'],
162-
): EnrichedScoredGroupWithAudits {
163-
const plugin = plugins.find(({ slug }) => slug === refPlugin);
185+
): WeighedScoredGroup {
186+
const plugin = plugins.find(({ slug }) => slug === ref.plugin);
164187
if (!plugin) {
165-
throwIsNotPresentError(`Plugin ${refPlugin}`, 'report');
188+
throwIsNotPresentError(`Plugin ${ref.plugin}`, 'report');
166189
}
167-
const groupWithAudits = plugin.groups?.find(({ slug }) => slug === refSlug);
190+
const groupWithAudits = plugin.groups?.find(({ slug }) => slug === ref.slug);
168191

169192
if (!groupWithAudits) {
170-
throwIsNotPresentError(`Group ${refSlug}`, plugin.slug);
193+
throwIsNotPresentError(`Group ${ref.slug}`, plugin.slug);
171194
}
172195
const groupAudits = groupWithAudits.refs.reduce<WeighedAuditReport[]>(
173-
(acc: WeighedAuditReport[], ref) => {
196+
(acc: WeighedAuditReport[], groupRef) => {
174197
const audit = getAuditByRef(
175-
{ ...ref, plugin: refPlugin, type: 'audit' },
198+
{ ...groupRef, plugin: ref.plugin, type: 'audit' },
176199
plugins,
177200
);
178201
return [...acc, audit];
179202
},
180203
[],
181204
);
182-
const audits = [...groupAudits].sort(compareCategoryAudits);
205+
const audits = [...groupAudits].sort(compareCategoryAuditsAndGroups);
183206

184207
return {
185208
...groupWithAudits,
186209
audits,
210+
weight: ref.weight,
211+
plugin: ref.plugin,
187212
};
188213
}
189214

190-
export function compareCategoryAudits(
191-
a: WeighedAuditReport,
192-
b: WeighedAuditReport,
215+
export function compareCategoryAuditsAndGroups(
216+
a: WeighedAuditReport | WeighedScoredGroup,
217+
b: WeighedAuditReport | WeighedScoredGroup,
193218
): number {
194219
if (a.weight !== b.weight) {
195220
return b.weight - a.weight;
@@ -199,7 +224,7 @@ export function compareCategoryAudits(
199224
return a.score - b.score;
200225
}
201226

202-
if (a.value !== b.value) {
227+
if ('value' in a && 'value' in b && a.value !== b.value) {
203228
return b.value - a.value;
204229
}
205230

0 commit comments

Comments
 (0)