From a53ea157367c9cec91184cfbb226487c81229513 Mon Sep 17 00:00:00 2001 From: Alexis Fontaine Date: Sat, 1 Jun 2019 08:45:01 +0000 Subject: [PATCH] Define environment variables to be injected in the test file processes --- docs/06-configuration.md | 4 +++ lib/cli.js | 9 +++++ lib/environment-variables.js | 16 +++++++++ lib/fork.js | 16 ++++----- .../environment-variables/ava.config.js | 5 +++ test/fixture/environment-variables/index.js | 6 ++++ .../environment-variables/package.json | 1 + test/fixture/environment-variables/test.js | 6 ++++ .../package.json | 7 ++++ test/integration/environment-variables.js | 36 +++++++++++++++++++ 10 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 lib/environment-variables.js create mode 100644 test/fixture/environment-variables/ava.config.js create mode 100644 test/fixture/environment-variables/index.js create mode 100644 test/fixture/environment-variables/package.json create mode 100644 test/fixture/environment-variables/test.js create mode 100644 test/fixture/invalid-environment-variables/package.json create mode 100644 test/integration/environment-variables.js diff --git a/docs/06-configuration.md b/docs/06-configuration.md index 92b295dc2..8d5521d2f 100644 --- a/docs/06-configuration.md +++ b/docs/06-configuration.md @@ -30,6 +30,9 @@ To ignore files, prefix the pattern with an `!` (exclamation mark). "concurrency": 5, "failFast": true, "failWithoutAssertions": false, + "environmentVariables": { + "MY_ENVIRONMENT_VARIABLE": "some value" + }, "tap": true, "verbose": true, "compileEnhancements": false, @@ -57,6 +60,7 @@ Arguments passed to the CLI will always take precedence over the CLI options con - `cache`: cache compiled test and helper files under `node_modules/.cache/ava`. If `false`, files are cached in a temporary directory instead - `failFast`: stop running further tests once a test fails - `failWithoutAssertions`: if `false`, does not fail a test if it doesn't run [assertions](./03-assertions.md) +- `environmentVariables`: specifies environment variables to be made available to the tests. The environment variables defined here override the ones from `process.env` - `tap`: if `true`, enables the [TAP reporter](./05-command-line.md#tap-reporter) - `verbose`: if `true`, enables verbose output - `snapshotDir`: specifies a fixed location for storing snapshot files. Use this if your snapshots are ending up in the wrong location diff --git a/lib/cli.js b/lib/cli.js index 00c6278b3..c873073b6 100644 --- a/lib/cli.js +++ b/lib/cli.js @@ -163,6 +163,7 @@ exports.run = async () => { // eslint-disable-line complexity const babelPipeline = require('./babel-pipeline'); const normalizeExtensions = require('./extensions'); const {normalizeGlobs} = require('./globs'); + const validateEnvironmentVariables = require('./environment-variables'); let babelConfig = null; try { @@ -171,6 +172,13 @@ exports.run = async () => { // eslint-disable-line complexity exit(error.message); } + let environmentVariables; + try { + environmentVariables = validateEnvironmentVariables(conf.environmentVariables); + } catch (error) { + exit(error.message); + } + let extensions; try { extensions = normalizeExtensions(conf.extensions || [], babelConfig); @@ -206,6 +214,7 @@ exports.run = async () => { // eslint-disable-line complexity failFast: conf.failFast, failWithoutAssertions: conf.failWithoutAssertions !== false, globs, + environmentVariables, match, parallelRuns, projectDir, diff --git a/lib/environment-variables.js b/lib/environment-variables.js new file mode 100644 index 000000000..e0a7a924b --- /dev/null +++ b/lib/environment-variables.js @@ -0,0 +1,16 @@ +'use strict'; +function validateEnvironmentVariables(environmentVariables) { + if (!environmentVariables) { + return {}; + } + + for (const value of Object.values(environmentVariables)) { + if (typeof value !== 'string') { + throw new TypeError('The \'environmentVariables\' configuration must be an object containing string values.'); + } + } + + return environmentVariables; +} + +module.exports = validateEnvironmentVariables; diff --git a/lib/fork.js b/lib/fork.js index 6a12a9083..f748e03cb 100644 --- a/lib/fork.js +++ b/lib/fork.js @@ -9,20 +9,20 @@ if (fs.realpathSync(__filename) !== __filename) { console.warn('WARNING: `npm link ava` and the `--preserve-symlink` flag are incompatible. We have detected that AVA is linked via `npm link`, and that you are using either an early version of Node 6, or the `--preserve-symlink` flag. This breaks AVA. You should upgrade to Node 6.2.0+, avoid the `--preserve-symlink` flag, or avoid using `npm link ava`.'); } -const env = {NODE_ENV: 'test', ...process.env}; +// In case the test file imports a different AVA install, +// the presence of this variable allows it to require this one instead +const AVA_PATH = path.resolve(__dirname, '..'); // Ensure NODE_PATH paths are absolute -if (env.NODE_PATH) { - env.NODE_PATH = env.NODE_PATH +let NODE_PATH; + +if (process.env.NODE_PATH) { + NODE_PATH = process.env.NODE_PATH .split(path.delimiter) .map(x => path.resolve(x)) .join(path.delimiter); } -// In case the test file imports a different AVA install, -// the presence of this variable allows it to require this one instead -env.AVA_PATH = path.resolve(__dirname, '..'); - const describeTTY = tty => ({ colorDepth: tty.getColorDepth ? tty.getColorDepth() : undefined, columns: tty.columns || 80, @@ -56,7 +56,7 @@ module.exports = (file, opts, execArgv) => { const subprocess = childProcess.fork(workerPath, args, { cwd: opts.projectDir, silent: true, - env, + env: {NODE_ENV: 'test', ...process.env, ...opts.environmentVariables, AVA_PATH, NODE_PATH}, execArgv: execArgv || process.execArgv }); diff --git a/test/fixture/environment-variables/ava.config.js b/test/fixture/environment-variables/ava.config.js new file mode 100644 index 000000000..d8f79e8de --- /dev/null +++ b/test/fixture/environment-variables/ava.config.js @@ -0,0 +1,5 @@ +const config = require('.'); + +export default { + environmentVariables: {[config.name]: config.value} +}; diff --git a/test/fixture/environment-variables/index.js b/test/fixture/environment-variables/index.js new file mode 100644 index 000000000..58dbeb10c --- /dev/null +++ b/test/fixture/environment-variables/index.js @@ -0,0 +1,6 @@ +'use strict'; + +module.exports = { + name: 'MY_ENVIRONMENT_VARIABLE', + value: 'some value' +}; diff --git a/test/fixture/environment-variables/package.json b/test/fixture/environment-variables/package.json new file mode 100644 index 000000000..0967ef424 --- /dev/null +++ b/test/fixture/environment-variables/package.json @@ -0,0 +1 @@ +{} diff --git a/test/fixture/environment-variables/test.js b/test/fixture/environment-variables/test.js new file mode 100644 index 000000000..de7d2dfb7 --- /dev/null +++ b/test/fixture/environment-variables/test.js @@ -0,0 +1,6 @@ +import test from '../../..'; +import {name, value} from '.'; + +test('works', t => { + t.is(process.env[name], value); +}); diff --git a/test/fixture/invalid-environment-variables/package.json b/test/fixture/invalid-environment-variables/package.json new file mode 100644 index 000000000..be0d922a7 --- /dev/null +++ b/test/fixture/invalid-environment-variables/package.json @@ -0,0 +1,7 @@ +{ + "ava": { + "environmentVariables": { + "SOME_INVALID_ENVIRONMENT_VARIABLE": {} + } + } +} diff --git a/test/integration/environment-variables.js b/test/integration/environment-variables.js new file mode 100644 index 000000000..7d2efc8e7 --- /dev/null +++ b/test/integration/environment-variables.js @@ -0,0 +1,36 @@ +'use strict'; +const {test} = require('tap'); +const figures = require('figures'); +const {execCli} = require('../helper/cli'); +const {name, value} = require('../fixture/environment-variables'); + +test('sets default environment variables from the config', t => { + execCli(['test.js'], {dirname: 'fixture/environment-variables'}, (err, stdout) => { + t.ifError(err); + t.match(stdout, /1 test passed/); + t.end(); + }); +}); + +test('overrides environment variables provided through the CLI', t => { + const env = {[name]: `${value} (updated)`}; + + execCli(['test.js'], {dirname: 'fixture/environment-variables', env}, (err, stdout) => { + t.ifError(err); + t.match(stdout, /1 test passed/); + t.end(); + }); +}); + +test('errors if environment variables are not string values', t => { + execCli(['es2015.js'], {dirname: 'fixture/invalid-environment-variables'}, (err, stdout, stderr) => { + t.ok(err); + + let expectedOutput = '\n'; + expectedOutput += figures.cross + ' The \'environmentVariables\' configuration must be an object containing string values.'; + expectedOutput += '\n'; + + t.is(stderr, expectedOutput); + t.end(); + }); +});