Comparing version 0.4.1 to 1.0.0-alpha.1
119
index.js
@@ -7,6 +7,3 @@ /* | ||
/*jslint nomen: true */ | ||
var path = require('path'), | ||
Store = require('./lib/store'), | ||
Report = require('./lib/report'), | ||
meta = require('./lib/util/meta'); | ||
var meta = require('./lib/util/meta'); | ||
@@ -34,87 +31,2 @@ //register our standard plugins | ||
/** | ||
* the Instrumenter class. | ||
* @property Instrumenter | ||
* @type Instrumenter | ||
* @static | ||
*/ | ||
Instrumenter: require('./lib/instrumenter'), | ||
/** | ||
* the Store class. | ||
* @property Store | ||
* @type Store | ||
* @static | ||
*/ | ||
Store: Store, | ||
/** | ||
* the Collector class | ||
* @property Collector | ||
* @type Collector | ||
* @static | ||
*/ | ||
Collector: require('./lib/collector'), | ||
/** | ||
* the hook module | ||
* @property hook | ||
* @type Hook | ||
* @static | ||
*/ | ||
hook: require('./lib/hook'), | ||
/** | ||
* the Report class | ||
* @property Report | ||
* @type Report | ||
* @static | ||
*/ | ||
Report: Report, | ||
/** | ||
* the config module | ||
* @property config | ||
* @type Config | ||
* @static | ||
*/ | ||
config: require('./lib/config'), | ||
/** | ||
* the Reporter class | ||
* @property Reporter | ||
* @type Reporter | ||
* @static | ||
*/ | ||
Reporter: require('./lib/reporter'), | ||
/** | ||
* utility for processing coverage objects | ||
* @property utils | ||
* @type ObjectUtils | ||
* @static | ||
*/ | ||
utils: require('./lib/object-utils'), | ||
/** | ||
* asynchronously returns a function that can match filesystem paths. | ||
* The function returned in the callback may be passed directly as a `matcher` | ||
* to the functions in the `hook` module. | ||
* | ||
* When no options are passed, the match function is one that matches all JS | ||
* files under the current working directory except ones under `node_modules` | ||
* | ||
* Match patterns are `ant`-style patterns processed using the `fileset` library. | ||
* Examples not provided due to limitations in putting asterisks inside | ||
* jsdoc comments. Please refer to tests under `test/other/test-matcher.js` | ||
* for examples. | ||
* | ||
* @method matcherFor | ||
* @static | ||
* @param {Object} options Optional. Lookup options. | ||
* @param {String} [options.root] the root of the filesystem tree under | ||
* which to match files. Defaults to `process.cwd()` | ||
* @param {Array} [options.includes] an array of include patterns to match. | ||
* Defaults to all JS files under the root. | ||
* @param {Array} [options.excludes] and array of exclude patterns. File paths | ||
* matching these patterns will be excluded by the returned matcher. | ||
* Defaults to files under `node_modules` found anywhere under root. | ||
* @param {Function(err, matchFunction)} callback The callback that is | ||
* called with two arguments. The first is an `Error` object in case | ||
* of errors or a falsy value if there were no errors. The second | ||
* is a function that may be use as a matcher. | ||
*/ | ||
matcherFor: require('./lib/util/file-matcher').matcherFor, | ||
/** | ||
* the version of the library | ||
@@ -125,32 +37,5 @@ * @property VERSION | ||
*/ | ||
VERSION: meta.VERSION, | ||
/** | ||
* the abstract Writer class | ||
* @property Writer | ||
* @type Writer | ||
* @static | ||
*/ | ||
Writer: require('./lib/util/writer').Writer, | ||
/** | ||
* the abstract ContentWriter class | ||
* @property ContentWriter | ||
* @type ContentWriter | ||
* @static | ||
*/ | ||
ContentWriter: require('./lib/util/writer').ContentWriter, | ||
/** | ||
* the concrete FileWriter class | ||
* @property FileWriter | ||
* @type FileWriter | ||
* @static | ||
*/ | ||
FileWriter: require('./lib/util/file-writer'), | ||
//undocumented | ||
_yuiLoadHook: require('./lib/util/yui-load-hook'), | ||
//undocumented | ||
TreeSummarizer: require('./lib/util/tree-summarizer'), | ||
//undocumented | ||
assetsDir: path.resolve(__dirname, 'lib', 'assets') | ||
VERSION: meta.VERSION | ||
}; | ||
@@ -8,19 +8,8 @@ /* | ||
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'); | ||
configuration = require('istanbul-api').config, | ||
checkCoverage = require('istanbul-api').checkCoverage; | ||
function isAbsolute(file) { | ||
if (path.isAbsolute) { | ||
return path.isAbsolute(file); | ||
} | ||
return path.resolve(file) === path.normalize(file); | ||
} | ||
function CheckCoverageCommand() { | ||
@@ -30,24 +19,2 @@ 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'; | ||
@@ -107,6 +74,3 @@ util.inherits(CheckCoverageCommand, Command); | ||
}), | ||
includePattern = '**/coverage*.json', | ||
root, | ||
collector = new Collector(), | ||
errors = []; | ||
includePattern; | ||
@@ -116,79 +80,3 @@ if (opts.argv.remain.length > 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")); | ||
}); | ||
checkCoverage.run(config, { root: opts.root, include: includePattern }, callback); | ||
} | ||
@@ -195,0 +83,0 @@ }); |
@@ -6,4 +6,13 @@ /* | ||
var runWithCover = require('./common/run-with-cover'), | ||
var Module = require('module'), | ||
util = require('util'), | ||
path = require('path'), | ||
fs = require('fs'), | ||
nopt = require('nopt'), | ||
which = require('which'), | ||
inputError = require('../util/input-error'), | ||
formatOption = require('../util/help-formatter').formatOption, | ||
api = require('istanbul-api'), | ||
cover = api.cover, | ||
configuration = api.config, | ||
Command = require('./index'); | ||
@@ -18,13 +27,137 @@ | ||
function usage(arg0, command) { | ||
console.error('\nUsage: ' + arg0 + ' ' + command + ' [<options>] <executable-js-file-or-command> [-- <arguments-to-jsfile>]\n\nOptions are:\n\n' | ||
+ [ | ||
formatOption('--config <path-to-config>', 'the configuration file to use, defaults to .istanbul.yml'), | ||
formatOption('--root <path> ', 'the root path to look for files to instrument, defaults to .'), | ||
formatOption('-x <exclude-pattern> [-x <exclude-pattern>]', 'one or more fileset patterns e.g. "**/vendor/**"'), | ||
formatOption('-i <include-pattern> [-i <include-pattern>]', 'one or more fileset patterns e.g. "**/*.js"'), | ||
formatOption('--[no-]default-excludes', 'apply default excludes [ **/node_modules/**, **/test/**, **/tests/** ], defaults to true'), | ||
formatOption('--hook-run-in-context', 'hook vm.runInThisContext in addition to require (supports RequireJS), defaults to false'), | ||
formatOption('--report <format> [--report <format>] ', 'report format, defaults to lcov (= lcov.info + HTML)'), | ||
formatOption('--dir <report-dir>', 'report directory, defaults to ./coverage'), | ||
formatOption('--print <type>', 'type of report to print to console, one of summary (default), detail, both or none'), | ||
formatOption('--verbose, -v', 'verbose mode'), | ||
formatOption('--[no-]preserve-comments', 'remove / preserve comments in the output, defaults to false'), | ||
formatOption('--include-all-sources', 'instrument all unused sources after running tests, defaults to true'), | ||
formatOption('--[no-]include-pid', 'include PID in output coverage filename') | ||
].join('\n\n') + '\n'); | ||
console.error('\n'); | ||
} | ||
function run(args, callback) { | ||
var template = { | ||
config: path, | ||
root: path, | ||
x: [ Array, String ], | ||
report: [Array, String ], | ||
dir: path, | ||
verbose: Boolean, | ||
'default-excludes': Boolean, | ||
print: String, | ||
'self-test': Boolean, | ||
'hook-run-in-context': Boolean, | ||
'preserve-comments': Boolean, | ||
'include-all-sources': Boolean, | ||
i: [ Array, String ], | ||
'include-pid': Boolean, | ||
'extension': [ Array, String ] | ||
}, | ||
opts = nopt(template, { v : '--verbose' }, args, 0), | ||
overrides = { | ||
verbose: opts.verbose, | ||
instrumentation: { | ||
root: opts.root, | ||
'default-excludes': opts['default-excludes'], | ||
excludes: opts.x, | ||
'include-all-sources': opts['include-all-sources'], | ||
'include-pid': opts['include-pid'] | ||
}, | ||
reporting: { | ||
reports: opts.report, | ||
print: opts.print, | ||
dir: opts.dir | ||
}, | ||
hooks: { | ||
'hook-run-in-context': opts['hook-run-in-context'], | ||
'handle-sigint': opts['handle-sigint'] | ||
} | ||
}, | ||
config, | ||
verbose, | ||
cmdAndArgs = opts.argv.remain, | ||
cmd, | ||
cmdArgs, | ||
runFn; | ||
if (opts.extension && opts.extension.length) { | ||
overrides.instrumentation.extensions = opts.extension.map(function (e) { | ||
if (e.indexOf('.') !== 0) { | ||
e = '.' + e; | ||
} | ||
return e; | ||
}); | ||
} | ||
config = configuration.loadFile(opts.config, overrides); | ||
verbose = config.verbose; | ||
if (cmdAndArgs.length === 0) { | ||
return callback(inputError.create('Need a filename argument for the cover command!')); | ||
} | ||
cmd = cmdAndArgs.shift(); | ||
cmdArgs = cmdAndArgs; | ||
if (!fs.existsSync(cmd)) { | ||
try { | ||
cmd = which.sync(cmd); | ||
} catch (ex) { | ||
return callback(inputError.create('Unable to resolve file [' + cmd + ']')); | ||
} | ||
} else { | ||
cmd = path.resolve(cmd); | ||
} | ||
runFn = function () { | ||
process.argv = ["node", cmd].concat(cmdArgs); | ||
if (verbose) { | ||
console.log('Running: ' + process.argv.join(' ')); | ||
} | ||
process.env.running_under_istanbul=1; | ||
Module.runMain(cmd, null, true); | ||
}; | ||
cover.getCoverFunctions(config, opts.i, function (err, fns) { | ||
/* istanbul ignore if */ | ||
if (err) { | ||
throw err; | ||
} | ||
process.once('exit', fns.exitFn); | ||
// enable passing --handle-sigint to write reports on SIGINT. | ||
// This allows a user to manually kill a process while | ||
// still getting the istanbul report. | ||
/* istanbul ignore if */ | ||
if (config.hooks.handleSigint()) { | ||
process.once('SIGINT', process.exit); | ||
} | ||
if (opts['self-test']) { | ||
fns.unhookFn(); | ||
} | ||
fns.hookFn(); | ||
runFn(); | ||
}); | ||
} | ||
Command.mix(CoverCommand, { | ||
synopsis: function () { | ||
return "transparently adds coverage information to a node command. Saves coverage.json and reports at the end of execution"; | ||
return "transparently adds coverage information to a node command. Saves coverage.raw.json and reports at the end of execution"; | ||
}, | ||
usage: function () { | ||
runWithCover.usage(this.toolName(), this.type()); | ||
usage(this.toolName(), this.type()); | ||
}, | ||
run: function (args, callback) { | ||
runWithCover.run(args, this.type(), true, callback); | ||
run(args, callback); | ||
} | ||
@@ -31,0 +164,0 @@ }); |
@@ -10,3 +10,3 @@ /* | ||
VERSION = require('../../index').VERSION, | ||
configuration = require('../config'), | ||
configuration = require('istanbul-api').config, | ||
yaml = require('js-yaml'), | ||
@@ -13,0 +13,0 @@ formatPara = require('../util/help-formatter').formatPara; |
@@ -7,123 +7,11 @@ /* | ||
var path = require('path'), | ||
mkdirp = require('mkdirp'), | ||
once = require('once'), | ||
async = require('async'), | ||
fs = require('fs'), | ||
filesFor = require('../util/file-matcher').filesFor, | ||
nopt = require('nopt'), | ||
Instrumenter = require('../instrumenter'), | ||
inputError = require('../util/input-error'), | ||
api = require('istanbul-api'), | ||
instrument = api.instrument, | ||
formatOption = require('../util/help-formatter').formatOption, | ||
util = require('util'), | ||
Command = require('./index'), | ||
Collector = require('../collector'), | ||
configuration = require('../config'), | ||
verbose; | ||
inputError = require('../util/input-error'), | ||
configuration = require('istanbul-api').config; | ||
/* | ||
* Chunk file size to use when reading non JavaScript files in memory | ||
* and copying them over when using complete-copy flag. | ||
*/ | ||
var READ_FILE_CHUNK_SIZE = 64 * 1024; | ||
function BaselineCollector(instrumenter) { | ||
this.instrumenter = instrumenter; | ||
this.collector = new Collector(); | ||
this.instrument = instrumenter.instrument.bind(this.instrumenter); | ||
var origInstrumentSync = instrumenter.instrumentSync; | ||
this.instrumentSync = function () { | ||
var args = Array.prototype.slice.call(arguments), | ||
ret = origInstrumentSync.apply(this.instrumenter, args), | ||
baseline = this.instrumenter.lastFileCoverage(), | ||
coverage = {}; | ||
coverage[baseline.path] = baseline; | ||
this.collector.add(coverage); | ||
return ret; | ||
}; | ||
//monkey patch the instrumenter to call our version instead | ||
instrumenter.instrumentSync = this.instrumentSync.bind(this); | ||
} | ||
BaselineCollector.prototype = { | ||
getCoverage: function () { | ||
return this.collector.getFinalCoverage(); | ||
} | ||
}; | ||
function processFiles(instrumenter, inputDir, outputDir, relativeNames, extensions) { | ||
var processor = function (name, callback) { | ||
var inputFile = path.resolve(inputDir, name), | ||
outputFile = path.resolve(outputDir, name), | ||
inputFileExtenstion = path.extname(inputFile), | ||
isJavaScriptFile = extensions.indexOf(inputFileExtenstion) > -1, | ||
oDir = path.dirname(outputFile), | ||
readStream, writeStream; | ||
callback = once(callback); | ||
mkdirp.sync(oDir); | ||
if (fs.statSync(inputFile).isDirectory()) { | ||
return callback(null, name); | ||
} | ||
if (isJavaScriptFile) { | ||
fs.readFile(inputFile, 'utf8', function (err, data) { | ||
if (err) { return callback(err, name); } | ||
instrumenter.instrument(data, inputFile, function (iErr, instrumented) { | ||
if (iErr) { return callback(iErr, name); } | ||
fs.writeFile(outputFile, instrumented, 'utf8', function (err) { | ||
return callback(err, name); | ||
}); | ||
}); | ||
}); | ||
} | ||
else { | ||
// non JavaScript file, copy it as is | ||
readStream = fs.createReadStream(inputFile, {'bufferSize': READ_FILE_CHUNK_SIZE}); | ||
writeStream = fs.createWriteStream(outputFile); | ||
readStream.on('error', callback); | ||
writeStream.on('error', callback); | ||
readStream.pipe(writeStream); | ||
readStream.on('end', function() { | ||
callback(null, name); | ||
}); | ||
} | ||
}, | ||
q = async.queue(processor, 10), | ||
errors = [], | ||
count = 0, | ||
startTime = new Date().getTime(); | ||
q.push(relativeNames, function (err, name) { | ||
var inputFile, outputFile; | ||
if (err) { | ||
errors.push({ file: name, error: err.message || err.toString() }); | ||
inputFile = path.resolve(inputDir, name); | ||
outputFile = path.resolve(outputDir, name); | ||
fs.writeFileSync(outputFile, fs.readFileSync(inputFile)); | ||
} | ||
if (verbose) { | ||
console.log('Processed: ' + name); | ||
} else { | ||
if (count % 100 === 0) { process.stdout.write('.'); } | ||
} | ||
count += 1; | ||
}); | ||
q.drain = function () { | ||
var endTime = new Date().getTime(); | ||
console.log('\nProcessed [' + count + '] files in ' + Math.floor((endTime - startTime) / 1000) + ' secs'); | ||
if (errors.length > 0) { | ||
console.log('The following ' + errors.length + ' file(s) had errors and were copied as-is'); | ||
console.log(errors); | ||
} | ||
}; | ||
} | ||
function InstrumentCommand() { | ||
@@ -151,3 +39,2 @@ Command.call(this); | ||
'default value of `__coverage__` to something else'), | ||
formatOption('--embed-source', 'embed source code into the coverage object, defaults to false'), | ||
formatOption('--[no-]compact', 'produce [non]compact output, defaults to compact'), | ||
@@ -175,7 +62,6 @@ formatOption('--[no-]preserve-comments', 'remove / preserve comments in the output, defaults to false'), | ||
'baseline-file': path, | ||
'embed-source': Boolean, | ||
'preserve-comments': Boolean, | ||
'es-modules': Boolean | ||
}, | ||
opts = nopt(template, { v : '--verbose' }, args, 0), | ||
opts = nopt(template, {v: '--verbose'}, args, 0), | ||
overrides = { | ||
@@ -186,3 +72,2 @@ verbose: opts.verbose, | ||
compact: opts.compact, | ||
'embed-source': opts['embed-source'], | ||
'preserve-comments': opts['preserve-comments'], | ||
@@ -197,14 +82,6 @@ excludes: opts.x, | ||
config = configuration.loadFile(opts.config, overrides), | ||
iOpts = config.instrumentation, | ||
cmdArgs = opts.argv.remain, | ||
file, | ||
stats, | ||
stream, | ||
includes, | ||
instrumenter, | ||
needBaseline = iOpts.saveBaseline(), | ||
baselineFile = path.resolve(iOpts.baselineFile()), | ||
output = opts.output; | ||
output = opts.output, | ||
excludes = opts.x; | ||
verbose = config.verbose; | ||
if (cmdArgs.length !== 1) { | ||
@@ -214,54 +91,3 @@ return callback(inputError.create('Need exactly one filename/ dirname argument for the instrument command!')); | ||
if (iOpts.completeCopy()) { | ||
includes = ['**/*']; | ||
} | ||
else { | ||
includes = iOpts.extensions().map(function(ext) { | ||
return '**/*' + ext; | ||
}); | ||
} | ||
instrumenter = new Instrumenter({ | ||
coverageVariable: iOpts.variable(), | ||
embedSource: iOpts.embedSource(), | ||
noCompact: !iOpts.compact(), | ||
preserveComments: iOpts.preserveComments(), | ||
esModules: iOpts.esModules() | ||
}); | ||
if (needBaseline) { | ||
mkdirp.sync(path.dirname(baselineFile)); | ||
instrumenter = new BaselineCollector(instrumenter); | ||
process.on('exit', function () { | ||
console.log('Saving baseline coverage at: ' + baselineFile); | ||
fs.writeFileSync(baselineFile, JSON.stringify(instrumenter.getCoverage()), 'utf8'); | ||
}); | ||
} | ||
file = path.resolve(cmdArgs[0]); | ||
stats = fs.statSync(file); | ||
if (stats.isDirectory()) { | ||
if (!output) { return callback(inputError.create('Need an output directory [-o <dir>] when input is a directory!')); } | ||
if (output === file) { return callback(inputError.create('Cannot instrument into the same directory/ file as input!')); } | ||
mkdirp.sync(output); | ||
filesFor({ | ||
root: file, | ||
includes: includes, | ||
excludes: opts.x || iOpts.excludes(false), // backwards-compat, *sigh* | ||
relative: true | ||
}, function (err, files) { | ||
if (err) { return callback(err); } | ||
processFiles(instrumenter, file, output, files, iOpts.extensions()); | ||
}); | ||
} else { | ||
if (output) { | ||
stream = fs.createWriteStream(output); | ||
} else { | ||
stream = process.stdout; | ||
} | ||
stream.write(instrumenter.instrumentSync(fs.readFileSync(file, 'utf8'), file)); | ||
if (stream !== process.stdout) { | ||
stream.end(); | ||
} | ||
} | ||
instrument.run(config, { input: cmdArgs[0], output: output, excludes: excludes}, callback); | ||
} | ||
@@ -268,0 +94,0 @@ }); |
@@ -7,14 +7,11 @@ /* | ||
var nopt = require('nopt'), | ||
Report = require('../report'), | ||
Reporter = require('../reporter'), | ||
api = require('istanbul-api'), | ||
reports = api.reports, | ||
path = require('path'), | ||
fs = require('fs'), | ||
Collector = require('../collector'), | ||
helpFormatter = require('../util/help-formatter'), | ||
formatOption = helpFormatter.formatOption, | ||
formatPara = helpFormatter.formatPara, | ||
filesFor = require('../util/file-matcher').filesFor, | ||
util = require('util'), | ||
Command = require('./index'), | ||
configuration = require('../config'); | ||
configuration = require('istanbul-api').config; | ||
@@ -28,10 +25,2 @@ function ReportCommand() { | ||
function printDeprecationMessage(pat, fmt) { | ||
console.error('**********************************************************************'); | ||
console.error('DEPRECATION WARNING! You are probably using the old format of the report command'); | ||
console.error('This will stop working soon, see `istanbul help report` for the new command format'); | ||
console.error('Assuming you meant: istanbul report --include=' + pat + ' ' + fmt); | ||
console.error('**********************************************************************'); | ||
} | ||
Command.mix(ReportCommand, { | ||
@@ -53,11 +42,7 @@ synopsis: function () { | ||
console.error('\n'); | ||
console.error('<format> is one of '); | ||
Report.getReportList().forEach(function (name) { | ||
console.error(formatOption(name, Report.create(name).synopsis())); | ||
}); | ||
console.error('<format> is a report name'); | ||
console.error(""); | ||
console.error(formatPara([ | ||
'Default format is lcov unless otherwise specified in the config file.', | ||
'In addition you can tweak the file names for various reports using the config file.', | ||
'Type `istanbul help config` to see what can be tweaked.' | ||
'In addition you can tweak the file names for various reports using the config file.' | ||
].join(' '))); | ||
@@ -77,5 +62,2 @@ console.error('\n'); | ||
opts = nopt(template, { v : '--verbose' }, args, 0), | ||
includePattern = opts.include || '**/coverage*.json', | ||
root, | ||
collector = new Collector(), | ||
config = configuration.loadFile(opts.config, { | ||
@@ -87,37 +69,4 @@ verbose: opts.verbose, | ||
}), | ||
formats = opts.argv.remain, | ||
reporter = new Reporter(config); | ||
// Start: backward compatible processing | ||
if (formats.length === 2 && | ||
Report.getReportList().indexOf(formats[1]) < 0) { | ||
includePattern = formats[1]; | ||
formats = [ formats[0] ]; | ||
printDeprecationMessage(includePattern, formats[0]); | ||
} | ||
// End: backward compatible processing | ||
if (formats.length === 0) { | ||
formats = config.reporting.reports(); | ||
} | ||
if (formats.length === 0) { | ||
formats = [ 'lcov' ]; | ||
} | ||
reporter.addAll(formats); | ||
root = opts.root || process.cwd(); | ||
filesFor({ | ||
root: root, | ||
includes: [ includePattern ] | ||
}, function (err, files) { | ||
if (err) { throw err; } | ||
files.forEach(function (file) { | ||
var coverageObject = JSON.parse(fs.readFileSync(file, 'utf8')); | ||
collector.add(coverageObject); | ||
}); | ||
reporter.write(collector, false, function (err) { | ||
console.log('Done'); | ||
return callback(err); | ||
}); | ||
}); | ||
formats = opts.argv.remain; | ||
reports.run(formats, config, { include: opts.include, root: opts.root }, callback); | ||
} | ||
@@ -124,0 +73,0 @@ }); |
@@ -6,8 +6,4 @@ | ||
*/ | ||
var Store = require('./store'), | ||
Report = require('./report'), | ||
Command = require('./command'); | ||
var Command = require('./command'); | ||
Store.loadAll(); | ||
Report.loadAll(); | ||
Command.loadAll(); | ||
@@ -14,0 +10,0 @@ |
{ | ||
"name": "istanbul", | ||
"version": "0.4.1", | ||
"version": "1.0.0-alpha.1", | ||
"description": "Yet another JS code coverage tool that computes statement, line, function and branch coverage with module loader hooks to transparently add coverage when running tests. Supports all JS coverage use cases including unit tests, server side functional tests and browser tests. Built for scale", | ||
@@ -84,3 +84,3 @@ "keywords": [ | ||
"scripts": { | ||
"pretest": "jshint index.js lib/ test/ && ./download-escodegen-browser.sh", | ||
"pretest": "jshint index.js lib/ test/", | ||
"test": "node --harmony test/run.js", | ||
@@ -102,14 +102,8 @@ "posttest": "node ./lib/cli.js check-coverage --statements 95 --branches 80", | ||
"dependencies": { | ||
"istanbul-api": "^1.0.0-alpha", | ||
"abbrev": "1.0.x", | ||
"async": "1.x", | ||
"escodegen": "1.7.x", | ||
"esprima": "2.7.x", | ||
"fileset": "0.2.x", | ||
"handlebars": "^4.0.1", | ||
"js-yaml": "3.x", | ||
"mkdirp": "0.5.x", | ||
"nopt": "3.x", | ||
"once": "1.x", | ||
"resolve": "1.1.x", | ||
"supports-color": "^3.1.0", | ||
"which": "^1.1.1", | ||
@@ -121,2 +115,4 @@ "wordwrap": "^1.0.0" | ||
"glob": "^5.0.14", | ||
"istanbul-lib-coverage": "^1.0.0-alpha.0", | ||
"istanbul-lib-instrument": "^1.0.0-alpha.0", | ||
"jshint": "^2.8.0", | ||
@@ -123,0 +119,0 @@ "nodeunit": "0.9.x", |
@@ -14,2 +14,3 @@ ## Istanbul - a JS code coverage tool written in JS | ||
* [Getting started and configuration](#getting-started) | ||
* [Usage on Windows](#usage-on-windows) | ||
* [The command line](#the-command-line) | ||
@@ -60,3 +61,20 @@ * [Ignoring code for coverage](#ignoring-code-for-coverage) | ||
### Usage on Windows | ||
Istanbul assumes that the `command` passed to it is a JS file (e.g. Jasmine, vows etc.), | ||
this is however not true on Windows where npm wrap bin files in a `.cmd` file. | ||
Since Istanbul can not parse `.cmd` files you need to reference the bin file manually. | ||
Here is an example using Jasmine 2: | ||
istanbul cover node_modules\jasmine\bin\jasmine.js | ||
In order to use this cross platform (e.i. Linux, Mac and Windows), you can insert | ||
the above line into the script object in your package.json file but with normal | ||
slash. | ||
"scripts": { | ||
"test": "istanbul cover node_modules/jasmine/bin/jasmine.js" | ||
} | ||
### Configuring | ||
@@ -273,2 +291,1 @@ | ||
coverage, carpet-area coverage, the country that makes good carpets and so on... | ||
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Deprecated
MaintenanceThe maintainer of the package marked it as deprecated. This could indicate that a single version should not be used, or that the package is no longer maintained and any new vulnerabilities will not be fixed.
Found 1 instance in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 2 instances in 1 package
8
0
289
6
60202
8
17
706
1
+ Addedistanbul-api@^1.0.0-alpha
+ Addedansi-regex@2.1.1(transitive)
+ Addedansi-styles@2.2.1(transitive)
+ Addedappend-transform@0.4.0(transitive)
+ Addedasync@2.6.4(transitive)
+ Addedbabel-code-frame@6.26.0(transitive)
+ Addedbabel-generator@6.26.1(transitive)
+ Addedbabel-messages@6.23.0(transitive)
+ Addedbabel-runtime@6.26.0(transitive)
+ Addedbabel-template@6.26.0(transitive)
+ Addedbabel-traverse@6.26.0(transitive)
+ Addedbabel-types@6.26.0(transitive)
+ Addedbabylon@6.18.0(transitive)
+ Addedchalk@1.1.3(transitive)
+ Addedcore-js@2.6.12(transitive)
+ Addeddebug@2.6.93.2.7(transitive)
+ Addeddefault-require-extensions@1.0.0(transitive)
+ Addeddetect-indent@4.0.0(transitive)
+ Addedescape-string-regexp@1.0.5(transitive)
+ Addedfileset@2.0.3(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglobals@9.18.0(transitive)
+ Addedhas-ansi@2.0.0(transitive)
+ Addedinvariant@2.2.4(transitive)
+ Addedis-finite@1.1.0(transitive)
+ Addedis-utf8@0.2.1(transitive)
+ Addedistanbul-api@1.3.7(transitive)
+ Addedistanbul-lib-coverage@1.2.1(transitive)
+ Addedistanbul-lib-hook@1.2.2(transitive)
+ Addedistanbul-lib-instrument@1.10.2(transitive)
+ Addedistanbul-lib-report@1.1.5(transitive)
+ Addedistanbul-lib-source-maps@1.2.6(transitive)
+ Addedistanbul-reports@1.5.1(transitive)
+ Addedjs-tokens@3.0.2(transitive)
+ Addedjsesc@1.3.0(transitive)
+ Addedlodash@4.17.21(transitive)
+ Addedloose-envify@1.4.0(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedms@2.0.02.1.3(transitive)
+ Addedpath-parse@1.0.7(transitive)
+ Addedregenerator-runtime@0.11.1(transitive)
+ Addedrepeating@2.0.1(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedsemver@5.7.2(transitive)
+ Addedsource-map@0.5.7(transitive)
+ Addedstrip-ansi@3.0.1(transitive)
+ Addedstrip-bom@2.0.0(transitive)
+ Addedsupports-color@2.0.0(transitive)
+ Addedto-fast-properties@1.0.3(transitive)
+ Addedtrim-right@1.0.1(transitive)
- Removedescodegen@1.7.x
- Removedesprima@2.7.x
- Removedfileset@0.2.x
- Removedhandlebars@^4.0.1
- Removedonce@1.x
- Removedresolve@1.1.x
- Removedsupports-color@^3.1.0
- Removedamdefine@1.0.1(transitive)
- Removeddeep-is@0.1.4(transitive)
- Removedescodegen@1.7.1(transitive)
- Removedesprima@1.2.52.7.3(transitive)
- Removedestraverse@1.9.3(transitive)
- Removedfast-levenshtein@1.0.7(transitive)
- Removedfileset@0.2.1(transitive)
- Removedglob@5.0.15(transitive)
- Removedlevn@0.2.5(transitive)
- Removedminimatch@2.0.10(transitive)
- Removedoptionator@0.5.0(transitive)
- Removedprelude-ls@1.1.2(transitive)
- Removedresolve@1.1.7(transitive)
- Removedsource-map@0.2.0(transitive)
- Removedtype-check@0.3.2(transitive)
- Removedwordwrap@0.0.3(transitive)