Skip to content

Commit 73894e2

Browse files
committed
Add prefer-to-be-defined rule
1 parent 4bbec5f commit 73894e2

File tree

5 files changed

+136
-0
lines changed

5 files changed

+136
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ Then configure the rules you want to use under the rules section.
3232
"jest/no-disabled-tests": "warn",
3333
"jest/no-focused-tests": "error",
3434
"jest/no-identical-title": "error",
35+
"jest/prefer-to-be-defined": "warn",
3536
"jest/prefer-to-have-length": "warn",
3637
"jest/valid-expect": "error"
3738
}
@@ -55,6 +56,8 @@ You can also whitelist the environment variables provided by Jest by doing:
5556
* [no-focused-tests](/docs/rules/no-focused-tests.md) - disallow focused tests.
5657
* [no-identical-title](/docs/rules/no-identical-title.md) - disallow identical
5758
titles.
59+
* [prefer-to-be-defined](/docs/rules/prefer-to-be-defined.md) - suggest using
60+
`toBeDefined()`.
5861
* [prefer-to-have-length](/docs/rules/prefer-to-have-length.md) - suggest using
5962
`toHaveLength()`.
6063
* [valid-expect](/docs/rules/valid-expect.md) - ensure expect is called
@@ -85,6 +88,7 @@ The rules enabled in this configuration are:
8588
* [jest/no-disabled-tests](/docs/rules/no-disabled-tests.md)
8689
* [jest/no-focused-tests](/docs/rules/no-focused-tests.md)
8790
* [jest/no-identical-title](/docs/rules/no-identical-title.md)
91+
* [jest/prefer-to-be-defined](/docs/rules/prefer-to-be-defined.md)
8892
* [jest/prefer-to-have-length](/docs/rules/prefer-to-have-length.md)
8993
* [jest/valid-expect](/docs/rules/valid-expect.md)
9094

docs/rules/prefer-to-be-defined.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Suggest using `toBeDefined()` (prefer-to-be-defined)
2+
3+
In order to have a better failure message, `toBeDefined()` should be used upon
4+
asserting expections on defined value.
5+
6+
## Rule details
7+
8+
This rule triggers a warning if `not.toBe()` is used to assert a undefined
9+
value.
10+
11+
```js
12+
expect(true).not.toBe(undefined);
13+
```
14+
15+
This rule is enabled by default.
16+
17+
### Default configuration
18+
19+
The following patterns are considered warning:
20+
21+
```js
22+
expect(true).not.toBeUndefined();
23+
```
24+
25+
The following pattern is not warning:
26+
27+
```js
28+
expect(true).toBeDefined();
29+
```

index.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const noDisabledTests = require('./rules/no_disabled_tests');
44
const noFocusedTests = require('./rules/no_focused_tests');
55
const noIdenticalTitle = require('./rules/no_identical_title');
6+
const preferToBeDefined = require('./rules/prefer_to_be_defined');
67
const preferToHaveLength = require('./rules/prefer_to_have_length');
78
const validExpect = require('./rules/valid_expect');
89

@@ -13,6 +14,7 @@ module.exports = {
1314
'jest/no-disabled-tests': 'warn',
1415
'jest/no-focused-tests': 'error',
1516
'jest/no-identical-title': 'error',
17+
'jest/prefer-to-be-defined': 'warn',
1618
'jest/prefer-to-have-length': 'warn',
1719
'jest/valid-expect': 'error',
1820
},
@@ -45,6 +47,7 @@ module.exports = {
4547
'no-disabled-tests': noDisabledTests,
4648
'no-focused-tests': noFocusedTests,
4749
'no-identical-title': noIdenticalTitle,
50+
'prefer-to-be-defined': preferToBeDefined,
4851
'prefer-to-have-length': preferToHaveLength,
4952
'valid-expect': validExpect,
5053
},
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
'use strict';
2+
3+
const RuleTester = require('eslint').RuleTester;
4+
const rules = require('../../').rules;
5+
6+
const ruleTester = new RuleTester();
7+
8+
ruleTester.run('prefer_to_be_defined', rules['prefer-to-be-defined'], {
9+
valid: ['expect(true).toBeDefined();'],
10+
11+
invalid: [
12+
{
13+
code: 'expect(true).not.toBe(undefined);',
14+
errors: [
15+
{
16+
message: 'Use toBeDefined() instead',
17+
column: 14,
18+
line: 1,
19+
},
20+
],
21+
output: 'expect(true).toBeDefined();',
22+
},
23+
{
24+
code: 'expect(true).not.toEqual(undefined);',
25+
errors: [
26+
{
27+
message: 'Use toBeDefined() instead',
28+
column: 14,
29+
line: 1,
30+
},
31+
],
32+
output: 'expect(true).toBeDefined();',
33+
},
34+
{
35+
code: 'expect(true).not.toBeUndefined();',
36+
errors: [
37+
{
38+
message: 'Use toBeDefined() instead',
39+
column: 14,
40+
line: 1,
41+
},
42+
],
43+
output: 'expect(true).toBeDefined();',
44+
},
45+
],
46+
});

rules/prefer_to_be_defined.js

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
'use strict';
2+
3+
module.exports = context => {
4+
return {
5+
CallExpression(node) {
6+
const calleeName = node.callee.name;
7+
8+
if (
9+
calleeName === 'expect' &&
10+
node.arguments.length == 1 &&
11+
node.parent &&
12+
node.parent.type === 'MemberExpression' &&
13+
node.parent.parent &&
14+
node.parent.parent.type === 'MemberExpression'
15+
) {
16+
const parentProperty = node.parent.property;
17+
const propertyName = parentProperty.name;
18+
const parentProperty2 = node.parent.parent.property;
19+
const propertyName2 = parentProperty2.name;
20+
const argument = node.parent.parent.parent.arguments[0];
21+
22+
if (
23+
(propertyName === 'not' &&
24+
(propertyName2 === 'toBe' || propertyName2 === 'toEqual') &&
25+
argument.value === undefined) ||
26+
(propertyName === 'not' && propertyName2 === 'toBeUndefined')
27+
) {
28+
context.report({
29+
fix(fixer) {
30+
const propertyDot = context
31+
.getSourceCode()
32+
.getFirstTokenBetween(
33+
parentProperty,
34+
parentProperty2,
35+
token => token.value === '.'
36+
);
37+
const fixes = [
38+
fixer.remove(parentProperty),
39+
fixer.remove(propertyDot),
40+
fixer.replaceText(parentProperty2, 'toBeDefined'),
41+
];
42+
if (argument) {
43+
fixes.push(fixer.remove(argument));
44+
}
45+
return fixes;
46+
},
47+
message: 'Use toBeDefined() instead',
48+
node: parentProperty,
49+
});
50+
}
51+
}
52+
},
53+
};
54+
};

0 commit comments

Comments
 (0)