Skip to content

Commit

Permalink
Merge pull request #10 from darcy-rayner/feature/merge-multiple-summa…
Browse files Browse the repository at this point in the history
…ries

Feature/merge multiple summaries
  • Loading branch information
darcy-rayner authored Apr 21, 2018
2 parents 36775e2 + 41f116a commit c614656
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 17 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,8 @@ schedule(istanbulCoverage({

// The location of the istanbul coverage file.
coveragePath: "./coverage/coverage-summary.json",
// Alternatively, if you have multiple coverage summaries, you can merge them into one report
coveragePaths: ["./dir1/coverage-summary.json", "./dir2/coverage-summary.json"]

// Which set of files to summarise from the coverage file.
reportFileSet: "all", // || "modified" || "created" || "createdOrModified"
Expand Down
9 changes: 8 additions & 1 deletion src/config.model.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { makeCompleteConfiguration } from "./config.model"

describe("makeCompleteConfiguration", () => {
const base = {
coveragePath: "./coverage/coverage-summary.json",
coveragePaths: ["./coverage/coverage-summary.json"],
reportFileSet: "all",
reportMode: "message",
entrySortMethod: "alphabetically",
Expand All @@ -20,6 +20,13 @@ describe("makeCompleteConfiguration", () => {
expect(output).toEqual(base)
})

it("overrides coveragePaths with the value from coveragePath", () => {
const output = makeCompleteConfiguration({
coveragePath: "some-other-path",
})
expect(output).toEqual({ ...base, coveragePaths: ["some-other-path"] })
})

it("overrides a specific value from the default", () => {
const output = makeCompleteConfiguration({
reportMode: "warn",
Expand Down
12 changes: 9 additions & 3 deletions src/config.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@ export interface Config {
customFailureMessage?: string
numberOfEntries: number
entrySortMethod: SortMethod
coveragePath: string
coveragePath?: string
coveragePaths: string[]
reportFileSet: ReportFileSet
threshold: CoverageThreshold
reportMode: ReportMode
Expand All @@ -33,7 +34,7 @@ export interface Config {
*/
export function makeCompleteConfiguration(config?: Partial<Config>): Config {
const defaults: Config = {
coveragePath: "./coverage/coverage-summary.json",
coveragePaths: [],
reportFileSet: "all",
reportMode: "message",
entrySortMethod: "alphabetically",
Expand All @@ -45,5 +46,10 @@ export function makeCompleteConfiguration(config?: Partial<Config>): Config {
lines: 100,
},
}
return config ? { ...defaults, ...config } : defaults

const combined = config ? { ...defaults, ...config } : defaults
const coveragePath = combined.coveragePath ? combined.coveragePath : "./coverage/coverage-summary.json"
const coveragePaths = combined.coveragePaths.length === 0 ? [coveragePath] : combined.coveragePaths
delete combined.coveragePath
return { ...combined, coveragePaths }
}
47 changes: 40 additions & 7 deletions src/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@ function setupGitService() {
})
}

function setupCoverageFile(coverage?: string) {
function setupCoverageFile(coverages: string[] = []) {
;(FilesystemService as any).mockImplementation(() => {
return {
exists: p => coverage !== undefined,
exists: p => coverages.length !== 0,
read: p => {
const coverage = coverages.pop()
return coverage !== undefined ? Buffer.from(coverage, "utf8") : undefined
},
}
Expand All @@ -70,14 +71,16 @@ describe("istanbulCoverage()", () => {
},
}
setupGitService()
setupCoverageFile(`{
setupCoverageFile([
`{
${makeEntry("total", 50, 50, 50, 50)},
${makeEntry(`${__dirname}/src/modified-file1.ts`, 66, 25, 25, 25)},
${makeEntry(`${__dirname}/src/modified-file2.ts`, 99, 50, 75, 50)},
${makeEntry(`${__dirname}/src/created-file1.ts`, 66, 100, 25, 50)},
${makeEntry(`${__dirname}/src/created-file2.ts`, 99, 75, 50, 25)},
${makeEntry(`${__dirname}/src/unmodified-field.ts`, 25, 25, 25, 25)}
}`)
}`,
])
})

afterEach(() => {
Expand All @@ -103,6 +106,36 @@ Total | (165/200) 83% | (175/200) 88% | (75/200) 38% | (75/200) 38%
)
})

it("can combine multiple coverage files", async () => {
setupCoverageFile([
`{
${makeEntry("total", 50, 50, 50, 50)},
${makeEntry(`${__dirname}/src/modified-file1.ts`, 66, 25, 25, 25)},
${makeEntry(`${__dirname}/src/modified-file2.ts`, 99, 50, 75, 50)}
}`,
`{
${makeEntry("total", 50, 50, 50, 50)},
${makeEntry(`${__dirname}/src/created-file1.ts`, 66, 100, 25, 50)},
${makeEntry(`${__dirname}/src/created-file2.ts`, 99, 75, 50, 25)}
}`,
])
await istanbulCoverage({
reportFileSet: "createdOrModified",
coveragePaths: ["coverage-path-1", "coverage-path-2"],
})
expect(global.markdown).toHaveBeenCalledWith(
`## Coverage in Created or Modified Files
File | Line Coverage | Statement Coverage | Function Coverage | Branch Coverage
---- | ------------: | -----------------: | ----------------: | --------------:
[src/created\\-file1.ts](../blob/master/src/created\\-file1.ts) | (66/100) 66% | (100/100) 100% | (25/100) 25% | (50/100) 50%
[src/created\\-file2.ts](../blob/master/src/created\\-file2.ts) | (99/100) 99% | (75/100) 75% | (50/100) 50% | (25/100) 25%
[src/modified\\-file1.ts](../blob/master/src/modified\\-file1.ts) | (66/100) 66% | (25/100) 25% | (25/100) 25% | (25/100) 25%
[src/modified\\-file2.ts](../blob/master/src/modified\\-file2.ts) | (99/100) 99% | (50/100) 50% | (75/100) 75% | (50/100) 50%
Total | (330/400) 83% | (250/400) 63% | (175/400) 44% | (150/400) 38%
`
)
})

it('will only report on modified files when reportFileSet is set to "modified"', async () => {
await istanbulCoverage({
reportFileSet: "modified",
Expand Down Expand Up @@ -256,7 +289,7 @@ Total | (355/500) 71% | (275/500) 55% | (200/500) 40% | (175/500) 35%
expect(global.message).not.toBeCalled()
})
it("doesn't output anything when the coverage data is empty", async () => {
setupCoverageFile("{}")
setupCoverageFile(["{}"])
await istanbulCoverage({
reportMode: "fail",
})
Expand All @@ -265,14 +298,14 @@ Total | (355/500) 71% | (275/500) 55% | (200/500) 40% | (175/500) 35%
expect(global.message).not.toBeCalled()
})
it("outputs a warning when it can't find the coverage file", async () => {
setupCoverageFile(undefined)
setupCoverageFile([])
await istanbulCoverage({
reportMode: "warn",
})
expect(global.warn).toBeCalled()
})
it("outputs a warning when coverage file is invalidly formatted", async () => {
setupCoverageFile("{")
setupCoverageFile(["{"])
await istanbulCoverage({
reportMode: "fail",
})
Expand Down
27 changes: 21 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,21 +138,36 @@ File | Line Coverage | Statement Coverage | Function Coverage | Branch Coverage
return [header, ...lines, ellided, total, ""].filter(part => part !== undefined).join("\n")
}

function getCoveragePaths(coveragePaths: string[]): string[] {
return coveragePaths.map(singleCoveragePath => {
if (!process.mainModule) {
return singleCoveragePath
}
const appDir = `${process.mainModule.paths[0].split("node_modules")[0].slice(0, -1)}/`
return path.resolve(appDir, singleCoveragePath)
})
}

function getCombinedCoverageCollection(coveragePaths: string[]): CoverageCollection {
return coveragePaths
.map(coveragePath => {
const collection = parseCoverageCollection(coveragePath)
return collection ? collection : {}
})
.reduce((previous, current) => ({ ...previous, ...current }), {})
}

/**
* Danger.js plugin for monitoring code coverage on changed files.
*/
export function istanbulCoverage(config?: Partial<Config>): Promise<void> {
const combinedConfig = makeCompleteConfiguration(config)

let coveragePath = combinedConfig.coveragePath
if (process.mainModule) {
const appDir = `${process.mainModule.paths[0].split("node_modules")[0].slice(0, -1)}/`
const coveragePaths = getCoveragePaths(combinedConfig.coveragePaths)

coveragePath = path.resolve(appDir, combinedConfig.coveragePath)
}
let coverage: CoverageCollection
try {
const parsedCoverage = parseCoverageCollection(coveragePath)
const parsedCoverage = getCombinedCoverageCollection(coveragePaths)
if (!parsedCoverage) {
return Promise.resolve()
}
Expand Down

0 comments on commit c614656

Please sign in to comment.