From b1c5dd7d7763141a872a9af8e1c9ba08650fa9c5 Mon Sep 17 00:00:00 2001 From: Michael Seredenko Date: Tue, 5 Dec 2023 08:54:55 +0100 Subject: [PATCH] feat(utils): add sorting of audit issues for report md Closes #313 #313 --- packages/utils/src/lib/report-to-md.ts | 3 +- packages/utils/src/lib/report.ts | 20 +++++++++++ packages/utils/src/lib/report.unit.test.ts | 42 +++++++++++++++++++++- 3 files changed, 63 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/lib/report-to-md.ts b/packages/utils/src/lib/report-to-md.ts index ed19c4a74..a3f057cec 100644 --- a/packages/utils/src/lib/report-to-md.ts +++ b/packages/utils/src/lib/report-to-md.ts @@ -34,6 +34,7 @@ import { reportHeadlineText, reportMetaTableHeaders, reportOverviewTableHeaders, + sortAuditIssues, sortAudits, sortCategoryAudits, } from './report'; @@ -216,7 +217,7 @@ function reportToAuditsSection(report: ScoredReport): string { const detailsTableData = [ detailsTableHeaders, - ...audit.details.issues.map((issue: Issue) => { + ...audit.details.issues.sort(sortAuditIssues).map((issue: Issue) => { const severity = `${getSeverityIcon(issue.severity)} ${ issue.severity }`; diff --git a/packages/utils/src/lib/report.ts b/packages/utils/src/lib/report.ts index 361a64ae4..d91918864 100644 --- a/packages/utils/src/lib/report.ts +++ b/packages/utils/src/lib/report.ts @@ -4,6 +4,7 @@ import { CategoryRef, IssueSeverity as CliIssueSeverity, Format, + Issue, PersistConfig, Report, reportSchema, @@ -278,3 +279,22 @@ export function getPluginNameFromSlug( plugins.find(({ slug: pluginSlug }) => pluginSlug === slug)?.title || slug ); } + +export function sortAuditIssues(a: Issue, b: Issue): number { + if (a.severity !== b.severity) { + return -compareIssueSeverity(a.severity, b.severity); + } + + if (a.source?.file !== b.source?.file) { + return a.source?.file.localeCompare(b.source?.file || '') || 0; + } + + if (a.source?.position?.startLine !== b.source?.position?.startLine) { + return ( + (a.source?.position?.startLine || 0) - + (b.source?.position?.startLine || 0) + ); + } + + return 0; +} diff --git a/packages/utils/src/lib/report.unit.test.ts b/packages/utils/src/lib/report.unit.test.ts index c41223f77..dec673186 100644 --- a/packages/utils/src/lib/report.unit.test.ts +++ b/packages/utils/src/lib/report.unit.test.ts @@ -1,6 +1,11 @@ import { vol } from 'memfs'; import { afterEach, describe, expect, it, vi } from 'vitest'; -import { CategoryRef, IssueSeverity, PluginReport } from '@code-pushup/models'; +import { + CategoryRef, + Issue, + IssueSeverity, + PluginReport, +} from '@code-pushup/models'; import { MEMFS_VOLUME, report } from '@code-pushup/models/testing'; import { calcDuration, @@ -8,6 +13,7 @@ import { countWeightedRefs, getPluginNameFromSlug, loadReport, + sortAuditIssues, sortAudits, sortCategoryAudits, } from './report'; @@ -223,3 +229,37 @@ describe('getPluginNameFromSlug', () => { expect(getPluginNameFromSlug('plugin-b', plugins)).toBe('Plugin B'); }); }); + +describe('sortAuditIssues', () => { + it('should sort issues by severity and source file', () => { + const mockIssues = [ + { severity: 'warning', source: { file: 'b' } }, + { severity: 'error', source: { file: 'c' } }, + { severity: 'error', source: { file: 'a' } }, + { severity: 'info', source: { file: 'b' } }, + ] as Issue[]; + const sortedIssues = [...mockIssues].sort(sortAuditIssues); + expect(sortedIssues).toEqual([ + { severity: 'error', source: { file: 'a' } }, + { severity: 'error', source: { file: 'c' } }, + { severity: 'warning', source: { file: 'b' } }, + { severity: 'info', source: { file: 'b' } }, + ]); + }); + + it('should sort issues by source file and source start line', () => { + const mockIssues = [ + { severity: 'info', source: { file: 'b', position: { startLine: 2 } } }, + { severity: 'info', source: { file: 'c', position: { startLine: 1 } } }, + { severity: 'info', source: { file: 'a', position: { startLine: 2 } } }, + { severity: 'info', source: { file: 'b', position: { startLine: 1 } } }, + ] as Issue[]; + const sortedIssues = [...mockIssues].sort(sortAuditIssues); + expect(sortedIssues).toEqual([ + { severity: 'info', source: { file: 'a', position: { startLine: 2 } } }, + { severity: 'info', source: { file: 'b', position: { startLine: 1 } } }, + { severity: 'info', source: { file: 'b', position: { startLine: 2 } } }, + { severity: 'info', source: { file: 'c', position: { startLine: 1 } } }, + ]); + }); +});