Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Define environment variables to be injected in the test file processes
  • Loading branch information
alexisfontaine authored and novemberborn committed Jun 1, 2019
1 parent 626e58c commit a53ea15
Show file tree
Hide file tree
Showing 10 changed files with 98 additions and 8 deletions.
4 changes: 4 additions & 0 deletions docs/06-configuration.md
Expand Up @@ -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,
Expand Down Expand Up @@ -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
Expand Down
9 changes: 9 additions & 0 deletions lib/cli.js
Expand Up @@ -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 {
Expand All @@ -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);
Expand Down Expand Up @@ -206,6 +214,7 @@ exports.run = async () => { // eslint-disable-line complexity
failFast: conf.failFast,
failWithoutAssertions: conf.failWithoutAssertions !== false,
globs,
environmentVariables,
match,
parallelRuns,
projectDir,
Expand Down
16 changes: 16 additions & 0 deletions 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;
16 changes: 8 additions & 8 deletions lib/fork.js
Expand Up @@ -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,
Expand Down Expand Up @@ -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
});

Expand Down
5 changes: 5 additions & 0 deletions test/fixture/environment-variables/ava.config.js
@@ -0,0 +1,5 @@
const config = require('.');

export default {
environmentVariables: {[config.name]: config.value}
};
6 changes: 6 additions & 0 deletions test/fixture/environment-variables/index.js
@@ -0,0 +1,6 @@
'use strict';

module.exports = {
name: 'MY_ENVIRONMENT_VARIABLE',
value: 'some value'
};
1 change: 1 addition & 0 deletions test/fixture/environment-variables/package.json
@@ -0,0 +1 @@
{}
6 changes: 6 additions & 0 deletions 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);
});
7 changes: 7 additions & 0 deletions test/fixture/invalid-environment-variables/package.json
@@ -0,0 +1,7 @@
{
"ava": {
"environmentVariables": {
"SOME_INVALID_ENVIRONMENT_VARIABLE": {}
}
}
}
36 changes: 36 additions & 0 deletions 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();
});
});

0 comments on commit a53ea15

Please sign in to comment.