diff options
Diffstat (limited to 'vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/command/check-coverage.js')
-rw-r--r-- | vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/command/check-coverage.js | 195 |
1 files changed, 195 insertions, 0 deletions
diff --git a/vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/command/check-coverage.js b/vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/command/check-coverage.js new file mode 100644 index 00000000..a7e0a9c7 --- /dev/null +++ b/vnfmarket/src/main/webapp/vnfmarket/node_modules/istanbul/lib/command/check-coverage.js @@ -0,0 +1,195 @@ +/* + Copyright (c) 2012, Yahoo! Inc. All rights reserved. + Copyrights licensed under the New BSD License. See the accompanying LICENSE file for terms. + */ + +var nopt = require('nopt'), + path = require('path'), + fs = require('fs'), + Collector = require('../collector'), + formatOption = require('../util/help-formatter').formatOption, + util = require('util'), + utils = require('../object-utils'), + filesFor = require('../util/file-matcher').filesFor, + Command = require('./index'), + configuration = require('../config'); + +function isAbsolute(file) { + if (path.isAbsolute) { + return path.isAbsolute(file); + } + + return path.resolve(file) === path.normalize(file); +} + +function CheckCoverageCommand() { + Command.call(this); +} + +function removeFiles(covObj, root, files) { + var filesObj = {}, + obj = {}; + + // Create lookup table. + files.forEach(function (file) { + filesObj[file] = true; + }); + + Object.keys(covObj).forEach(function (key) { + // Exclude keys will always be relative, but covObj keys can be absolute or relative + var excludeKey = isAbsolute(key) ? path.relative(root, key) : key; + // Also normalize for files that start with `./`, etc. + excludeKey = path.normalize(excludeKey); + if (filesObj[excludeKey] !== true) { + obj[key] = covObj[key]; + } + }); + + return obj; +} + +CheckCoverageCommand.TYPE = 'check-coverage'; +util.inherits(CheckCoverageCommand, Command); + +Command.mix(CheckCoverageCommand, { + synopsis: function () { + return "checks overall/per-file coverage against thresholds from coverage JSON files. Exits 1 if thresholds are not met, 0 otherwise"; + }, + + usage: function () { + console.error('\nUsage: ' + this.toolName() + ' ' + this.type() + ' <options> [<include-pattern>]\n\nOptions are:\n\n' + + [ + formatOption('--statements <threshold>', 'global statement coverage threshold'), + formatOption('--functions <threshold>', 'global function coverage threshold'), + formatOption('--branches <threshold>', 'global branch coverage threshold'), + formatOption('--lines <threshold>', 'global line coverage threshold') + ].join('\n\n') + '\n'); + + console.error('\n\n'); + + console.error('Thresholds, when specified as a positive number are taken to be the minimum percentage required.'); + console.error('When a threshold is specified as a negative number it represents the maximum number of uncovered entities allowed.\n'); + console.error('For example, --statements 90 implies minimum statement coverage is 90%.'); + console.error(' --statements -10 implies that no more than 10 uncovered statements are allowed\n'); + console.error('Per-file thresholds can be specified via a configuration file.\n'); + console.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'); + }, + + run: function (args, callback) { + + var template = { + config: path, + root: path, + statements: Number, + lines: Number, + branches: Number, + functions: Number, + verbose: Boolean + }, + opts = nopt(template, { v : '--verbose' }, args, 0), + // Translate to config opts. + config = configuration.loadFile(opts.config, { + verbose: opts.verbose, + check: { + global: { + statements: opts.statements, + lines: opts.lines, + branches: opts.branches, + functions: opts.functions + } + } + }), + includePattern = '**/coverage*.json', + root, + collector = new Collector(), + errors = []; + + if (opts.argv.remain.length > 0) { + includePattern = opts.argv.remain[0]; + } + + root = opts.root || process.cwd(); + filesFor({ + root: root, + includes: [ includePattern ] + }, function (err, files) { + if (err) { throw err; } + if (files.length === 0) { + return callback('ERROR: No coverage files found.'); + } + files.forEach(function (file) { + var coverageObject = JSON.parse(fs.readFileSync(file, 'utf8')); + collector.add(coverageObject); + }); + var thresholds = { + global: { + statements: config.check.global.statements || 0, + branches: config.check.global.branches || 0, + lines: config.check.global.lines || 0, + functions: config.check.global.functions || 0, + excludes: config.check.global.excludes || [] + }, + each: { + statements: config.check.each.statements || 0, + branches: config.check.each.branches || 0, + lines: config.check.each.lines || 0, + functions: config.check.each.functions || 0, + excludes: config.check.each.excludes || [] + } + }, + rawCoverage = collector.getFinalCoverage(), + globalResults = utils.summarizeCoverage(removeFiles(rawCoverage, root, thresholds.global.excludes)), + eachResults = removeFiles(rawCoverage, root, thresholds.each.excludes); + + // Summarize per-file results and mutate original results. + Object.keys(eachResults).forEach(function (key) { + eachResults[key] = utils.summarizeFileCoverage(eachResults[key]); + }); + + if (config.verbose) { + console.log('Compare actuals against thresholds'); + console.log(JSON.stringify({ global: globalResults, each: eachResults, thresholds: thresholds }, undefined, 4)); + } + + function check(name, thresholds, actuals) { + [ + "statements", + "branches", + "lines", + "functions" + ].forEach(function (key) { + var actual = actuals[key].pct, + actualUncovered = actuals[key].total - actuals[key].covered, + threshold = thresholds[key]; + + if (threshold < 0) { + if (threshold * -1 < actualUncovered) { + errors.push('ERROR: Uncovered count for ' + key + ' (' + actualUncovered + + ') exceeds ' + name + ' threshold (' + -1 * threshold + ')'); + } + } else { + if (actual < threshold) { + errors.push('ERROR: Coverage for ' + key + ' (' + actual + + '%) does not meet ' + name + ' threshold (' + threshold + '%)'); + } + } + }); + } + + check("global", thresholds.global, globalResults); + + Object.keys(eachResults).forEach(function (key) { + check("per-file" + " (" + key + ") ", thresholds.each, eachResults[key]); + }); + + return callback(errors.length === 0 ? null : errors.join("\n")); + }); + } +}); + +module.exports = CheckCoverageCommand; + + |