From 1329a3b008dd0b3f174db3dbb51e1cf8b54ca06d Mon Sep 17 00:00:00 2001 From: "Benjamin E. Coe" Date: Thu, 31 May 2018 11:57:22 -0700 Subject: [PATCH] feat: add option that allows instrument to exit on error (#850) --- index.js | 24 +++++++++++--------- lib/commands/instrument.js | 8 ++++++- test/fixtures/cli/subdir/input-dir/bad.js | 1 + test/nyc-bin.js | 27 ++++++++++++++++++++++- 4 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 test/fixtures/cli/subdir/input-dir/bad.js diff --git a/index.js b/index.js index dd1428a82..be11aa59b 100755 --- a/index.js +++ b/index.js @@ -1,3 +1,5 @@ +'use strict' + /* global __coverage__ */ const arrify = require('arrify') @@ -268,25 +270,27 @@ NYC.prototype._maybeInstrumentSource = function (code, filename, relFile) { } NYC.prototype._transformFactory = function (cacheDir) { - var _this = this - var instrumenter = this.instrumenter() - var instrumented + const instrumenter = this.instrumenter() + let instrumented - return function (code, metadata, hash) { - var filename = metadata.filename - var sourceMap = null + return (code, metadata, hash) => { + const filename = metadata.filename + let sourceMap = null - if (_this._sourceMap) sourceMap = _this.sourceMaps.extractAndRegister(code, filename, hash) + if (this._sourceMap) sourceMap = this.sourceMaps.extractAndRegister(code, filename, hash) try { instrumented = instrumenter.instrumentSync(code, filename, sourceMap) } catch (e) { - // don't fail external tests due to instrumentation bugs. debugLog('failed to instrument ' + filename + 'with error: ' + e.stack) - instrumented = code + if (this.config.exitOnError) { + process.exit(1) + } else { + instrumented = code + } } - if (_this.fakeRequire) { + if (this.fakeRequire) { return 'function x () {}' } else { return instrumented diff --git a/lib/commands/instrument.js b/lib/commands/instrument.js index 660f60757..b24c0bb56 100644 --- a/lib/commands/instrument.js +++ b/lib/commands/instrument.js @@ -46,6 +46,11 @@ exports.builder = function (yargs) { type: 'boolean', description: 'should nyc handle instrumentation?' }) + .option('exit-on-error', { + default: false, + type: 'boolean', + description: 'should nyc exit when an instrumentation failure occurs?' + }) .example('$0 instrument ./lib ./output', 'instrument all .js files in ./lib with coverage and output in ./output') } @@ -62,7 +67,8 @@ exports.handler = function (argv) { extension: argv.extension, require: argv.require, compact: argv.compact, - preserveComments: argv.preserveComments + preserveComments: argv.preserveComments, + exitOnError: argv.exitOnError }) nyc.instrumentAllFiles(argv.input, argv.output, function (err) { diff --git a/test/fixtures/cli/subdir/input-dir/bad.js b/test/fixtures/cli/subdir/input-dir/bad.js new file mode 100644 index 000000000..d64a60cb1 --- /dev/null +++ b/test/fixtures/cli/subdir/input-dir/bad.js @@ -0,0 +1 @@ +generate async futurelet console.log('Hello, World!') // this isn't real JS. diff --git a/test/nyc-bin.js b/test/nyc-bin.js index 5a2cb937f..c810a7541 100644 --- a/test/nyc-bin.js +++ b/test/nyc-bin.js @@ -1,4 +1,4 @@ -/* global describe, it */ +/* global describe, it, beforeEach */ const _ = require('lodash') const path = require('path') @@ -425,6 +425,10 @@ describe('the nyc cli', function () { }) describe('instrument', function () { + beforeEach(() => { + rimraf.sync(path.resolve(fixturesCLI, 'subdir', 'output-dir')) + }) + describe('no output folder', function () { it('allows a single file to be instrumented', function (done) { var args = [bin, 'instrument', './half-covered.js'] @@ -485,6 +489,27 @@ describe('the nyc cli', function () { done() }) }) + + it('can be configured to exit on error', function (done) { + var args = [ + bin, + 'instrument', + '--exit-on-error', + './input-dir', + './output-dir' + ] + + var subdir = path.resolve(fixturesCLI, 'subdir') + var proc = spawn(process.execPath, args, { + cwd: subdir, + env: env + }) + + proc.on('exit', function (code) { + code.should.equal(1) + done() + }) + }) }) describe('output folder specified', function () {