Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 17 additions & 4 deletions lib/commands/check-coverage.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,18 +44,31 @@ exports.checkCoverages = async function (argv, report) {
}
const map = await report.getCoverageMapFromAllCoverageFiles()
if (argv.perFile) {
map.files().forEach(file => {
checkCoverage(map.fileCoverageFor(file).toSummary(), thresholds, file)
})
const files = map.files()
if (files.length === 0) {
// There is nothing to check per file. Fall back to the (empty) overall
// summary so that a non-zero threshold is still reported as unmet.
checkCoverage(map.getCoverageSummary(), thresholds)
} else {
files.forEach(file => {
checkCoverage(map.fileCoverageFor(file).toSummary(), thresholds, file)
})
}
} else {
checkCoverage(map.getCoverageSummary(), thresholds)
}
}

function checkCoverage (summary, thresholds, file) {
Object.keys(thresholds).forEach(key => {
const threshold = thresholds[key]
if (threshold === undefined) return
const coverage = summary[key].pct
if (coverage < thresholds[key]) {
// When there is nothing to measure, istanbul reports the string "Unknown"
// rather than a number. A string never compares as less than a number, so
// the check below would silently pass. Treat it as unmet whenever a
// threshold was actually requested (a threshold of 0 means "don't care").
if (coverage === 'Unknown' ? threshold > 0 : coverage < threshold) {
process.exitCode = 1
if (file) {
console.error(
Expand Down
63 changes: 62 additions & 1 deletion test/integration.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ beforeEach(function () {
const { output, status } = spawnSync(nodePath, [
c8Path,
'check-coverage',
'--exclude="test/fixtures/*.js"',
'--exclude="test/fixtures/all/**"',
'--temp-directory=tmp/check-coverage',
'--lines=70',
'--branches=55',
Expand Down Expand Up @@ -245,6 +245,67 @@ beforeEach(function () {
status.should.equal(1)
output.toString('utf8').should.matchSnapshot()
})

it('exits with 1 if there is no coverage data to check', () => {
const { output, status } = spawnSync(nodePath, [
c8Path,
'--exclude="test/*.js"',
'--temp-directory=tmp/check-coverage-empty',
'--clean=true',
'--lines=100',
'--branches=0',
'--functions=0',
'--statements=0',
'--check-coverage',
`--merge-async=${mergeAsync}`,
nodePath,
'-e',
'1'
])
status.should.equal(1)
output.toString('utf8').should.matchSnapshot()
})

it('exits with 1 if there is no coverage data to check per file', () => {
const { output, status } = spawnSync(nodePath, [
c8Path,
'--exclude="test/*.js"',
'--temp-directory=tmp/check-coverage-empty',
'--clean=true',
'--lines=100',
'--branches=0',
'--functions=0',
'--statements=0',
'--check-coverage',
'--per-file',
`--merge-async=${mergeAsync}`,
nodePath,
'-e',
'1'
])
status.should.equal(1)
output.toString('utf8').should.matchSnapshot()
})

it('exits with 0 if there is no coverage data but the threshold is 0', () => {
const { output, status } = spawnSync(nodePath, [
c8Path,
'--exclude="test/*.js"',
'--temp-directory=tmp/check-coverage-empty',
'--clean=true',
'--lines=0',
'--branches=0',
'--functions=0',
'--statements=0',
'--check-coverage',
`--merge-async=${mergeAsync}`,
nodePath,
'-e',
'1'
])
status.should.equal(0)
output.toString('utf8').should.matchSnapshot()
})
})

describe('report', () => {
Expand Down
58 changes: 58 additions & 0 deletions test/integration.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -296,12 +296,41 @@ ERROR: Coverage for statements (83.33%) does not meet global threshold (100%)

exports[`c8 check-coverage exits with 0 if coverage within threshold 1`] = `",,"`;

exports[`c8 check-coverage exits with 0 if there is no coverage data but the threshold is 0 1`] = `
",----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
,"
`;

exports[`c8 check-coverage exits with 1 if coverage is below threshold 1`] = `
",,ERROR: Coverage for lines (83.33%) does not meet global threshold (101%)
ERROR: Coverage for statements (83.33%) does not meet global threshold (95%)
"
`;

exports[`c8 check-coverage exits with 1 if there is no coverage data to check 1`] = `
",----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
,ERROR: Coverage for lines (Unknown%) does not meet global threshold (100%)
"
`;

exports[`c8 check-coverage exits with 1 if there is no coverage data to check per file 1`] = `
",----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
,ERROR: Coverage for lines (Unknown%) does not meet global threshold (100%)
"
`;

exports[`c8 cobertura report escapes special characters 1`] = `
"<?xml version=\\"1.0\\" ?>
<!DOCTYPE coverage SYSTEM \\"http://cobertura.sourceforge.net/xml/coverage-04.dtd\\">
Expand Down Expand Up @@ -662,12 +691,41 @@ ERROR: Coverage for statements (83.33%) does not meet global threshold (100%)

exports[`c8 mergeAsync check-coverage exits with 0 if coverage within threshold 1`] = `",,"`;

exports[`c8 mergeAsync check-coverage exits with 0 if there is no coverage data but the threshold is 0 1`] = `
",----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
,"
`;

exports[`c8 mergeAsync check-coverage exits with 1 if coverage is below threshold 1`] = `
",,ERROR: Coverage for lines (83.33%) does not meet global threshold (101%)
ERROR: Coverage for statements (83.33%) does not meet global threshold (95%)
"
`;

exports[`c8 mergeAsync check-coverage exits with 1 if there is no coverage data to check 1`] = `
",----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
,ERROR: Coverage for lines (Unknown%) does not meet global threshold (100%)
"
`;

exports[`c8 mergeAsync check-coverage exits with 1 if there is no coverage data to check per file 1`] = `
",----------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
----------|---------|----------|---------|---------|-------------------
All files | 0 | 0 | 0 | 0 |
----------|---------|----------|---------|---------|-------------------
,ERROR: Coverage for lines (Unknown%) does not meet global threshold (100%)
"
`;

exports[`c8 mergeAsync cobertura report escapes special characters 1`] = `
"<?xml version=\\"1.0\\" ?>
<!DOCTYPE coverage SYSTEM \\"http://cobertura.sourceforge.net/xml/coverage-04.dtd\\">
Expand Down