aboutsummaryrefslogtreecommitdiff
path: root/node_modules/nyc/lib
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/nyc/lib')
-rw-r--r--node_modules/nyc/lib/commands/instrument.js55
-rw-r--r--node_modules/nyc/lib/config-util.js253
-rw-r--r--node_modules/nyc/lib/hash.js14
-rw-r--r--node_modules/nyc/lib/instrumenters/istanbul.js49
-rw-r--r--node_modules/nyc/lib/instrumenters/noop.js21
-rw-r--r--node_modules/nyc/lib/process-args.js36
-rw-r--r--node_modules/nyc/lib/process.js98
-rw-r--r--node_modules/nyc/lib/self-coverage-helper.js20
-rw-r--r--node_modules/nyc/lib/source-maps.js57
9 files changed, 603 insertions, 0 deletions
diff --git a/node_modules/nyc/lib/commands/instrument.js b/node_modules/nyc/lib/commands/instrument.js
new file mode 100644
index 000000000..6ff4a5222
--- /dev/null
+++ b/node_modules/nyc/lib/commands/instrument.js
@@ -0,0 +1,55 @@
+var NYC
+try {
+ NYC = require('../../index.covered.js')
+} catch (e) {
+ NYC = require('../../index.js')
+}
+
+exports.command = 'instrument <input> [output]'
+
+exports.describe = 'instruments a file or a directory tree and writes the instrumented code to the desired output location'
+
+exports.builder = function (yargs) {
+ return yargs
+ .usage('$0 instrument <input> [output]')
+ .option('require', {
+ alias: 'i',
+ default: [],
+ describe: 'a list of additional modules that nyc should attempt to require in its subprocess, e.g., babel-register, babel-polyfill.'
+ })
+ .option('extension', {
+ alias: 'e',
+ default: [],
+ describe: 'a list of extensions that nyc should handle in addition to .js'
+ })
+ .option('source-map', {
+ default: true,
+ type: 'boolean',
+ description: 'should nyc detect and handle source maps?'
+ })
+ .option('instrument', {
+ default: true,
+ type: 'boolean',
+ description: 'should nyc handle instrumentation?'
+ })
+ .example('$0 instrument ./lib ./output', 'instrument all .js files in ./lib with coverage and output in ./output')
+}
+
+exports.handler = function (argv) {
+ // if instrument is set to false,
+ // enable a noop instrumenter.
+ if (!argv.instrument) argv.instrumenter = './lib/instrumenters/noop'
+ else argv.instrumenter = './lib/instrumenters/istanbul'
+
+ var nyc = new NYC({
+ instrumenter: argv.instrumenter,
+ sourceMap: argv.sourceMap,
+ extension: argv.extension,
+ require: argv.require
+ })
+
+ nyc.instrumentAllFiles(argv.input, argv.output, function (err) {
+ if (err) console.error(err.message)
+ process.exit(1)
+ })
+}
diff --git a/node_modules/nyc/lib/config-util.js b/node_modules/nyc/lib/config-util.js
new file mode 100644
index 000000000..62d057a3f
--- /dev/null
+++ b/node_modules/nyc/lib/config-util.js
@@ -0,0 +1,253 @@
+const arrify = require('arrify')
+const fs = require('fs')
+const path = require('path')
+const findUp = require('find-up')
+const testExclude = require('test-exclude')
+const Yargs = require('yargs/yargs')
+
+var Config = {}
+
+// load config from a cascade of sources:
+// * command line arguments
+// * package.json
+// * .nycrc
+Config.loadConfig = function (argv, cwd) {
+ cwd = cwd || process.env.NYC_CWD || process.cwd()
+ var pkgPath = findUp.sync('package.json', {cwd: cwd})
+ var rcPath = findUp.sync('.nycrc', {cwd: cwd})
+ var rcConfig = null
+
+ if (rcPath) {
+ rcConfig = JSON.parse(
+ fs.readFileSync(rcPath, 'utf-8')
+ )
+ }
+
+ if (pkgPath) {
+ cwd = path.dirname(pkgPath)
+ }
+
+ var config = Config.buildYargs(cwd)
+ .default({
+ cwd: cwd
+ })
+ if (rcConfig) config.config(rcConfig)
+ config = config.parse(argv || [])
+
+ // post-hoc, we convert several of the
+ // configuration settings to arrays, providing
+ // a consistent contract to index.js.
+ config.require = arrify(config.require)
+ config.extension = arrify(config.extension)
+ config.exclude = arrify(config.exclude)
+ config.include = arrify(config.include)
+ config.cwd = cwd
+
+ return config
+}
+
+// build a yargs object, omitting any settings
+// that would cause the application to exit early.
+Config.buildYargs = function (cwd) {
+ return Yargs([])
+ .usage('$0 [command] [options]\n\nrun your tests with the nyc bin to instrument them with coverage')
+ .command('report', 'run coverage report for .nyc_output', function (yargs) {
+ return yargs
+ .usage('$0 report [options]')
+ .option('reporter', {
+ alias: 'r',
+ describe: 'coverage reporter(s) to use',
+ default: 'text'
+ })
+ .option('report-dir', {
+ describe: 'directory to output coverage reports in',
+ default: 'coverage'
+ })
+ .option('temp-directory', {
+ describe: 'directory to read raw coverage information from',
+ default: './.nyc_output'
+ })
+ .option('show-process-tree', {
+ describe: 'display the tree of spawned processes',
+ default: false,
+ type: 'boolean'
+ })
+ .example('$0 report --reporter=lcov', 'output an HTML lcov report to ./coverage')
+ })
+ .command('check-coverage', 'check whether coverage is within thresholds provided', function (yargs) {
+ return yargs
+ .usage('$0 check-coverage [options]')
+ .option('branches', {
+ default: 0,
+ description: 'what % of branches must be covered?'
+ })
+ .option('functions', {
+ default: 0,
+ description: 'what % of functions must be covered?'
+ })
+ .option('lines', {
+ default: 90,
+ description: 'what % of lines must be covered?'
+ })
+ .option('statements', {
+ default: 0,
+ description: 'what % of statements must be covered?'
+ })
+ .example('$0 check-coverage --lines 95', "check whether the JSON in nyc's output folder meets the thresholds provided")
+ })
+ .option('reporter', {
+ alias: 'r',
+ describe: 'coverage reporter(s) to use',
+ default: 'text',
+ globa: false
+ })
+ .option('report-dir', {
+ describe: 'directory to output coverage reports in',
+ default: 'coverage',
+ global: false
+ })
+ .option('silent', {
+ alias: 's',
+ default: false,
+ type: 'boolean',
+ describe: "don't output a report after tests finish running",
+ global: false
+ })
+ .option('all', {
+ alias: 'a',
+ default: false,
+ type: 'boolean',
+ describe: 'whether or not to instrument all files of the project (not just the ones touched by your test suite)',
+ global: false
+ })
+ .option('exclude', {
+ alias: 'x',
+ default: testExclude.defaultExclude,
+ describe: 'a list of specific files and directories that should be excluded from coverage, glob patterns are supported, node_modules is always excluded',
+ global: false
+ })
+ .option('include', {
+ alias: 'n',
+ default: [],
+ describe: 'a list of specific files that should be covered, glob patterns are supported',
+ global: false
+ })
+ .option('require', {
+ alias: 'i',
+ default: [],
+ describe: 'a list of additional modules that nyc should attempt to require in its subprocess, e.g., babel-register, babel-polyfill.',
+ global: false
+ })
+ .option('eager', {
+ default: false,
+ type: 'boolean',
+ describe: 'instantiate the instrumenter at startup (see https://git.io/vMKZ9)',
+ global: false
+ })
+ .option('cache', {
+ alias: 'c',
+ default: true,
+ type: 'boolean',
+ describe: 'cache instrumentation results for improved performance',
+ global: false
+ })
+ .option('babel-cache', {
+ default: false,
+ type: 'boolean',
+ describe: 'cache babel transpilation results for improved performance',
+ global: false
+ })
+ .option('extension', {
+ alias: 'e',
+ default: [],
+ describe: 'a list of extensions that nyc should handle in addition to .js',
+ global: false
+ })
+ .option('check-coverage', {
+ type: 'boolean',
+ default: false,
+ describe: 'check whether coverage is within thresholds provided',
+ global: false
+ })
+ .option('branches', {
+ default: 0,
+ description: 'what % of branches must be covered?',
+ global: false
+ })
+ .option('functions', {
+ default: 0,
+ description: 'what % of functions must be covered?',
+ global: false
+ })
+ .option('lines', {
+ default: 90,
+ description: 'what % of lines must be covered?',
+ global: false
+ })
+ .option('statements', {
+ default: 0,
+ description: 'what % of statements must be covered?',
+ global: false
+ })
+ .option('source-map', {
+ default: true,
+ type: 'boolean',
+ description: 'should nyc detect and handle source maps?',
+ global: false
+ })
+ .option('produce-source-map', {
+ default: false,
+ type: 'boolean',
+ description: "should nyc's instrumenter produce source maps?",
+ global: false
+ })
+ .option('instrument', {
+ default: true,
+ type: 'boolean',
+ description: 'should nyc handle instrumentation?',
+ global: false
+ })
+ .option('hook-run-in-context', {
+ default: true,
+ type: 'boolean',
+ description: 'should nyc wrap vm.runInThisContext?',
+ global: false
+ })
+ .option('show-process-tree', {
+ describe: 'display the tree of spawned processes',
+ default: false,
+ type: 'boolean',
+ global: false
+ })
+ .option('clean', {
+ describe: 'should the .nyc_output folder be cleaned before executing tests',
+ default: true,
+ type: 'boolean',
+ global: false
+ })
+ .option('temp-directory', {
+ describe: 'directory to output raw coverage information to',
+ default: './.nyc_output',
+ global: false
+ })
+ .pkgConf('nyc', cwd || process.cwd())
+ .example('$0 npm test', 'instrument your tests with coverage')
+ .example('$0 --require babel-core/register npm test', 'instrument your tests with coverage and babel')
+ .example('$0 report --reporter=text-lcov', 'output lcov report after running your tests')
+ .epilog('visit https://git.io/voHar for list of available reporters')
+ .boolean('help')
+ .boolean('h')
+ .boolean('version')
+}
+
+// decorate yargs with all the actions
+// that would make it exit: help, version, command.
+Config.decorateYargs = function (yargs) {
+ return yargs
+ .help('h')
+ .alias('h', 'help')
+ .version()
+ .command(require('../lib/commands/instrument'))
+}
+
+module.exports = Config
diff --git a/node_modules/nyc/lib/hash.js b/node_modules/nyc/lib/hash.js
new file mode 100644
index 000000000..a36372071
--- /dev/null
+++ b/node_modules/nyc/lib/hash.js
@@ -0,0 +1,14 @@
+const CACHE_VERSION = require('../package.json').version
+const md5hex = require('md5-hex')
+const salt = JSON.stringify({
+ istanbul: require('istanbul-lib-coverage/package.json').version,
+ nyc: CACHE_VERSION
+})
+
+function Hash (code, filename) {
+ return md5hex([code, filename, salt]) + '_' + CACHE_VERSION
+}
+
+Hash.salt = salt
+
+module.exports = Hash
diff --git a/node_modules/nyc/lib/instrumenters/istanbul.js b/node_modules/nyc/lib/instrumenters/istanbul.js
new file mode 100644
index 000000000..c1d4b1338
--- /dev/null
+++ b/node_modules/nyc/lib/instrumenters/istanbul.js
@@ -0,0 +1,49 @@
+'use strict'
+
+var convertSourceMap = require('convert-source-map')
+var mergeSourceMap = require('merge-source-map')
+
+function InstrumenterIstanbul (cwd, options) {
+ var istanbul = InstrumenterIstanbul.istanbul()
+ var instrumenter = istanbul.createInstrumenter({
+ autoWrap: true,
+ coverageVariable: '__coverage__',
+ embedSource: true,
+ noCompact: false,
+ preserveComments: true,
+ produceSourceMap: options.produceSourceMap
+ })
+
+ return {
+ instrumentSync: function (code, filename, sourceMap) {
+ var instrumented = instrumenter.instrumentSync(code, filename)
+ // the instrumenter can optionally produce source maps,
+ // this is useful for features like remapping stack-traces.
+ // TODO: test source-map merging logic.
+ if (options.produceSourceMap) {
+ var lastSourceMap = instrumenter.lastSourceMap()
+ if (lastSourceMap) {
+ if (sourceMap) {
+ lastSourceMap = mergeSourceMap(
+ sourceMap.toObject(),
+ lastSourceMap
+ )
+ }
+ instrumented += '\n' + convertSourceMap.fromObject(lastSourceMap).toComment()
+ }
+ }
+ return instrumented
+ },
+ lastFileCoverage: function () {
+ return instrumenter.lastFileCoverage()
+ }
+ }
+}
+
+InstrumenterIstanbul.istanbul = function () {
+ InstrumenterIstanbul._istanbul || (InstrumenterIstanbul._istanbul = require('istanbul-lib-instrument'))
+
+ return InstrumenterIstanbul._istanbul || (InstrumenterIstanbul._istanbul = require('istanbul'))
+}
+
+module.exports = InstrumenterIstanbul
diff --git a/node_modules/nyc/lib/instrumenters/noop.js b/node_modules/nyc/lib/instrumenters/noop.js
new file mode 100644
index 000000000..935b587c0
--- /dev/null
+++ b/node_modules/nyc/lib/instrumenters/noop.js
@@ -0,0 +1,21 @@
+var FileCoverage = require('istanbul-lib-coverage').classes.FileCoverage
+var readInitialCoverage = require('istanbul-lib-instrument').readInitialCoverage
+
+function NOOP () {
+ return {
+ instrumentSync: function (code, filename) {
+ var extracted = readInitialCoverage(code)
+ if (extracted) {
+ this.fileCoverage = new FileCoverage(extracted.coverageData)
+ } else {
+ this.fileCoverage = null
+ }
+ return code
+ },
+ lastFileCoverage: function () {
+ return this.fileCoverage
+ }
+ }
+}
+
+module.exports = NOOP
diff --git a/node_modules/nyc/lib/process-args.js b/node_modules/nyc/lib/process-args.js
new file mode 100644
index 000000000..df6bcaac1
--- /dev/null
+++ b/node_modules/nyc/lib/process-args.js
@@ -0,0 +1,36 @@
+const parser = require('yargs-parser')
+const commands = [
+ 'report',
+ 'check-coverage',
+ 'instrument'
+]
+
+module.exports = {
+ // don't pass arguments that are meant
+ // for nyc to the bin being instrumented.
+ hideInstrumenterArgs: function (yargv) {
+ var argv = process.argv.slice(1)
+ argv = argv.slice(argv.indexOf(yargv._[0]))
+ if (argv[0][0] === '-') {
+ argv.unshift(process.execPath)
+ }
+ return argv
+ },
+ // don't pass arguments for the bin being
+ // instrumented to nyc.
+ hideInstrumenteeArgs: function () {
+ var argv = process.argv.slice(2)
+ var yargv = parser(argv)
+ if (!yargv._.length) return argv
+ for (var i = 0, command; (command = yargv._[i]) !== undefined; i++) {
+ if (~commands.indexOf(command)) return argv
+ }
+
+ // drop all the arguments after the bin being
+ // instrumented by nyc.
+ argv = argv.slice(0, argv.indexOf(yargv._[0]))
+ argv.push(yargv._[0])
+
+ return argv
+ }
+}
diff --git a/node_modules/nyc/lib/process.js b/node_modules/nyc/lib/process.js
new file mode 100644
index 000000000..3976f14ed
--- /dev/null
+++ b/node_modules/nyc/lib/process.js
@@ -0,0 +1,98 @@
+const archy = require('archy')
+const libCoverage = require('istanbul-lib-coverage')
+
+function ProcessInfo (defaults) {
+ defaults = defaults || {}
+
+ this.pid = String(process.pid)
+ this.argv = process.argv
+ this.execArgv = process.execArgv
+ this.cwd = process.cwd()
+ this.time = Date.now()
+ this.ppid = null
+ this.root = null
+ this.coverageFilename = null
+ this.nodes = [] // list of children, filled by buildProcessTree()
+
+ this._coverageMap = null
+
+ for (var key in defaults) {
+ this[key] = defaults[key]
+ }
+}
+
+Object.defineProperty(ProcessInfo.prototype, 'label', {
+ get: function () {
+ if (this._label) {
+ return this._label
+ }
+
+ var covInfo = ''
+ if (this._coverageMap) {
+ covInfo = '\n ' + this._coverageMap.getCoverageSummary().lines.pct + ' % Lines'
+ }
+ return this.argv.join(' ') + covInfo
+ }
+})
+
+ProcessInfo.buildProcessTree = function (infos) {
+ var treeRoot = new ProcessInfo({ _label: 'nyc' })
+ var nodes = { }
+
+ infos = infos.sort(function (a, b) {
+ return a.time - b.time
+ })
+
+ infos.forEach(function (p) {
+ nodes[p.root + ':' + p.pid] = p
+ })
+
+ infos.forEach(function (p) {
+ if (!p.ppid) {
+ return
+ }
+
+ var parent = nodes[p.root + ':' + p.ppid]
+ if (!parent) {
+ parent = treeRoot
+ }
+
+ parent.nodes.push(p)
+ })
+
+ return treeRoot
+}
+
+ProcessInfo.prototype.getCoverageMap = function (merger) {
+ if (this._coverageMap) {
+ return this._coverageMap
+ }
+
+ var childMaps = this.nodes.map(function (child) {
+ return child.getCoverageMap(merger)
+ })
+
+ this._coverageMap = merger([this.coverageFilename], childMaps)
+
+ return this._coverageMap
+}
+
+ProcessInfo.prototype.render = function (nyc) {
+ this.getCoverageMap(function (filenames, maps) {
+ var map = libCoverage.createCoverageMap({})
+
+ nyc.loadReports(filenames).forEach(function (report) {
+ map.merge(report)
+ })
+
+ maps.forEach(function (otherMap) {
+ map.merge(otherMap)
+ })
+
+ return map
+ })
+
+ return archy(this)
+}
+
+module.exports = ProcessInfo
diff --git a/node_modules/nyc/lib/self-coverage-helper.js b/node_modules/nyc/lib/self-coverage-helper.js
new file mode 100644
index 000000000..675f9bea9
--- /dev/null
+++ b/node_modules/nyc/lib/self-coverage-helper.js
@@ -0,0 +1,20 @@
+/* global ___NYC_SELF_COVERAGE___ */
+
+const path = require('path')
+const fs = require('fs')
+const mkdirp = require('mkdirp')
+const onExit = require('signal-exit')
+
+onExit(function () {
+ var coverage = global.___NYC_SELF_COVERAGE___
+ if (typeof ___NYC_SELF_COVERAGE___ === 'object') coverage = ___NYC_SELF_COVERAGE___
+ if (!coverage) return
+
+ var selfCoverageDir = path.join(__dirname, '../.self_coverage')
+ mkdirp.sync(selfCoverageDir)
+ fs.writeFileSync(
+ path.join(selfCoverageDir, process.pid + '.json'),
+ JSON.stringify(coverage),
+ 'utf-8'
+ )
+})
diff --git a/node_modules/nyc/lib/source-maps.js b/node_modules/nyc/lib/source-maps.js
new file mode 100644
index 000000000..c3238544c
--- /dev/null
+++ b/node_modules/nyc/lib/source-maps.js
@@ -0,0 +1,57 @@
+const convertSourceMap = require('convert-source-map')
+const libCoverage = require('istanbul-lib-coverage')
+const libSourceMaps = require('istanbul-lib-source-maps')
+const fs = require('fs')
+const path = require('path')
+
+// TODO: write some unit tests for this class.
+function SourceMaps (opts) {
+ this.cache = opts.cache
+ this.cacheDirectory = opts.cacheDirectory
+ this.sourceMapCache = libSourceMaps.createSourceMapStore()
+ this.loadedMaps = {}
+}
+
+SourceMaps.prototype.extractAndRegister = function (code, filename, hash) {
+ var sourceMap = convertSourceMap.fromSource(code) || convertSourceMap.fromMapFileSource(code, path.dirname(filename))
+ if (sourceMap) {
+ if (this.cache && hash) {
+ var mapPath = path.join(this.cacheDirectory, hash + '.map')
+ fs.writeFileSync(mapPath, sourceMap.toJSON())
+ } else {
+ this.sourceMapCache.registerMap(filename, sourceMap.sourcemap)
+ }
+ }
+ return sourceMap
+}
+
+SourceMaps.prototype.remapCoverage = function (obj) {
+ var transformed = this.sourceMapCache.transformCoverage(
+ libCoverage.createCoverageMap(obj)
+ )
+ return transformed.map.data
+}
+
+SourceMaps.prototype.reloadCachedSourceMaps = function (report) {
+ var _this = this
+ Object.keys(report).forEach(function (absFile) {
+ var fileReport = report[absFile]
+ if (fileReport && fileReport.contentHash) {
+ var hash = fileReport.contentHash
+ if (!(hash in _this.loadedMaps)) {
+ try {
+ var mapPath = path.join(_this.cacheDirectory, hash + '.map')
+ _this.loadedMaps[hash] = JSON.parse(fs.readFileSync(mapPath, 'utf8'))
+ } catch (e) {
+ // set to false to avoid repeatedly trying to load the map
+ _this.loadedMaps[hash] = false
+ }
+ }
+ if (_this.loadedMaps[hash]) {
+ _this.sourceMapCache.registerMap(absFile, _this.loadedMaps[hash])
+ }
+ }
+ })
+}
+
+module.exports = SourceMaps