Skip to content

Commit 4bf691d

Browse files
committed
Groundwork to support experimental features
From time to time, AVA will implement experimental features. These may change or be removed at any time, not just when there's a new major version. You can opt-in to such a feature by enabling it in the `nonSemVerExperiments` configuration.
1 parent 49b202f commit 4bf691d

File tree

12 files changed

+64
-1
lines changed

12 files changed

+64
-1
lines changed

docs/06-configuration.md

+15
Original file line numberDiff line numberDiff line change
@@ -162,4 +162,19 @@ test('My test', t => {
162162

163163
AVA has a minimum depth of `3`.
164164

165+
## Experiments
166+
167+
From time to time, AVA will implement experimental features. These may change or be removed at any time, not just when there's a new major version. You can opt-in to such a feature by enabling it in the `nonSemVerExperiments` configuration.
168+
169+
`ava.config.js`:
170+
```js
171+
export default {
172+
nonSemVerExperiments: {
173+
feature: true
174+
}
175+
};
176+
```
177+
178+
There are currently no such features available.
179+
165180
[CLI]: ./05-command-line.md

docs/support-statement.md

+2
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,5 @@ We try to avoid *accidentally* dropping support for non-latest Node.js releases.
1515
We may explicitly drop support for non-latest Node.js releases. If this occurs we will bump AVA's major version number. This may be due to adoption of backported APIs or the availability of newer V8 releases in later Node.js versions, either in AVA itself or one of our dependencies.
1616

1717
We may drop support for a Node.js version, in a major-version-bumping-pre-release, if that new AVA version is expected to become stable around or after the end-of-life date of the Node.js version in question.
18+
19+
Experimental features opted into through the `nonSemVerExperiments` configuration may be changed or removed at any time.

lib/api.js

+1
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ class Api extends Emittery {
149149

150150
await this.emit('run', {
151151
clearLogOnNextRun: runtimeOptions.clearLogOnNextRun === true,
152+
experiments: Object.keys(apiOptions.experiments),
152153
failFastEnabled: failFast,
153154
filePathPrefix: commonPathPrefix(files),
154155
files,

lib/cli.js

+1
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ exports.run = async () => { // eslint-disable-line complexity
238238
color: conf.color,
239239
compileEnhancements: conf.compileEnhancements !== false,
240240
concurrency: conf.concurrency ? parseInt(conf.concurrency, 10) : 0,
241+
experiments: conf.nonSemVerExperiments,
241242
extensions,
242243
failFast: conf.failFast,
243244
failWithoutAssertions: conf.failWithoutAssertions !== false,

lib/load-config.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ const pkgConf = require('pkg-conf');
66

77
const NO_SUCH_FILE = Symbol('no ava.config.js file');
88
const MISSING_DEFAULT_EXPORT = Symbol('missing default export');
9+
const EXPERIMENTS = new Set([]);
910

1011
function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {}) { // eslint-disable-line complexity
1112
let packageConf = pkgConf.sync('ava', {cwd: resolveFrom});
@@ -82,7 +83,20 @@ function loadConfig({configFile, resolveFrom = process.cwd(), defaults = {}} = {
8283
}
8384
}
8485

85-
return {...defaults, ...fileConf, ...packageConf, projectDir};
86+
const config = {...defaults, nonSemVerExperiments: {}, ...fileConf, ...packageConf, projectDir};
87+
88+
const {nonSemVerExperiments: experiments} = config;
89+
if (!isPlainObject(experiments)) {
90+
throw new Error(`nonSemVerExperiments from ${fileForErrorMessage} must be an object`);
91+
}
92+
93+
for (const key of Object.keys(experiments)) {
94+
if (!EXPERIMENTS.has(key)) {
95+
throw new Error(`nonSemVerExperiments.${key} from ${fileForErrorMessage} is not a supported experiment`);
96+
}
97+
}
98+
99+
return config;
86100
}
87101

88102
module.exports = loadConfig;

lib/reporters/mini.js

+5
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ class MiniReporter {
135135

136136
cliCursor.hide(this.reportStream);
137137
this.lineWriter.writeLine();
138+
139+
if (plan.experiments.length > 0) {
140+
this.lineWriter.writeLine(colors.information(`${figures.warning} Experiments are enabled. These are unsupported and may change or be be removed at any time.`));
141+
}
142+
138143
this.spinner.start();
139144
}
140145

lib/reporters/verbose.js

+3
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ class VerboseReporter {
9797
}
9898

9999
this.lineWriter.writeLine();
100+
if (plan.experiments.length > 0) {
101+
this.lineWriter.writeLine(colors.information(`${figures.warning} Experiments are enabled. These are unsupported and may change or be removed at any time.${os.EOL}`));
102+
}
100103
}
101104

102105
consumeStateChange(evt) { // eslint-disable-line complexity
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default {
2+
nonSemVerExperiments: []
3+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export default {
2+
nonSemVerExperiments: {
3+
unsupported: true
4+
}
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

test/load-config.js

+12
Original file line numberDiff line numberDiff line change
@@ -131,3 +131,15 @@ test('throws an error if a config file contains `ava` property', t => {
131131
t.throws(loadConfig, /Encountered 'ava' property in ava.config.js; avoid wrapping the configuration/);
132132
t.end();
133133
});
134+
135+
test('throws an error if a config file contains a non-object `nonSemVerExperiments` property', t => {
136+
changeDir('non-object-experiments');
137+
t.throws(loadConfig, /nonSemVerExperiments from ava.config.js must be an object/);
138+
t.end();
139+
});
140+
141+
test('throws an error if a config file enables an unsupported experiment', t => {
142+
changeDir('unsupported-experiments');
143+
t.throws(loadConfig, /nonSemVerExperiments.unsupported from ava.config.js is not a supported experiment/);
144+
t.end();
145+
});

0 commit comments

Comments
 (0)