@@ -32,7 +32,15 @@
require('../self-coverage-helper')
}
-function NYC (config) {
+function coverageFinder () {
+ var coverage = global.__coverage__
+ if (typeof __coverage__ === 'object') coverage = __coverage__
+ if (!coverage) coverage = global['__coverage__'] = {}
+ return coverage
+}
+
+class NYC {
+ constructor (config) {
config = config || {}
this.config = config
@@ -81,12 +89,12 @@
this.fakeRequire = null
this.processInfo = new ProcessInfo(config && config._processInfo)
- this.rootId = this.processInfo.root || this.generateUniqueID()
+ this.rootId = this.processInfo.root || uuid()
this.hashCache = {}
-}
+ }
-NYC.prototype._createTransform = function (ext) {
+ _createTransform (ext) {
var opts = {
salt: Hash.salt(this.config),
hashData: (input, metadata) => [metadata.filename],
@@ -105,25 +113,25 @@
opts.factory = this._transformFactory.bind(this)
}
return cachingTransform(opts)
-}
+ }
-NYC.prototype._disableCachingTransform = function () {
+ _disableCachingTransform () {
return !(this.cache && this.config.isChildProcess)
-}
+ }
-NYC.prototype._loadAdditionalModules = function () {
+ _loadAdditionalModules () {
this.require.forEach(requireModule => {
// Attempt to require the module relative to the directory being instrumented.
// Then try other locations, e.g. the nyc node_modules folder.
require(resolveFrom.silent(this.cwd, requireModule) || requireModule)
})
-}
+ }
-NYC.prototype.instrumenter = function () {
+ instrumenter () {
return this._instrumenter || (this._instrumenter = this._createInstrumenter())
-}
+ }
-NYC.prototype._createInstrumenter = function () {
+ _createInstrumenter () {
return this._instrumenterLib({
ignoreClassMethods: [].concat(this.config.ignoreClassMethod).filter(a => a),
produceSourceMap: this.config.produceSourceMap,
@@ -132,14 +140,14 @@
esModules: this.config.esModules,
plugins: this.config.parserPlugins
})
-}
+ }
-NYC.prototype.addFile = function (filename) {
+ addFile (filename) {
const source = this._readTranspiledSource(filename)
this._maybeInstrumentSource(source, filename)
-}
+ }
-NYC.prototype._readTranspiledSource = function (filePath) {
+ _readTranspiledSource (filePath) {
var source = null
var ext = path.extname(filePath)
if (typeof Module._extensions[ext] === 'undefined') {
@@ -151,9 +159,9 @@
}
}, filePath)
return source
-}
+ }
-NYC.prototype.addAllFiles = function () {
+ addAllFiles () {
this._loadAdditionalModules()
this.fakeRequire = true
@@ -169,9 +177,9 @@
this.fakeRequire = false
this.writeCoverageFile()
-}
+ }
-NYC.prototype.instrumentAllFiles = function (input, output, cb) {
+ instrumentAllFiles (input, output, cb) {
let inputDir = '.' + path.sep
const visitor = relFile => {
const inFile = path.resolve(inputDir, relFile)
@@ -211,24 +219,30 @@
return cb(err)
}
cb()
-}
+ }
-NYC.prototype._transform = function (code, filename) {
+ _transform (code, filename) {
const extname = path.extname(filename).toLowerCase()
const transform = this.transforms[extname] || (() => null)
return transform(code, { filename })
-}
+ }
-NYC.prototype._maybeInstrumentSource = function (code, filename) {
+ _maybeInstrumentSource (code, filename) {
if (!this.exclude.shouldInstrument(filename)) {
return null
}
return this._transform(code, filename)
-}
+ }
+
+ maybePurgeSourceMapCache () {
+ if (!this.cache) {
+ this.sourceMaps.purgeCache()
+ }
+ }
-NYC.prototype._transformFactory = function (cacheDir) {
+ _transformFactory (cacheDir) {
const instrumenter = this.instrumenter()
let instrumented
@@ -256,21 +270,21 @@
return instrumented
}
}
-}
+ }
-NYC.prototype._handleJs = function (code, options) {
+ _handleJs (code, options) {
// ensure the path has correct casing (see istanbuljs/nyc#269 and nodejs/node#6624)
const filename = path.resolve(this.cwd, options.filename)
return this._maybeInstrumentSource(code, filename) || code
-}
+ }
-NYC.prototype._addHook = function (type) {
+ _addHook (type) {
const handleJs = this._handleJs.bind(this)
const dummyMatcher = () => true // we do all processing in transformer
libHook['hook' + type](dummyMatcher, handleJs, { extensions: this.extensions })
-}
+ }
-NYC.prototype._addRequireHooks = function () {
+ _addRequireHooks () {
if (this.hookRequire) {
this._addHook('Require')
}
@@ -280,49 +294,47 @@
if (this.hookRunInThisContext) {
this._addHook('RunInThisContext')
}
-}
+ }
-NYC.prototype.cleanup = function () {
+ cleanup () {
if (!process.env.NYC_CWD) rimraf.sync(this.tempDirectory())
-}
+ }
-NYC.prototype.clearCache = function () {
+ clearCache () {
if (this.cache) {
rimraf.sync(this.cacheDirectory)
}
-}
+ }
-NYC.prototype.createTempDirectory = function () {
+ createTempDirectory () {
mkdirp.sync(this.tempDirectory())
if (this.cache) mkdirp.sync(this.cacheDirectory)
mkdirp.sync(this.processInfoDirectory())
-}
+ }
-NYC.prototype.reset = function () {
+ reset () {
this.cleanup()
this.createTempDirectory()
-}
+ }
-NYC.prototype._wrapExit = function () {
+ _wrapExit () {
// we always want to write coverage
// regardless of how the process exits.
onExit(() => {
this.writeCoverageFile()
}, { alwaysLast: true })
-}
+ }
-NYC.prototype.wrap = function (bin) {
+ wrap (bin) {
process.env.NYC_PROCESS_ID = this.processInfo.uuid
this._addRequireHooks()
this._wrapExit()
this._loadAdditionalModules()
return this
-}
-
-NYC.prototype.generateUniqueID = uuid
+ }
-NYC.prototype.writeCoverageFile = function () {
+ writeCoverageFile () {
var coverage = coverageFinder()
if (!coverage) return
@@ -360,16 +372,9 @@
JSON.stringify(this.processInfo),
'utf-8'
)
-}
-
-function coverageFinder () {
- var coverage = global.__coverage__
- if (typeof __coverage__ === 'object') coverage = __coverage__
- if (!coverage) coverage = global['__coverage__'] = {}
- return coverage
-}
+ }
-NYC.prototype.getCoverageMapFromAllCoverageFiles = function (baseDirectory) {
+ getCoverageMapFromAllCoverageFiles (baseDirectory) {
const map = libCoverage.createCoverageMap({})
this.eachReport(undefined, (report) => {
@@ -387,9 +392,9 @@
}
return map
-}
+ }
-NYC.prototype.report = function () {
+ report () {
var tree
var map = this.getCoverageMapFromAllCoverageFiles()
var context = libReport.createContext({
@@ -409,10 +414,10 @@
if (this._showProcessTree) {
this.showProcessTree()
}
-}
+ }
-// XXX(@isaacs) Index generation should move to istanbul-lib-processinfo
-NYC.prototype.writeProcessIndex = function () {
+ // XXX(@isaacs) Index generation should move to istanbul-lib-processinfo
+ writeProcessIndex () {
const dir = this.processInfoDirectory()
const pidToUid = new Map()
const infoByUid = new Map()
@@ -437,7 +442,7 @@
infos.forEach(info => {
if (info.parent) {
const parentInfo = infoByUid.get(info.parent)
- if (parentInfo.children.indexOf(info.uuid) === -1) {
+ if (parentInfo && !parentInfo.children.includes(info.uuid)) {
parentInfo.children.push(info.uuid)
}
}
@@ -483,15 +488,15 @@
})
fs.writeFileSync(path.resolve(dir, 'index.json'), JSON.stringify(index))
-}
+ }
-NYC.prototype.showProcessTree = function () {
+ showProcessTree () {
var processTree = ProcessInfo.buildProcessTree(this._loadProcessInfos())
console.log(processTree.render(this))
-}
+ }
-NYC.prototype.checkCoverage = function (thresholds, perFile) {
+ checkCoverage (thresholds, perFile) {
var map = this.getCoverageMapFromAllCoverageFiles()
var nyc = this
@@ -504,9 +509,9 @@
// ERROR: Coverage for lines (90.12%) does not meet global threshold (120%)
nyc._checkCoverage(map.getCoverageSummary(), thresholds)
}
-}
+ }
-NYC.prototype._checkCoverage = function (summary, thresholds, file) {
+ _checkCoverage (summary, thresholds, file) {
Object.keys(thresholds).forEach(function (key) {
var coverage = summary[key].pct
if (coverage < thresholds[key]) {
@@ -518,9 +523,9 @@
}
}
})
-}
+ }
-NYC.prototype._loadProcessInfos = function () {
+ _loadProcessInfos () {
return fs.readdirSync(this.processInfoDirectory()).map(f => {
let data
try {
@@ -540,9 +545,9 @@
infos[info.file] = info.data
return infos
}, {})
-}
+ }
-NYC.prototype.eachReport = function (filenames, iterator, baseDirectory) {
+ eachReport (filenames, iterator, baseDirectory) {
baseDirectory = baseDirectory || this.tempDirectory()
if (typeof filenames === 'function') {
@@ -568,9 +573,9 @@
iterator(report)
})
-}
+ }
-NYC.prototype.loadReports = function (filenames) {
+ loadReports (filenames) {
var reports = []
this.eachReport(filenames, (report) => {
@@ -578,18 +583,19 @@
})
return reports
-}
+ }
-NYC.prototype.tempDirectory = function () {
+ tempDirectory () {
return path.resolve(this.cwd, this._tempDirectory)
-}
+ }
-NYC.prototype.reportDirectory = function () {
+ reportDirectory () {
return path.resolve(this.cwd, this._reportDir)
-}
+ }
-NYC.prototype.processInfoDirectory = function () {
+ processInfoDirectory () {
return path.resolve(this.tempDirectory(), 'processinfo')
+ }
}
module.exports = NYC