Skip to content

Commit

Permalink
Experimentally reverse teardown order
Browse files Browse the repository at this point in the history
Co-authored-by: Mark Wubben <[email protected]>
  • Loading branch information
Marc and novemberborn authored Jun 14, 2020
1 parent b3866b6 commit 952a017
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 4 deletions.
26 changes: 25 additions & 1 deletion docs/02-execution-context.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,36 @@ Plan how many assertion there are in the test. The test will fail if the actual

## `t.teardown(fn)`

Registers the `fn` function to be run after the test has finished. You can register multiple functions and they'll run in order. You can use asynchronous functions: only one will run at a time.
Registers the `fn` function to be run after the test has finished. You can register multiple functions and they'll run in order<sup>†</sup>. You can use asynchronous functions: only one will run at a time.

You cannot perform assertions using the `t` object or register additional functions from inside `fn`.

You cannot use `t.teardown()` in hooks either.

<sup>†</sup> In the next major release we'll change this so teardown functions run in reverse order. The last registered function will be called first. You can opt in to this behavior now by enabling the `reverseTeardowns` experiment.

**`package.json`**:

```json
{
"ava": {
"nonSemVerExperiments": {
"reverseTeardowns": true
}
}
}
```

**`ava.config.js`**:

```js
export default {
nonSemVerExperiments: {
reverseTeardowns: true
}
}
```

## `t.timeout(ms)`

Set a timeout for the test, in milliseconds. The test will fail if this timeout is exceeded. The timeout is reset each time an assertion is made.
2 changes: 1 addition & 1 deletion lib/load-config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const pkgConf = require('pkg-conf');

const NO_SUCH_FILE = Symbol('no ava.config.js file');
const MISSING_DEFAULT_EXPORT = Symbol('missing default export');
const EXPERIMENTS = new Set();
const EXPERIMENTS = new Set(['reverseTeardowns']);

// *Very* rudimentary support for loading ava.config.js files containing an `export default` statement.
const evaluateJsConfig = configFile => {
Expand Down
8 changes: 7 additions & 1 deletion lib/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -482,7 +482,13 @@ class Test {
}

async runTeardowns() {
for (const teardown of this.teardowns) {
const teardowns = [...this.teardowns];

if (this.experiments.reverseTeardowns) {
teardowns.reverse();
}

for (const teardown of teardowns) {
try {
await teardown(); // eslint-disable-line no-await-in-loop
} catch (error) {
Expand Down
19 changes: 18 additions & 1 deletion test-tap/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const delay = require('delay');
const snapshotManager = require('../lib/snapshot-manager');
const Test = require('../lib/test');
const HelloMessage = require('./fixture/hello-message');
const {ava} = require('./helper/ava-test');
const {ava, withExperiments} = require('./helper/ava-test');

const failingTestHint = 'Test was expected to fail, but succeeded, you should stop marking the test as failing';

Expand Down Expand Up @@ -799,6 +799,23 @@ test('teardowns run sequentially in order', t => {
});
});

test('teardowns run in reverse order when the `reverseTeardowns` experimental feature is enabled', t => {
let resolveA;
const teardownA = sinon.stub().returns(new Promise(resolve => {
resolveA = resolve;
}));
const teardownB = sinon.stub().resolves(delay(200));

return withExperiments({reverseTeardowns: true})(a => {
a.teardown(teardownA);
a.teardown(() => teardownB().then(resolveA));
a.pass();
}).run().then(result => {
t.is(result.passed, true);
t.ok(teardownB.calledBefore(teardownA));
});
});

test('teardown with cb', t => {
const teardown = sinon.spy();
return ava.cb(a => {
Expand Down

0 comments on commit 952a017

Please sign in to comment.