Skip to content

Commit 0f7c6ba

Browse files
committed
feat: add prefer-to-be-defined rule
BREAKING CHANGE: prefer-to-be-undefined rule has been removed and merged into this rule.
1 parent e3f8884 commit 0f7c6ba

File tree

8 files changed

+180
-109
lines changed

8 files changed

+180
-109
lines changed

README.md

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,22 +72,22 @@ config file:
7272
}
7373
```
7474

75-
See
76-
[ESLint documentation](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
75+
See [ESLint
76+
documentation](http://eslint.org/docs/user-guide/configuring#extending-configuration-files)
7777
for more information about extending configuration files.
7878

7979
## Rules
8080

81-
| Rule | Description | Recommended | Fixable |
82-
| -------------------------------------------------------------- | ----------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------- |
83-
| [no-disabled-tests](docs/rules/no-disabled-tests.md) | Disallow disabled tests | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
84-
| [no-focused-tests](docs/rules/no-focused-tests.md) | Disallow focused tests | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
85-
| [no-identical-title](docs/rules/no-unhandled-errors.md) | Disallow identical titles | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
86-
| [no-large-snapshots](docs/rules/no-large-snapshots.md) | Disallow large snapshots | | |
87-
| [prefer-to-have-length](docs/rules/prefer-to-have-length.md) | Suggest using toHaveLength() | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | ![fixable](https://img.shields.io/badge/-fixable-green.svg) |
88-
| [prefer-to-be-null](docs/rules/prefer-to-be-null.md) | Suggest using toBeNull() | | ![fixable](https://img.shields.io/badge/-fixable-green.svg) |
89-
| [prefer-to-be-undefined](docs/rules/prefer-to-be-undefined.md) | Suggest using toBeUndefined() | | ![fixable](https://img.shields.io/badge/-fixable-green.svg) |
90-
| [valid-expect](docs/rules/valid-expect.md) | Enforce valid expect() usage | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
81+
| Rule | Description | Recommended | Fixable |
82+
| ------------------------------------------------------------ | --------------------------------------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------- |
83+
| [no-disabled-tests](docs/rules/no-disabled-tests.md) | Disallow disabled tests | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
84+
| [no-focused-tests](docs/rules/no-focused-tests.md) | Disallow focused tests | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
85+
| [no-identical-title](docs/rules/no-unhandled-errors.md) | Disallow identical titles | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
86+
| [no-large-snapshots](docs/rules/no-large-snapshots.md) | Disallow large snapshots | | |
87+
| [prefer-to-have-length](docs/rules/prefer-to-have-length.md) | Suggest using toHaveLength() | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | ![fixable](https://img.shields.io/badge/-fixable-green.svg) |
88+
| [prefer-to-be-null](docs/rules/prefer-to-be-null.md) | Suggest using toBeNull() | | ![fixable](https://img.shields.io/badge/-fixable-green.svg) |
89+
| [prefer-to-be-defined](docs/rules/prefer-to-be-defined.md) | Suggest using toBeDefined() / toBeUndefined() | | ![fixable](https://img.shields.io/badge/-fixable-green.svg) |
90+
| [valid-expect](docs/rules/valid-expect.md) | Enforce valid expect() usage | ![recommended](https://img.shields.io/badge/-recommended-lightgrey.svg) | |
9191

9292
## Credit
9393

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

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

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

Lines changed: 0 additions & 28 deletions
This file was deleted.

index.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ const noFocusedTests = require('./rules/no_focused_tests');
55
const noIdenticalTitle = require('./rules/no_identical_title');
66
const noLargeSnapshots = require('./rules/no_large_snapshots');
77
const preferToBeNull = require('./rules/prefer_to_be_null');
8-
const preferToBeUndefined = require('./rules/prefer_to_be_undefined');
8+
const preferToBeDefined = require('./rules/prefer_to_be_defined');
99
const preferToHaveLength = require('./rules/prefer_to_have_length');
1010
const validExpect = require('./rules/valid_expect');
1111

@@ -55,7 +55,7 @@ module.exports = {
5555
'no-identical-title': noIdenticalTitle,
5656
'no-large-snapshots': noLargeSnapshots,
5757
'prefer-to-be-null': preferToBeNull,
58-
'prefer-to-be-undefined': preferToBeUndefined,
58+
'prefer-to-be-defined': preferToBeDefined,
5959
'prefer-to-have-length': preferToHaveLength,
6060
'valid-expect': validExpect,
6161
},
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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: [
10+
'expect(true).toBeDefined();',
11+
'expect(true).not.toBeDefined();',
12+
'expect(true).toBe(true);',
13+
'expect(undefined).toBeUndefined();',
14+
'expect({}).toEqual({});',
15+
'expect(null).toEqual(null);',
16+
],
17+
18+
invalid: [
19+
{
20+
code: 'expect(true).not.toBe(undefined);',
21+
errors: [
22+
{
23+
message: 'Use toBeDefined() instead',
24+
column: 14,
25+
line: 1,
26+
},
27+
],
28+
output: 'expect(true).toBeDefined();',
29+
},
30+
{
31+
code: 'expect(true).not.toEqual(undefined);',
32+
errors: [
33+
{
34+
message: 'Use toBeDefined() instead',
35+
column: 14,
36+
line: 1,
37+
},
38+
],
39+
output: 'expect(true).toBeDefined();',
40+
},
41+
{
42+
code: 'expect(true).not.toBeUndefined();',
43+
errors: [
44+
{
45+
message: 'Use toBeDefined() instead',
46+
column: 14,
47+
line: 1,
48+
},
49+
],
50+
output: 'expect(true).toBeDefined();',
51+
},
52+
{
53+
code: 'expect(undefined).toBe(undefined);',
54+
errors: [
55+
{
56+
message: 'Use toBeUndefined() instead',
57+
column: 19,
58+
line: 1,
59+
},
60+
],
61+
output: 'expect(undefined).toBeUndefined();',
62+
},
63+
{
64+
code: 'expect(undefined).toEqual(undefined);',
65+
errors: [
66+
{
67+
message: 'Use toBeUndefined() instead',
68+
column: 19,
69+
line: 1,
70+
},
71+
],
72+
output: 'expect(undefined).toBeUndefined();',
73+
},
74+
],
75+
});

rules/__tests__/prefer_to_be_undefined.test.js

Lines changed: 0 additions & 40 deletions
This file was deleted.

rules/prefer_to_be_defined.js

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
'use strict';
2+
const argument = require('./util').argument;
3+
const argument2 = require('./util').argument2;
4+
const expectNotToBeCase = require('./util').expectNotToBeCase;
5+
const expectNotToBeUndefinedCase = require('./util').expectNotToBeUndefinedCase;
6+
const expectNotToEqualCase = require('./util').expectNotToEqualCase;
7+
const expectToBeCase = require('./util').expectToBeCase;
8+
const expectToEqualCase = require('./util').expectToEqualCase;
9+
const method = require('./util').method;
10+
const method2 = require('./util').method2;
11+
12+
module.exports = context => {
13+
return {
14+
CallExpression(node) {
15+
if (
16+
expectNotToBeCase(node, undefined) ||
17+
expectNotToEqualCase(node, undefined) ||
18+
expectNotToBeUndefinedCase(node)
19+
) {
20+
context.report({
21+
fix(fixer) {
22+
const propertyDot = context
23+
.getSourceCode()
24+
.getFirstTokenBetween(
25+
method(node),
26+
method2(node),
27+
token => token.value === '.'
28+
);
29+
const fixes = [
30+
fixer.remove(method(node)),
31+
fixer.remove(propertyDot),
32+
fixer.replaceText(method2(node), 'toBeDefined'),
33+
];
34+
if (argument2(node)) {
35+
fixes.push(fixer.remove(argument2(node)));
36+
}
37+
return fixes;
38+
},
39+
message: 'Use toBeDefined() instead',
40+
node: method(node),
41+
});
42+
} else if (
43+
expectToBeCase(node, undefined) ||
44+
expectToEqualCase(node, undefined)
45+
) {
46+
context.report({
47+
fix(fixer) {
48+
return [
49+
fixer.replaceText(method(node), 'toBeUndefined'),
50+
fixer.remove(argument(node)),
51+
];
52+
},
53+
message: 'Use toBeUndefined() instead',
54+
node: method(node),
55+
});
56+
}
57+
},
58+
};
59+
};

rules/prefer_to_be_undefined.js

Lines changed: 0 additions & 27 deletions
This file was deleted.

0 commit comments

Comments
 (0)