Skip to content

Commit a0908d8

Browse files
jfmengelssindresorhus
authored andcommitted
Add no-nested-tests rule (fixes #131) (#135)
1 parent a4e4ffb commit a0908d8

File tree

6 files changed

+123
-5
lines changed

6 files changed

+123
-5
lines changed

create-ava-rule.js

+3-5
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,9 @@ module.exports = () => {
8282
}
8383
},
8484
CallExpression: node => {
85-
if (!currentTestNode) {
86-
if (isTestFunctionCall(node.callee)) {
87-
// entering test function
88-
currentTestNode = node;
89-
}
85+
if (isTestFunctionCall(node.callee)) {
86+
// entering test function
87+
currentTestNode = node;
9088
}
9189
},
9290
'CallExpression:exit': node => {

docs/rules/no-nested-tests.md

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Ensure no tests are nested
2+
3+
Translations: [Français](https://github.com/avajs/ava-docs/blob/master/fr_FR/related/eslint-plugin-ava/docs/rules/no-nested-tests.md)
4+
5+
In AVA, you cannot nest tests, for example, create tests inside of other tests. Doing so will lead to odd behavior.
6+
7+
8+
## Fail
9+
10+
```js
11+
import test from 'ava';
12+
13+
test('foo', t => {
14+
const result = foo();
15+
t.true(result.foo);
16+
17+
test('bar', t => {
18+
t.true(result.bar);
19+
});
20+
});
21+
```
22+
23+
24+
## Pass
25+
26+
```js
27+
import test from 'ava';
28+
29+
test('foo', t => {
30+
const result = foo();
31+
t.true(result.foo);
32+
});
33+
34+
test('bar', t => {
35+
const result = foo();
36+
t.true(result.bar);
37+
});
38+
```

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ module.exports = {
2020
'ava/no-identical-title': 'error',
2121
'ava/no-ignored-test-files': 'error',
2222
'ava/no-invalid-end': 'error',
23+
'ava/no-nested-tests': 'error',
2324
'ava/no-only-test': 'error',
2425
'ava/no-skip-assert': 'error',
2526
'ava/no-skip-test': 'error',

readme.md

+2
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ Configure it in `package.json`.
3838
"ava/no-identical-title": "error",
3939
"ava/no-ignored-test-files": "error",
4040
"ava/no-invalid-end": "error",
41+
"ava/no-nested-tests": "error",
4142
"ava/no-only-test": "error",
4243
"ava/no-skip-assert": "error",
4344
"ava/no-skip-test": "error",
@@ -71,6 +72,7 @@ The rules will only activate in test files.
7172
- [no-ignored-test-files](docs/rules/no-ignored-test-files.md) - Ensure no tests are written in ignored files.
7273
- [no-invalid-end](docs/rules/no-invalid-end.md) - Ensure `t.end()` is only called inside `test.cb()`.
7374
- [no-only-test](docs/rules/no-only-test.md) - Ensure no `test.only()` are present.
75+
- [no-nested-tests](docs/rules/no-nested-tests.md) - Ensure no tests are nested.
7476
- [no-skip-assert](docs/rules/no-skip-assert.md) - Ensure no assertions are skipped.
7577
- [no-skip-test](docs/rules/no-skip-test.md) - Ensure no tests are skipped.
7678
- [no-statement-after-end](docs/rules/no-statement-after-end.md) - Ensure `t.end()` is the last statement executed.

rules/no-nested-tests.js

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
'use strict';
2+
const visitIf = require('enhance-visitors').visitIf;
3+
const createAvaRule = require('../create-ava-rule');
4+
5+
const create = context => {
6+
const ava = createAvaRule();
7+
let nestedCount = 0;
8+
9+
return ava.merge({
10+
'CallExpression': visitIf([
11+
ava.isInTestFile,
12+
ava.isTestNode
13+
])(node => {
14+
nestedCount++;
15+
if (nestedCount >= 2) {
16+
context.report({
17+
node,
18+
message: 'Tests should not be nested'
19+
});
20+
}
21+
}),
22+
23+
'CallExpression:exit': visitIf([
24+
ava.isInTestFile,
25+
ava.isTestNode
26+
])(() => {
27+
nestedCount--;
28+
})
29+
});
30+
};
31+
32+
module.exports = {
33+
create,
34+
meta: {}
35+
};

test/no-nested-tests.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import test from 'ava';
2+
import avaRuleTester from 'eslint-ava-rule-tester';
3+
import rule from '../rules/no-nested-tests';
4+
5+
const ruleTester = avaRuleTester(test, {
6+
env: {
7+
es6: true
8+
}
9+
});
10+
11+
const header = `const test = require('ava');\n`;
12+
const error = {
13+
ruleId: 'no-nested-tests',
14+
message: 'Tests should not be nested'
15+
};
16+
17+
ruleTester.run('no-nested-tests', rule, {
18+
valid: [
19+
header + 'test(t => {});',
20+
header + 'test("title", t => {});',
21+
header + 'test(t => {}); test(t => {});',
22+
header + 'test("title", t => {}); test("title", t => {});',
23+
header + 'test.skip(t => {});',
24+
header + 'test.skip(t => {}); test.skip(t => {});',
25+
header + 'test.only(t => {});',
26+
header + 'test.only(t => {}); test.only(t => {});',
27+
// shouldn't be triggered since it's not a test file
28+
'test(t => { test(t => {}); });'
29+
],
30+
invalid: [
31+
{
32+
code: header + 'test("2", t => { test(t => {}); });',
33+
errors: [error]
34+
},
35+
{
36+
code: header + 'test(t => { test(t => {}); test(t => {}); });',
37+
errors: [error, error]
38+
},
39+
{
40+
code: header + 'test(t => { test(t => { test(t => {}); }); });',
41+
errors: [error, error]
42+
}
43+
]
44+
});

0 commit comments

Comments
 (0)