Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Add more support for coverage thresholds, make error logging synchronous

  • Loading branch information...
commit cc74095d2727d70afefd8c6fbd80a2b993e671ad 1 parent 0fa6287
Krishnan Anantheswaran authored
Showing with 32 additions and 20 deletions.
  1. +3 −2 lib/cli.js
  2. +21 −10 lib/command/check-coverage.js
  3. +8 −8 lib/command/help.js
5 lib/cli.js
View
@@ -8,6 +8,7 @@
var Command = require('./command'),
inputError = require('./util/input-error'),
+ util = require('util'),
exit = process.exit; //hold a reference to original process.exit so that we are not affected even when a test changes it
require('./register-plugins');
@@ -30,8 +31,8 @@ function errHandler (ex) {
throw ex; // turn it into an uncaught exception
} else {
//don't print nasty traces but still exit(1)
- console.error(ex.message);
- console.error('Try "istanbul help" for usage');
+ util.error(ex.message);
+ util.error('Try "istanbul help" for usage');
exit(1);
}
}
31 lib/command/check-coverage.js
View
@@ -26,20 +26,24 @@ Command.mix(CheckCoverageCommand, {
},
usage: function () {
- console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> [<include-pattern>]\n\nOptions are:\n\n' +
+ util.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> [<include-pattern>]\n\nOptions are:\n\n' +
[
- formatOption('--statements <threshold>', 'The minimum statement coverage required as a percentage'),
- formatOption('--functions <threshold>', 'The minimum statement threshold coverage required as a percentage'),
- formatOption('--branches <threshold>', 'The minimum branch coverage required as a percentage'),
- formatOption('--lines <threshold>', 'The minimum line coverage required as a percentage')
+ formatOption('--statements <threshold>', 'statement coverage threshold'),
+ formatOption('--functions <threshold>', 'function coverage threshold'),
+ formatOption('--branches <threshold>', 'branch coverage threshold'),
+ formatOption('--lines <threshold>', 'line coverage threshold')
].join('\n\n') + '\n');
- console.error('\n');
+ util.error('\n\n');
- console.error('<include-pattern> is a fileset pattern that can be used to select one or more coverage files ' +
+ util.error('Thresholds, when specified as a positive number are taken to be the minimum percentage required.');
+ util.error('When a threshold is specified as a negative number it represents the maximum number of uncovered entities allowed.\n');
+ util.error('For example, --statements 90 implies minimum statement coverage is 90%.');
+ util.error(' --statements -10 implies that no more than 10 uncovered statements are allowed\n');
+ util.error('<include-pattern> is a fileset pattern that can be used to select one or more coverage files ' +
'for merge. This defaults to "**/coverage*.json"');
- console.error('\n');
+ util.error('\n');
},
run: function (args, callback) {
@@ -88,10 +92,17 @@ Command.mix(CheckCoverageCommand, {
Object.keys(thresholds).forEach(function (key) {
var actual = actuals[key].pct,
+ actualUncovered = actuals[key].total - actuals[key].covered,
threshold = thresholds[key];
- if (actual < threshold) {
- errors.push('ERROR: Coverage for ' + key + ' (' + actual + '%) does not meet threshold (' + threshold + '%)');
+ if (threshold < 0) {
+ if (threshold * -1 > actualUncovered) {
+ errors.push('ERROR: Uncovered count for ' + key + ' (' + actualUncovered + ') exceeds threshold (' + -1 * threshold + ')');
+ }
+ } else {
+ if (actual < threshold) {
+ errors.push('ERROR: Coverage for ' + key + ' (' + actual + '%) does not meet threshold (' + threshold + '%)');
+ }
}
});
return callback(errors.length === 0 ? null : errors.join("\n"));
16 lib/command/help.js
View
@@ -22,18 +22,18 @@ Command.mix(HelpCommand, {
usage: function () {
- console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <command>\n');
- console.error('Available commands are:\n');
+ util.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <command>\n');
+ util.error('Available commands are:\n');
var commandObj;
Command.getCommandList().forEach(function (cmd) {
commandObj = Command.create(cmd);
- console.error(formatOption(cmd, commandObj.synopsis()));
- console.error("\n");
+ util.error(formatOption(cmd, commandObj.synopsis()));
+ util.error("\n");
});
- console.error("Command names can be abbreviated as long as the abbreviation is unambiguous");
- console.error(this.toolName() + ' version:' + VERSION);
- console.error("\n");
+ util.error("Command names can be abbreviated as long as the abbreviation is unambiguous");
+ util.error(this.toolName() + ' version:' + VERSION);
+ util.error("\n");
},
run: function (args, callback) {
var command;
@@ -44,7 +44,7 @@ Command.mix(HelpCommand, {
command = Command.create(args[0]);
command.usage('istanbul', Command.resolveCommandName(args[0]));
} catch (ex) {
- console.error('Invalid command: ' + args[0]);
+ util.error('Invalid command: ' + args[0]);
this.usage();
}
}
Please sign in to comment.
Something went wrong with that request. Please try again.