diff --git a/src/action.ts b/src/action.ts index e72d1ff..acf8193 100644 --- a/src/action.ts +++ b/src/action.ts @@ -41,6 +41,8 @@ export const run = async (inputs: Inputs, octokit: Octokit, context: Context): P excludePatterns, baseSha: shas?.baseSha, headSha: shas?.headSha, + maxCharacters: 65536, + numberOfSurroundingLines: 1, }, actionLogger, ) diff --git a/src/cli.ts b/src/cli.ts index 9fafd30..c06348e 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -114,7 +114,7 @@ async function main(): Promise { excludePatterns, baseSha, headSha, - maxCharacters: 1_000_000 + numberOfSurroundingLines: 2, }, cliLogger, ) diff --git a/src/core/process-coverage.ts b/src/core/process-coverage.ts index eef1eed..5afb153 100644 --- a/src/core/process-coverage.ts +++ b/src/core/process-coverage.ts @@ -7,7 +7,7 @@ import { type FileCoverage, type PackageCoverage, } from '../coverage/index.js' -import { type ChangedLinesMap, filterByChangedLines, filterByGlob, getChangedLinesFromGit } from '../filter/index.js' +import { type ChangedLinesMap, filterByGlob, getChangedLinesFromGit } from '../filter/index.js' import { generateMarkdown } from '../markdown/index.js' /** @@ -50,9 +50,9 @@ export type ProcessCoverageInputs = { baseSha?: string | undefined /** Explicit head commit SHA for comparison */ headSha?: string | undefined - /** Number of lines to show before and after uncovered lines (default: 1) */ - numberOfSurroundingLines?: number | undefined - /** Maximum number of characters in the output (default: 65536, minimum: 900) */ + /** Number of lines to show before and after uncovered lines */ + numberOfSurroundingLines: number + /** Maximum number of characters in the output (minimum: 900) */ maxCharacters?: number | undefined } @@ -138,24 +138,22 @@ export async function processCoverage( const globFilteredPackages: PackageCoverage[] = filterByGlob(mergedPackages, inputs.excludePatterns, logger) const overallMetrics = CoberturaCoverageParser.calculatePackageCoverage(globFilteredPackages) logger.info( - `Calculated overall metrics (LineCoverage: ${overallMetrics.lineCoverage}, BranchCoverage: ${overallMetrics.branchCoverage})`, + `Calculated overall metrics (LineCoverage: ${overallMetrics.lineCoverage}, BranchCoverage: ${overallMetrics.branchCoverage})`, ) // Filter git changes - const fileFilteredPackages = changedLinesPerFileMap - ? filterByChangedLines(globFilteredPackages, changedLinesPerFileMap, logger) - : globFilteredPackages - const prMetrics = CoberturaCoverageParser.calculatePackageCoverage(fileFilteredPackages) + const prMetrics = CoberturaCoverageParser.calculatePackageCoverage(globFilteredPackages, changedLinesPerFileMap) logger.info( - `Calculated PR metrics (LineCoverage: ${prMetrics.lineCoverage}, BranchCoverage: ${prMetrics.branchCoverage})`, + `Calculated PR metrics (LineCoverage: ${prMetrics.lineCoverage}, BranchCoverage: ${prMetrics.branchCoverage})`, ) // Read file contents from disk using resolved paths - const fileContents = await readFileContents(fileFilteredPackages) + const fileContents = await readFileContents(globFilteredPackages, changedLinesPerFileMap) // Generate Markdown from filtered report const markdown = generateMarkdown( - fileFilteredPackages, + globFilteredPackages, + changedLinesPerFileMap, fileContents, overallMetrics, { maxCharacters: inputs.maxCharacters, numberOfSurroundingLines: inputs.numberOfSurroundingLines }, @@ -252,8 +250,12 @@ async function mergeReportAndResolveSources( * Files without resolvedPath or that can't be read are skipped. * * @param packages - Coverage packages with files containing resolvedPath + * @param changedLinesMap - The map which contains the lines to render */ -async function readFileContents(packages: PackageCoverage[]): Promise> { +async function readFileContents( + packages: PackageCoverage[], + changedLinesMap: ChangedLinesMap | undefined, +): Promise> { const contents = new Map() for (const pkg of packages) { @@ -261,6 +263,10 @@ async function readFileContents(packages: PackageCoverage[]): Promise x.files.flatMap(xx => xx.lines)) + public static calculatePackageCoverage( + packages: PackageCoverage[], + changedLinesMap: ChangedLinesMap | undefined = undefined + ): PercentageCoverageMetrics { + const lines = packages.flatMap(x => x.files.flatMap(xx => { + if (!xx.resolvedPath) + return xx.lines + const changedLines = changedLinesMap?.get(xx.resolvedPath) + if (!changedLines) { + return xx.lines + } + if (changedLines.size === 0) { + return [] + } + return xx.lines.filter(xxx => changedLines.has(xxx.lineNumber)) + })) return CoberturaCoverageParser.calculateCoverage(lines) } } diff --git a/src/filter/filter.ts b/src/filter/filter.ts index fd4d953..7a1b3bb 100644 --- a/src/filter/filter.ts +++ b/src/filter/filter.ts @@ -1,8 +1,7 @@ import * as path from 'node:path' import type { Logger } from '../core/index.js' import { CoberturaCoverageParser } from '../coverage/index.js' -import type { FileCoverage, PackageCoverage } from '../coverage/model.js' -import type { ChangedLinesMap } from './model.js' +import type { PackageCoverage } from '../coverage/model.js' /** * Filter coverage packages to exclude files matching any of the provided glob patterns. @@ -53,59 +52,3 @@ export function filterByGlob(packages: PackageCoverage[], patterns: string[], lo return filteredPackages } - -/** - * Filter coverage packages to only include lines that were changed. - * Files without a resolvedPath are included without filtering. - */ -export function filterByChangedLines( - packages: PackageCoverage[], - changedLines: ChangedLinesMap, - logger: Logger, -): PackageCoverage[] { - const changedFilePaths = Array.from(changedLines.keys()) - logger.debug?.(`Filtering against changed files ${JSON.stringify(changedFilePaths)}`) - - const totalFilesBefore = packages.reduce((sum, pkg) => sum + pkg.files.length, 0) - - const filteredPackages = packages - .map((pkg): PackageCoverage => { - const files = pkg.files - .map((file) => { - // If no resolvedPath, include file without filtering - if (!file.resolvedPath) { - return file - } - return filterFileLines(file, changedLines.get(file.resolvedPath)) - }) - .filter((file) => file.lines.length > 0) - return { - name: pkg.name, - files: files, - coverage: CoberturaCoverageParser.calculateFileCoverage(files), - } - }) - .filter((pkg) => pkg.files.length > 0) - - const totalFilesAfter = filteredPackages.reduce((sum, pkg) => sum + pkg.files.length, 0) - logger.info(`Filtered ${totalFilesAfter}/${totalFilesBefore} files against changed files`) - - return filteredPackages -} - -/** - * Filter a file's coverage to only include specified lines. - */ -function filterFileLines(file: FileCoverage, changedLineNumbers: Set | undefined): FileCoverage { - if (!changedLineNumbers || changedLineNumbers.size === 0) { - return { ...file, lines: [], coverage: CoberturaCoverageParser.calculateCoverage([]) } - } - - const filteredLines = file.lines.filter((line) => changedLineNumbers.has(line.lineNumber)) - - return { - ...file, - lines: filteredLines, - coverage: CoberturaCoverageParser.calculateCoverage(filteredLines), - } -} diff --git a/src/filter/index.ts b/src/filter/index.ts index 1369d5c..87b72d6 100644 --- a/src/filter/index.ts +++ b/src/filter/index.ts @@ -1,3 +1,3 @@ export { getChangedLinesFromGit, parseDiffOutput, parsePatchForChangedLines } from './changed-lines.js' -export { filterByChangedLines, filterByGlob } from './filter.js' +export { filterByGlob } from './filter.js' export type { ChangedLinesMap, FileChangedLines } from './model.js' diff --git a/src/markdown/generator.ts b/src/markdown/generator.ts index af7363f..47346c3 100644 --- a/src/markdown/generator.ts +++ b/src/markdown/generator.ts @@ -1,6 +1,8 @@ +import assert from 'node:assert' import type { Logger } from '../core/index.js' import { CoberturaCoverageParser } from '../coverage/index.js' import type { FileCoverage, LineCoverage, PackageCoverage, PercentageCoverageMetrics } from '../coverage/model.js' +import type { ChangedLinesMap } from '../filter/index.js' // ============================================================================= // CONSTANTS @@ -21,11 +23,8 @@ const FILE_STATUS_ICONS = { partialCoverage: '🟠', } as const -/** Default maximum number of surrounding lines around an uncovered line */ -export const DEFAULT_MAX_NUMBER_OF_SURROUNDING_LINES = 1 - /** Default maximum characters for markdown output */ -export const DEFAULT_MAX_CHARACTERS = 65536 +export const DEFAULT_MAX_CHARACTERS = 10_000_000 /** Minimum characters required for meaningful markdown output (badges + legend + notice) */ export const MINIMUM_CHARACTERS = 900 @@ -36,10 +35,10 @@ export const MINIMUM_CHARACTERS = 900 /** Options for markdown generation */ export type MarkdownOptions = { - /** Number of lines to show before and after uncovered lines (default: 1) */ - numberOfSurroundingLines?: number | undefined - /** Maximum number of characters in the output (default: 65536, minimum: 900) */ - maxCharacters?: number | undefined + /** Number of lines to show before and after uncovered lines */ + numberOfSurroundingLines: number + /** Maximum number of characters in the output (minimum: 900) */ + maxCharacters: number | undefined } /** Data structure for a package section with its files */ @@ -75,6 +74,7 @@ type FileCoverageClassification = { * This is a pure function suitable for snapshot testing. * * @param packages - Array of packages + * @param changedLinesMap - The changed lines information * @param fileContents - Map of resolved (absolute) path to array of line contents * @param overallMetrics - The overall percentage metrics * @param options - Optional configuration for Markdown generation @@ -84,12 +84,13 @@ type FileCoverageClassification = { */ export function generateMarkdown( packages: PackageCoverage[], + changedLinesMap: ChangedLinesMap | undefined, fileContents: Map, overallMetrics: PercentageCoverageMetrics, - options: MarkdownOptions = {}, + options: MarkdownOptions, logger: Logger, ): string { - const numberOfSurroundingLines = options.numberOfSurroundingLines ?? DEFAULT_MAX_NUMBER_OF_SURROUNDING_LINES + const numberOfSurroundingLines = options.numberOfSurroundingLines const maxCharacters = options.maxCharacters ?? DEFAULT_MAX_CHARACTERS // Validate minimum character limit @@ -108,7 +109,7 @@ export function generateMarkdown( const legend = generateLegend() // Step 2: Build package section data - const packageSections = buildPackageSections(packages, fileContents, numberOfSurroundingLines) + const packageSections = buildPackageSections(packages, changedLinesMap, fileContents, numberOfSurroundingLines) // Step 3: Sort packages sortPackages(packageSections) @@ -204,13 +205,14 @@ function formatPercentOrNaFromRation(covered: number, total: number): string { */ function buildPackageSections( packages: PackageCoverage[], + changedLinesMap: ChangedLinesMap | undefined, fileContents: Map, numberOfSurroundingLines: number, ): PackageSectionData[] { const sections: PackageSectionData[] = [] for (const pkg of packages) { - const sectionData = buildPackageSectionData(pkg, fileContents, numberOfSurroundingLines) + const sectionData = buildPackageSectionData(pkg, changedLinesMap, fileContents, numberOfSurroundingLines) if (sectionData !== null) { sections.push(sectionData) } @@ -225,6 +227,7 @@ function buildPackageSections( */ function buildPackageSectionData( pkg: PackageCoverage, + changedLinesMap: ChangedLinesMap | undefined, fileContents: Map, numberOfSurroundingLines: number, ): PackageSectionData | null { @@ -235,12 +238,13 @@ function buildPackageSectionData( const files: FileSectionData[] = [] for (const file of pkg.files) { + const changedLines = file.resolvedPath ? changedLinesMap?.get(file.resolvedPath) : undefined const content = file.resolvedPath ? (fileContents.get(file.resolvedPath) ?? []) : [] const classification = classifyFileCoverage(file) files.push({ filename: file.filename, - content: renderFileSection(file, content, numberOfSurroundingLines, classification), + content: renderFileSection(file, changedLines, content, numberOfSurroundingLines, classification), uncoveredLines: file.coverage.totalLines - file.coverage.linesCovered, partialBranches: file.coverage.totalBranches - file.coverage.branchesCovered, }) @@ -357,7 +361,8 @@ function buildMarkdownWithinLimitFileLevel( // Process packages and files packageLoop: for (let p = 0; p < packageSections.length; p++) { - const pkg = packageSections[p]! + const pkg = packageSections[p] + assert(pkg) // Try to include package header if (!budget.tryAppend(`${pkg.header}\n`)) { @@ -496,6 +501,7 @@ function getBadgeColor(percent: number): string { */ function renderFileSection( file: FileCoverage, + linesToRender: Set | undefined, fileLines: string[], numberOfSurroundingLines: number, classification: FileCoverageClassification, @@ -521,7 +527,7 @@ function renderFileSection( const extension = getFileExtension(file.filename) lines.push(`\`\`\`${extension}`) - lines.push(renderAnnotatedLines(file.lines, fileLines, numberOfSurroundingLines)) + lines.push(renderAnnotatedLines(file.lines, linesToRender, fileLines, numberOfSurroundingLines)) lines.push('```') lines.push('') @@ -573,6 +579,7 @@ function getFileExtension(filename: string): string { */ function renderAnnotatedLines( coverageLines: LineCoverage[], + linesToRender: Set | undefined, fileLines: string[], numberOfSurroundingLines: number, ): string { @@ -592,9 +599,13 @@ function renderAnnotatedLines( const interestingLineNumbers = new Set() for (const line of sortedLines) { const branchesCovered = line.branchesCovered === line.totalBranches - if (!line.covered || !branchesCovered) { - interestingLineNumbers.add(line.lineNumber) + if (line.covered && branchesCovered) { + continue + } + if (linesToRender && !linesToRender.has(line.lineNumber)) { + continue } + interestingLineNumbers.add(line.lineNumber) } // Expand to include context lines around interesting lines diff --git a/tests/filter/filter.test.ts b/tests/filter/filter.test.ts index 020c922..01a22b2 100644 --- a/tests/filter/filter.test.ts +++ b/tests/filter/filter.test.ts @@ -1,9 +1,7 @@ -import assert from 'node:assert' import { describe, expect, it } from 'vitest' import { createCliLogger, type Logger } from '../../src/core/process-coverage.js' import type { PackageCoverage } from '../../src/coverage/model.js' -import { filterByChangedLines, filterByGlob } from '../../src/filter/index.js' -import type { ChangedLinesMap } from '../../src/filter/model.js' +import { filterByGlob } from '../../src/filter/index.js' /** Mock logger that does nothing */ const mockLogger: Logger = createCliLogger(true) @@ -204,172 +202,3 @@ describe('filterByGlob', () => { expect(result[0]?.files[0]?.filename).toBe('src/no-path.ts') }) }) - -describe('filterByChangedLines', () => { - const sampleReport: PackageCoverage[] = [ - { - name: 'Package1', - files: [ - { - filename: 'src/file1.ts', - resolvedPath: '/repo/src/file1.ts', - lines: [ - { lineNumber: 1, covered: true, branchesCovered: 0, totalBranches: 0 }, - { lineNumber: 2, covered: false, branchesCovered: 0, totalBranches: 0 }, - { lineNumber: 3, covered: true, branchesCovered: 0, totalBranches: 0 }, - { lineNumber: 4, covered: true, branchesCovered: 1, totalBranches: 2 }, - { lineNumber: 5, covered: true, branchesCovered: 0, totalBranches: 0 }, - ], - coverage: { - linesCovered: 4, - totalLines: 5, - branchesCovered: 1, - totalBranches: 2, - lineCoverage: 0.8, - branchCoverage: 0.5, - }, - }, - { - filename: 'src/file2.ts', - resolvedPath: '/repo/src/file2.ts', - lines: [ - { lineNumber: 1, covered: true, branchesCovered: 0, totalBranches: 0 }, - { lineNumber: 2, covered: true, branchesCovered: 0, totalBranches: 0 }, - ], - coverage: { - linesCovered: 2, - totalLines: 2, - branchesCovered: 0, - totalBranches: 0, - lineCoverage: 1, - branchCoverage: undefined, - }, - }, - ], - coverage: { - linesCovered: 6, - totalLines: 7, - branchesCovered: 1, - totalBranches: 2, - lineCoverage: 6 / 7, - branchCoverage: 0.5, - }, - }, - ] - - it('filters lines to only those that were changed', () => { - const changedLines: ChangedLinesMap = new Map([['/repo/src/file1.ts', new Set([2, 4])]]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - expect(result).toHaveLength(1) - expect(result[0]?.files).toHaveLength(1) - - const file = result[0]?.files[0] - assert(file) - expect(file.filename).toBe('src/file1.ts') - expect(file.lines).toHaveLength(2) - expect(file.lines.map((l) => l.lineNumber)).toEqual([2, 4]) - }) - - it('recalculates line metrics based on filtered lines', () => { - const changedLines: ChangedLinesMap = new Map([['/repo/src/file1.ts', new Set([1, 2, 3])]]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - const file = result[0]?.files[0] - assert(file) - expect(file.coverage.linesCovered).toBe(2) // lines 1 and 3 are covered - expect(file.coverage.totalLines).toBe(3) // 3 lines total - }) - - it('preserves branch metrics from original file', () => { - const changedLines: ChangedLinesMap = new Map([['/repo/src/file1.ts', new Set([1, 2])]]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - const file = result[0]?.files[0] - assert(file) - expect(file.coverage.branchesCovered).toBe(0) // line 1 has no branches, line 2 has no branches - expect(file.coverage.totalBranches).toBe(0) // no branches in filtered lines - }) - - it('excludes files with no changed lines info', () => { - const changedLines: ChangedLinesMap = new Map([['/repo/src/file1.ts', new Set([1])]]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - expect(result[0]?.files).toHaveLength(1) - expect(result[0]?.files[0]?.filename).toBe('src/file1.ts') - }) - - it('excludes files with empty changed lines set', () => { - const changedLines: ChangedLinesMap = new Map([ - ['/repo/src/file1.ts', new Set([1])], - ['/repo/src/file2.ts', new Set()], - ]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - expect(result[0]?.files).toHaveLength(1) - }) - - it('removes packages with no files after filtering', () => { - const changedLines: ChangedLinesMap = new Map([['/repo/nonexistent.ts', new Set([1])]]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - expect(result).toHaveLength(0) - }) - - it('removes files with no lines after filtering', () => { - const changedLines: ChangedLinesMap = new Map([['/repo/src/file1.ts', new Set([100])]]) - - const result = filterByChangedLines(sampleReport, changedLines, mockLogger) - - expect(result).toHaveLength(0) - }) - - it('includes files without resolvedPath without filtering', () => { - const reportWithMissingPath: PackageCoverage[] = [ - { - name: 'Package1', - files: [ - { - filename: 'src/no-path.ts', - resolvedPath: undefined, - lines: [ - { lineNumber: 1, covered: true, branchesCovered: 0, totalBranches: 0 }, - { lineNumber: 2, covered: false, branchesCovered: 0, totalBranches: 0 }, - ], - coverage: { - linesCovered: 1, - totalLines: 2, - branchesCovered: 0, - totalBranches: 0, - lineCoverage: 0.5, - branchCoverage: undefined, - }, - }, - ], - coverage: { - linesCovered: 1, - totalLines: 2, - branchesCovered: 0, - totalBranches: 0, - lineCoverage: 0.5, - branchCoverage: undefined, - }, - }, - ] - - const changedLines: ChangedLinesMap = new Map([['/repo/other-file.ts', new Set([1])]]) - - const result = filterByChangedLines(reportWithMissingPath, changedLines, mockLogger) - - // File without resolvedPath should be included with all its lines - expect(result).toHaveLength(1) - expect(result[0]?.files).toHaveLength(1) - expect(result[0]?.files[0]?.lines).toHaveLength(2) - }) -}) diff --git a/tests/integration/process-coverage.integration.test.ts b/tests/integration/process-coverage.integration.test.ts index 5eaee88..7bae704 100644 --- a/tests/integration/process-coverage.integration.test.ts +++ b/tests/integration/process-coverage.integration.test.ts @@ -13,6 +13,7 @@ describe('processCoverage integration', () => { filePatterns: [path.join(testDir, 'coverage.xml')], sourceDir: testDir, excludePatterns: [], + numberOfSurroundingLines: 1, }, createCliLogger(true), ) @@ -29,6 +30,7 @@ describe('processCoverage integration', () => { filePatterns: [path.join(testDir, 'coverage.xml')], sourceDir: testDir, excludePatterns: [], + numberOfSurroundingLines: 1, }, createCliLogger(true), ) @@ -45,6 +47,7 @@ describe('processCoverage integration', () => { filePatterns: [path.join(testDir, 'coverage.xml')], sourceDir: testDir, excludePatterns: ['**/exclude/**'], + numberOfSurroundingLines: 1, }, createCliLogger(true), ) @@ -66,6 +69,7 @@ describe('processCoverage integration', () => { filePatterns: [`${testDir}/coverage-a.xml`, `${testDir}/coverage-b.xml`], sourceDir: testDir, excludePatterns: [], + numberOfSurroundingLines: 1, }, createCliLogger(true), ) @@ -80,6 +84,7 @@ describe('processCoverage integration', () => { filePatterns: ['/nonexistent/**/*.xml'], sourceDir: '.', excludePatterns: [], + numberOfSurroundingLines: 1, }, createCliLogger(true), ) diff --git a/tests/markdown/generator.test.ts b/tests/markdown/generator.test.ts index 8288842..fcd7efd 100644 --- a/tests/markdown/generator.test.ts +++ b/tests/markdown/generator.test.ts @@ -1,8 +1,8 @@ import { describe, expect, it } from 'vitest' import { createCliLogger } from '../../src/core/process-coverage.js' +import { CoberturaCoverageParser } from '../../src/coverage/index.js' import type { PackageCoverage, PercentageCoverageMetrics } from '../../src/coverage/model.js' import { generateMarkdown, MINIMUM_CHARACTERS } from '../../src/markdown/index.js' -import { CoberturaCoverageParser } from '../../src/coverage/index.js' type FakeFileInfo = { resolvedPath: string @@ -68,9 +68,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/example.ts', numberOfLines: 10 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -114,12 +115,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/src/core/utils.cs', numberOfLines: 15 }, { resolvedPath: '/repo/tests/test_utils.cs', numberOfLines: 10 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -152,9 +154,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/gaps.rs', numberOfLines: 50 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -173,9 +176,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -213,12 +217,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/src/file1.py', numberOfLines: 3 }, { resolvedPath: '/repo/src/file2.py', numberOfLines: 6 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -255,13 +260,14 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/test.cs', numberOfLines: 1 }, { resolvedPath: '/repo/test.rs', numberOfLines: 2 }, { resolvedPath: '/repo/test.tsx', numberOfLines: 3 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -293,9 +299,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/test.ts', numberOfLines: 10 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -325,9 +332,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/test.ts', numberOfLines: 10 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -359,9 +367,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/test.ts', numberOfLines: 5 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -395,9 +404,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/test.ts', numberOfLines: 15 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -428,9 +438,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/test.ts', numberOfLines: 6 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -461,9 +472,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/test.ts', numberOfLines: 5 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -496,9 +508,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, fileContents, CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -528,9 +541,10 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/src/short.ts', numberOfLines: 3 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -558,9 +572,11 @@ describe('generateMarkdown', () => { expect(() => generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/a.ts', numberOfLines: 1 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), { + numberOfSurroundingLines: 1, maxCharacters: 100, }, logger, @@ -586,9 +602,11 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/small.ts', numberOfLines: 2 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), { + numberOfSurroundingLines: 1, maxCharacters: 2000, }, logger, @@ -628,13 +646,17 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/file1.ts', numberOfLines: 2 }, { resolvedPath: '/repo/file2.ts', numberOfLines: 2 }, { resolvedPath: '/repo/file3.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - { maxCharacters: 1000 }, + { + numberOfSurroundingLines: 1, + maxCharacters: 1000, + }, logger, ) @@ -688,13 +710,17 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/pkg1/a.ts', numberOfLines: 5 }, { resolvedPath: '/repo/pkg2/b.ts', numberOfLines: 2 }, { resolvedPath: '/repo/pkg3/c.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - { maxCharacters: 900 }, + { + numberOfSurroundingLines: 1, + maxCharacters: 900, + }, logger, ) @@ -740,6 +766,7 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/file1.ts', numberOfLines: 2 }, { resolvedPath: '/repo/file2.ts', numberOfLines: 2 }, @@ -747,7 +774,10 @@ describe('generateMarkdown', () => { { resolvedPath: '/repo/file4.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - { maxCharacters: 1000 }, + { + numberOfSurroundingLines: 1, + maxCharacters: 1000, + }, logger, ) @@ -778,9 +808,10 @@ describe('generateMarkdown', () => { // Should not throw and should not truncate small content const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([{ resolvedPath: '/repo/test.ts', numberOfLines: 2 }]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -825,12 +856,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/low.ts', numberOfLines: 2 }, { resolvedPath: '/repo/high.ts', numberOfLines: 4 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -870,12 +902,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/low.ts', numberOfLines: 2 }, { resolvedPath: '/repo/high.ts', numberOfLines: 3 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -912,12 +945,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/zebra.ts', numberOfLines: 2 }, { resolvedPath: '/repo/alpha.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -950,12 +984,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/uncovered.ts', numberOfLines: 2 }, { resolvedPath: '/repo/covered.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -990,12 +1025,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/low-uncovered.ts', numberOfLines: 2 }, { resolvedPath: '/repo/high-uncovered.ts', numberOfLines: 4 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -1029,12 +1065,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/low-partial.ts', numberOfLines: 2 }, { resolvedPath: '/repo/high-partial.ts', numberOfLines: 3 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -1065,12 +1102,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/zebra.ts', numberOfLines: 2 }, { resolvedPath: '/repo/alpha.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -1116,6 +1154,7 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/zebra.ts', numberOfLines: 2 }, { resolvedPath: '/repo/covered.ts', numberOfLines: 2 }, @@ -1123,7 +1162,7 @@ describe('generateMarkdown', () => { { resolvedPath: '/repo/alpha.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, ) @@ -1154,12 +1193,13 @@ describe('generateMarkdown', () => { const markdown = generateMarkdown( packages, + undefined, createFakeFileContents([ { resolvedPath: '/repo/zebra.ts', numberOfLines: 2 }, { resolvedPath: '/repo/alpha.ts', numberOfLines: 2 }, ]), CoberturaCoverageParser.calculatePackageCoverage(packages), - {}, + { numberOfSurroundingLines: 1, maxCharacters: undefined }, logger, )