Skip to content

Commit b829dbc

Browse files
JLHwungsindresorhus
andcommitted
Add no-inline-assertions rule (#262)
Co-authored-by: Sindre Sorhus <[email protected]>
1 parent 7ef827e commit b829dbc

File tree

5 files changed

+121
-0
lines changed

5 files changed

+121
-0
lines changed

docs/rules/no-inline-assertions.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# Ensure assertions are not called from inline arrow functions
2+
3+
The test implementation should not purely consist of an inline assertion as assertions do not return a value and having them inline also makes the tests less readable.
4+
5+
This rule is fixable. It will wrap the assertion in braces `{}`. It will not do any whitespace or style changes.
6+
7+
8+
## Fail
9+
10+
```js
11+
import test from 'ava';
12+
13+
test('foo', t => t.true(fn()));
14+
```
15+
16+
17+
## Pass
18+
19+
```js
20+
import test from 'ava';
21+
22+
test('foo', t => {
23+
t.true(fn());
24+
});
25+
```

index.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ module.exports = {
2828
'ava/no-identical-title': 'error',
2929
'ava/no-ignored-test-files': 'error',
3030
'ava/no-import-test-files': 'error',
31+
'ava/no-inline-assertions': 'error',
3132
'ava/no-invalid-end': 'error',
3233
'ava/no-nested-tests': 'error',
3334
'ava/no-only-test': 'error',

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ Configure it in `package.json`.
4646
"ava/no-identical-title": "error",
4747
"ava/no-ignored-test-files": "error",
4848
"ava/no-import-test-files": "error",
49+
"ava/no-inline-assertions": "error",
4950
"ava/no-invalid-end": "error",
5051
"ava/no-nested-tests": "error",
5152
"ava/no-only-test": "error",
@@ -83,6 +84,7 @@ The rules will only activate in test files.
8384
- [no-identical-title](docs/rules/no-identical-title.md) - Ensure no tests have the same title.
8485
- [no-ignored-test-files](docs/rules/no-ignored-test-files.md) - Ensure no tests are written in ignored files.
8586
- [no-import-test-files](docs/rules/no-import-test-files.md) - Ensure no test files are imported anywhere.
87+
- [no-inline-assertions](docs/rules/no-inline-assertions.md) - Ensure assertions are not called from inline arrow functions. *(fixable)*
8688
- [no-invalid-end](docs/rules/no-invalid-end.md) - Ensure `t.end()` is only called inside `test.cb()`.
8789
- [no-nested-tests](docs/rules/no-nested-tests.md) - Ensure no tests are nested.
8890
- [no-only-test](docs/rules/no-only-test.md) - Ensure no `test.only()` are present. *(fixable)*

rules/no-inline-assertions.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
const {visitIf} = require('enhance-visitors');
3+
const createAvaRule = require('../create-ava-rule');
4+
const util = require('../util');
5+
6+
const create = context => {
7+
const ava = createAvaRule();
8+
9+
return ava.merge({
10+
CallExpression: visitIf([
11+
ava.isInTestFile,
12+
ava.isTestNode
13+
])(node => {
14+
const functionArgIndex = node.arguments.length - 1;
15+
if (functionArgIndex > 1) {
16+
return;
17+
}
18+
19+
const functionArg = node.arguments[functionArgIndex];
20+
21+
if (!util.isFunctionExpression(functionArg)) {
22+
return;
23+
}
24+
25+
const {body} = functionArg;
26+
if (body.type === 'CallExpression') {
27+
context.report({
28+
node,
29+
message: 'The test implementation should not be an inline arrow function.',
30+
fix: fixer => [fixer.insertTextBefore(body, '{'), fixer.insertTextAfter(body, '}')]
31+
});
32+
}
33+
})
34+
});
35+
};
36+
37+
module.exports = {
38+
create,
39+
meta: {
40+
docs: {
41+
url: util.getDocsUrl(__filename)
42+
},
43+
type: 'suggestion',
44+
fixable: 'code'
45+
}
46+
};

test/no-inline-assertions.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import test from 'ava';
2+
import avaRuleTester from 'eslint-ava-rule-tester';
3+
import rule from '../rules/no-inline-assertions';
4+
5+
const ruleTester = avaRuleTester(test, {
6+
env: {
7+
es6: true
8+
}
9+
});
10+
11+
const errors = [{ruleId: 'no-inline-assertions'}];
12+
const header = 'const test = require(\'ava\');\n';
13+
14+
ruleTester.run('no-todo-test', rule, {
15+
valid: [
16+
// Shouldn't be triggered as the test implementation is not an inline arrow function
17+
header + 'test("my test name", t => {\n t.true(fn()); \n});',
18+
header + 'test("my test name", function (t) { foo(); });',
19+
// Shouldn't be triggered since test body is empty
20+
header + 'test("my test name", () => {});',
21+
header + 'test("my test name", t => {});',
22+
// Shouldn't be triggered since test body is ill-defined
23+
header + 'test("my test name", t => "foo");',
24+
// Shouldn't be triggered since it's not a test file
25+
'test.todo("my test name");',
26+
// Shouldn't be triggered since the signature is incorrect
27+
header + 'test.todo("my test name", "bar");',
28+
header + 'test.todo("my test name", undefined, t => {})'
29+
],
30+
invalid: [
31+
{
32+
code: header + 'test("my test name", t => t.skip());',
33+
errors,
34+
output: header + 'test("my test name", t => {t.skip()});'
35+
},
36+
{
37+
code: header + 'test("my test name", t => t.true(fn()));',
38+
errors,
39+
output: header + 'test("my test name", t => {t.true(fn())});'
40+
},
41+
{
42+
code: header + 'test("my test name", t => \n t.true(fn()));',
43+
errors,
44+
output: header + 'test("my test name", t => \n {t.true(fn())});'
45+
}
46+
]
47+
});

0 commit comments

Comments
 (0)