Skip to content

Commit

Permalink
feat: add support for per file coverage checking (#591)
Browse files Browse the repository at this point in the history
  • Loading branch information
AmShaegar13 authored and bcoe committed Jul 5, 2017
1 parent e9fad9f commit bbadc1f
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 8 deletions.
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -153,6 +153,12 @@ nyc --check-coverage --lines 100 npm test

The above check fails if coverage falls below 100%.

To check thresholds on a per-file basis run:

```shell
nyc check-coverage --lines 95 --per-file
```

## Running reports

Once you've run your tests with nyc, simply run:
Expand Down Expand Up @@ -240,6 +246,7 @@ Any configuration options that can be set via the command line can also be speci
"description": "These are just examples for demonstration, nothing prescriptive",
"nyc": {
"check-coverage": true,
"per-file": true,
"lines": 99,
"statements": 99,
"functions": 99,
Expand Down
2 changes: 1 addition & 1 deletion bin/nyc.js
Expand Up @@ -97,5 +97,5 @@ function checkCoverage (argv, cb) {
functions: argv.functions,
branches: argv.branches,
statements: argv.statements
})
}, argv['per-file'])
}
29 changes: 22 additions & 7 deletions index.js
Expand Up @@ -441,21 +441,36 @@ NYC.prototype.showProcessTree = function () {
console.log(processTree.render(this))
}

NYC.prototype.checkCoverage = function (thresholds) {
NYC.prototype.checkCoverage = function (thresholds, perFile) {
var map = this._getCoverageMapFromAllCoverageFiles()
var summary = map.getCoverageSummary()
var nyc = this

// ERROR: Coverage for lines (90.12%) does not meet global threshold (120%)
if (perFile) {
map.files().forEach(function (file) {
// ERROR: Coverage for lines (90.12%) does not meet threshold (120%) for index.js
nyc._checkCoverage(map.fileCoverageFor(file).toSummary(), thresholds, file)
})
} else {
// ERROR: Coverage for lines (90.12%) does not meet global threshold (120%)
nyc._checkCoverage(map.getCoverageSummary(), thresholds)
}

// process.exitCode was not implemented until v0.11.8.
if (/^v0\.(1[0-1]\.|[0-9]\.)/.test(process.version) && process.exitCode !== 0) process.exit(process.exitCode)
}

NYC.prototype._checkCoverage = function (summary, thresholds, file) {
Object.keys(thresholds).forEach(function (key) {
var coverage = summary[key].pct
if (coverage < thresholds[key]) {
process.exitCode = 1
console.error('ERROR: Coverage for ' + key + ' (' + coverage + '%) does not meet global threshold (' + thresholds[key] + '%)')
if (file) {
console.error('ERROR: Coverage for ' + key + ' (' + coverage + '%) does not meet threshold (' + thresholds[key] + '%) for ' + file)
} else {
console.error('ERROR: Coverage for ' + key + ' (' + coverage + '%) does not meet global threshold (' + thresholds[key] + '%)')
}
}
})

// process.exitCode was not implemented until v0.11.8.
if (/^v0\.(1[0-1]\.|[0-9]\.)/.test(process.version) && process.exitCode !== 0) process.exit(process.exitCode)
}

NYC.prototype._loadProcessInfos = function () {
Expand Down
10 changes: 10 additions & 0 deletions lib/config-util.js
Expand Up @@ -93,6 +93,10 @@ Config.buildYargs = function (cwd) {
default: 0,
description: 'what % of statements must be covered?'
})
.option('per-file', {
default: false,
description: 'check thresholds per file'
})
.example('$0 check-coverage --lines 95', "check whether the JSON in nyc's output folder meets the thresholds provided")
})
.option('reporter', {
Expand Down Expand Up @@ -195,6 +199,12 @@ Config.buildYargs = function (cwd) {
description: 'should nyc detect and handle source maps?',
global: false
})
.option('per-file', {
default: false,
type: 'boolean',
description: 'check thresholds per file',
global: false
})
.option('produce-source-map', {
default: false,
type: 'boolean',
Expand Down
21 changes: 21 additions & 0 deletions test/nyc-bin.js
Expand Up @@ -141,6 +141,27 @@ describe('the nyc cli', function () {
done()
})
})

it('fails when the expected file coverage is below a threshold', function (done) {
var args = [bin, '--check-coverage', '--lines', '51', '--per-file', process.execPath, './half-covered.js']
var matcher = RegExp('ERROR: Coverage for lines \\(50%\\) does not meet threshold \\(51%\\) for .+/half-covered.js')

var proc = spawn(process.execPath, args, {
cwd: fixturesCLI,
env: env
})

var stderr = ''
proc.stderr.on('data', function (chunk) {
stderr += chunk
})

proc.on('close', function (code) {
code.should.not.equal(0)
stderr.trim().should.match(matcher)
done()
})
})
})

// https://github.com/bcoe/nyc/issues/190
Expand Down

0 comments on commit bbadc1f

Please sign in to comment.