Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

istanbul

Package Overview
Dependencies
Maintainers
2
Versions
95
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

istanbul - npm Package Compare versions

Comparing version 0.4.1 to 1.0.0-alpha.1

CHANGELOG.md

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...
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc