From ec129e841281da8b9643205f532a9a635d9bdc70 Mon Sep 17 00:00:00 2001 From: isaacs Date: Thu, 18 Apr 2019 17:37:06 -0700 Subject: [PATCH] feat: Add support for env.NYC_CONFIG_OVERRIDE This allows a process to spawn a child process with an environment variable NYC_CONFIG_OVERRIDE. This is a JSON string which overrides any values in the NYC_CONFIG env. It is not deleted in the child process, so will be contagious unless unset, and it is the responsibility of the caller to manage. The first intended use case of this feature is to allow node-tap to map tests to the specific portion of a system under test that they cover. In this way, unit tests can be more focused, and only re-run when their specific unit has changed. There are, of course, many other uses that this could be put to, and it did not seem appropriate to add a special hook _just_ for overriding the include list. --- bin/wrap.js | 6 ++++ .../test-config-override.js-TAP.test.js | 20 +++++++++++ test/config-override.js | 36 +++++++++++++++++++ test/fixtures/cli/conf-override-module.js | 2 ++ test/fixtures/cli/conf-override-root.js | 24 +++++++++++++ 5 files changed, 88 insertions(+) create mode 100644 tap-snapshots/test-config-override.js-TAP.test.js create mode 100644 test/config-override.js create mode 100644 test/fixtures/cli/conf-override-module.js create mode 100755 test/fixtures/cli/conf-override-root.js diff --git a/bin/wrap.js b/bin/wrap.js index 1cff275e6..4e64c2b5f 100644 --- a/bin/wrap.js +++ b/bin/wrap.js @@ -16,6 +16,12 @@ if (process.env.NYC_PROCESSINFO_EXTERNAL_ID) { delete process.env.NYC_PROCESSINFO_EXTERNAL_ID } +if (process.env.NYC_CONFIG_OVERRIDE) { + var override = JSON.parse(process.env.NYC_CONFIG_OVERRIDE) + config = Object.assign(config, override) + process.env.NYC_CONFIG = JSON.stringify(config) +} + ;(new NYC(config)).wrap() sw.runMain() diff --git a/tap-snapshots/test-config-override.js-TAP.test.js b/tap-snapshots/test-config-override.js-TAP.test.js new file mode 100644 index 000000000..63ff6ff35 --- /dev/null +++ b/tap-snapshots/test-config-override.js-TAP.test.js @@ -0,0 +1,20 @@ +/* IMPORTANT + * This snapshot file is auto-generated, but designed for humans. + * It should be checked into source control and tracked carefully. + * Re-generate by setting TAP_SNAPSHOT=1 and running tests. + * Make sure to inspect the output below. Do not ignore changes! + */ +'use strict' +exports[`test/config-override.js TAP spawn that does config overriding > stdout 1`] = ` +in parent { include: 'conf-override-root.js' } +in child { include: 'conf-override-module.js' } +in module { include: 'conf-override-module.js' } +-------------------------|----------|----------|----------|----------|-------------------| +File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s | +-------------------------|----------|----------|----------|----------|-------------------| +All files | 77.78 | 50 | 100 | 77.78 | | + conf-override-module.js | 100 | 100 | 100 | 100 | | + conf-override-root.js | 71.43 | 50 | 100 | 71.43 | 22,23 | +-------------------------|----------|----------|----------|----------|-------------------| + +` diff --git a/test/config-override.js b/test/config-override.js new file mode 100644 index 000000000..3b87e1526 --- /dev/null +++ b/test/config-override.js @@ -0,0 +1,36 @@ +const { spawn } = require('child_process') +const { resolve } = require('path') +const t = require('tap') +const node = process.execPath +const fixturesCLI = resolve(__dirname, './fixtures/cli') +const root = resolve(fixturesCLI, 'conf-override-root.js') +const bin = resolve(__dirname, '../self-coverage/bin/nyc') +const rimraf = require('rimraf').sync +const tmp = 'conf-override-test' +const fs = require('fs') +const resolvedJS = resolve(fixturesCLI, 'selfspawn-fibonacci.js') + +rimraf(resolve(fixturesCLI, tmp)) +t.teardown(() => rimraf(resolve(fixturesCLI, tmp))) + +t.test('spawn that does config overriding', t => { + const args = [ + bin, '-t', tmp, + '--exclude-after-remap=false', + '--include=conf-override-root.js', + node, 'conf-override-root.js' + ] + const proc = spawn(node, args, { + cwd: fixturesCLI + }) + const out = [] + const err = [] + proc.stdout.on('data', c => out.push(c)) + proc.stderr.on('data', c => err.push(c)) + proc.on('close', (code, signal) => { + t.equal(code, 0) + t.equal(signal, null) + t.matchSnapshot(Buffer.concat(out).toString(), 'stdout') + t.end() + }) +}) diff --git a/test/fixtures/cli/conf-override-module.js b/test/fixtures/cli/conf-override-module.js new file mode 100644 index 000000000..d949d3475 --- /dev/null +++ b/test/fixtures/cli/conf-override-module.js @@ -0,0 +1,2 @@ +const config = JSON.parse(process.env.NYC_CONFIG) +console.log('in module', {include: config.include}) diff --git a/test/fixtures/cli/conf-override-root.js b/test/fixtures/cli/conf-override-root.js new file mode 100755 index 000000000..a7a99f6ef --- /dev/null +++ b/test/fixtures/cli/conf-override-root.js @@ -0,0 +1,24 @@ +const config = JSON.parse(process.env.NYC_CONFIG) +const { include } = config + +if (process.argv[2] !== 'child') { + console.log('in parent', { include }) + require('child_process').spawn(process.execPath, [__filename, 'child'], { + cwd: __dirname, + env: Object.assign( + {}, + process.env, + { + NYC_CONFIG_OVERRIDE: JSON.stringify({ + include: 'conf-override-module.js' + }) + } + ), + stdio: 'inherit', + }) +} else { + // this should run, but not be covered, even though the shebang says to + // the child run ONLY covers the child file, not the dump-root.js + console.log('in child', { include }) + require('./conf-override-module.js') +}