diff --git a/lib/plugin.js b/lib/plugin.js index faf18d9..8a5d9ff 100644 --- a/lib/plugin.js +++ b/lib/plugin.js @@ -13,7 +13,8 @@ module.exports = function (helper) { var root = helper.getRootPath(), dstpath = path.resolve(root, options.destPath), nodes = {}, - nodesToRun = {}; + nodesToRun = {}, + sources = []; options || (options = {}); options.sourceLevels || (options.sourceLevels = options.levels); @@ -49,6 +50,8 @@ module.exports = function (helper) { (nodesToRun[node] = true); } } + } else if (options.jsSuffixes.indexOf(file.suffix) !== -1) { + sources.push(path.relative(root, file.fullname)); } }); @@ -106,7 +109,7 @@ module.exports = function (helper) { var toRun = Object.keys(nodesToRun); - return toRun.length && runner.run(toRun, root); + return toRun.length && runner.run(toRun, root, sources); }); } }; diff --git a/lib/runner.js b/lib/runner.js index e53bd54..6f9b148 100644 --- a/lib/runner.js +++ b/lib/runner.js @@ -11,11 +11,13 @@ var fs = require('fs'), covIdx; if (NEED_COVERAGE) { - covCollector = new (require('istanbul').Collector)(); +var istanbul = require('istanbul'), + covCollector = new (istanbul.Collector)(), + instrumenter = new (istanbul.Instrumenter)(), covIdx = 0; } -exports.run = function (targets, root) { +exports.run = function (targets, root, sources) { var isWinOS = path.sep === '\\', exec = require('child_process').exec, MOCHA_PHANTOM_BIN = path.resolve(__dirname, '../node_modules/.bin/mocha-phantomjs' + (isWinOS ? '.cmd' : '')), @@ -126,11 +128,37 @@ exports.run = function (targets, root) { } function storeFinalCoverage() { - var covFile = path.resolve(root, 'coverage.json'); - - fs.writeFileSync(covFile, JSON.stringify(covCollector.getFinalCoverage()), 'utf8'); - - covCollector.dispose(); + var covFile = path.resolve(root, 'coverage.json'), + store = covCollector.store, + transformer = instrumenter.instrumentSync.bind(instrumenter), + config = istanbul.config.loadFile(), + data = {}; + + // add all files not covered by specs with zero coverage + istanbul.matcherFor({ + root: root, + includes: sources, + excludes: store.keys().concat(config.instrumentation.excludes()) + }, function (err, matcher) { + matcher.files.forEach(function (file) { + // As implemented here: + // https://github.com/gotwarlost/istanbul/blob/master/lib/command/common/run-with-cover.js#L222 + var key = path.relative(root, file); + transformer(fs.readFileSync(file, 'utf-8'), key); + + Object.keys(instrumenter.coverState.s).forEach(function (key) { + instrumenter.coverState.s[key] = 0; + }); + + data[key] = instrumenter.coverState; + }); + + covCollector.add(data); + + fs.writeFileSync(covFile, JSON.stringify(covCollector.getFinalCoverage()), 'utf8'); + + covCollector.dispose(); + }); } return deferer.promise();