Skip to content

Commit

Permalink
Add no-incorrect-deep-equal rule (#264)
Browse files Browse the repository at this point in the history
  • Loading branch information
MrHen authored and sindresorhus committed Jul 6, 2019
1 parent 348c4e8 commit ff4f760
Show file tree
Hide file tree
Showing 5 changed files with 427 additions and 0 deletions.
29 changes: 29 additions & 0 deletions docs/rules/no-incorrect-deep-equal.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Avoid using `deepEqual` with primitives

The `deepEqual` and `notDeepEqual` assertions are unnecessary when comparing primitives. Use `is` or `not` instead.

This rule is fixable.


## Fail

```js
t.deepEqual(expression, 'foo');
t.deepEqual(expression, 1);
t.deepEqual(expression, `foo${bar}`);
t.deepEqual(expression, null);
t.deepEqual(expression, undefined);
t.notDeepEqual(expression, undefined);
```


## Pass

```js
t.is(expression, 'foo');

t.deepEqual(expression, otherExpression);
t.deepEqual(expression, {});
t.deepEqual(expression, []);
t.notDeepEqual(expression, []);
```
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ module.exports = {
'ava/no-identical-title': 'error',
'ava/no-ignored-test-files': 'error',
'ava/no-import-test-files': 'error',
'ava/no-incorrect-deep-equal': 'error',
'ava/no-inline-assertions': 'error',
'ava/no-invalid-end': 'error',
'ava/no-nested-tests': 'error',
Expand Down
2 changes: 2 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ Configure it in `package.json`.
"ava/no-identical-title": "error",
"ava/no-ignored-test-files": "error",
"ava/no-import-test-files": "error",
"ava/no-incorrect-deep-equal": "error",
"ava/no-inline-assertions": "error",
"ava/no-invalid-end": "error",
"ava/no-nested-tests": "error",
Expand Down Expand Up @@ -86,6 +87,7 @@ The rules will only activate in test files.
- [no-identical-title](docs/rules/no-identical-title.md) - Ensure no tests have the same title.
- [no-ignored-test-files](docs/rules/no-ignored-test-files.md) - Ensure no tests are written in ignored files.
- [no-import-test-files](docs/rules/no-import-test-files.md) - Ensure no test files are imported anywhere.
- [no-incorrect-deep-equal](docs/rules/no-incorrect-deep-equal.md) - Avoid using `deepEqual` with primitives. *(fixable)*
- [no-inline-assertions](docs/rules/no-inline-assertions.md) - Ensure assertions are not called from inline arrow functions. *(fixable)*
- [no-invalid-end](docs/rules/no-invalid-end.md) - Ensure `t.end()` is only called inside `test.cb()`.
- [no-nested-tests](docs/rules/no-nested-tests.md) - Ensure no tests are nested.
Expand Down
93 changes: 93 additions & 0 deletions rules/no-incorrect-deep-equal.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
'use strict';
const {visitIf} = require('enhance-visitors');
const util = require('../util');
const createAvaRule = require('../create-ava-rule');

const MESSAGE_ID = 'no-deep-equal-with-primative';

const buildDeepEqualMessage = (context, node) => {
context.report({
node,
messageId: MESSAGE_ID,
data: {
callee: node.callee.property.name
},
fix: fixer => fixer.replaceText(node.callee.property, 'is')
});
};

const buildNotDeepEqualMessage = (context, node) => {
context.report({
node,
messageId: MESSAGE_ID,
data: {
callee: node.callee.property.name
},
fix: fixer => fixer.replaceText(node.callee.property, 'not')
});
};

const create = context => {
const ava = createAvaRule();

const callExpression = 'CallExpression';
const deepEqual = '[callee.property.name="deepEqual"]';
const notDeepEqual = '[callee.property.name="notDeepEqual"]';

const argumentsLiteral = ':matches([arguments.0.type="Literal"],[arguments.1.type="Literal"])';
const argumentsUndefined = ':matches([arguments.0.type="Identifier"][arguments.0.name="undefined"],[arguments.1.type="Identifier"][arguments.1.name="undefined"])';
const argumentsTemplate = ':matches([arguments.0.type="TemplateLiteral"],[arguments.1.type="TemplateLiteral"])';

return ava.merge({
[`${callExpression}${deepEqual}${argumentsLiteral}`]: visitIf([
ava.isInTestFile,
ava.isInTestNode
])(node => {
buildDeepEqualMessage(context, node);
}),
[`${callExpression}${deepEqual}${argumentsUndefined}`]: visitIf([
ava.isInTestFile,
ava.isInTestNode
])(node => {
buildDeepEqualMessage(context, node);
}),
[`${callExpression}${deepEqual}${argumentsTemplate}`]: visitIf([
ava.isInTestFile,
ava.isInTestNode
])(node => {
buildDeepEqualMessage(context, node);
}),
[`${callExpression}${notDeepEqual}${argumentsLiteral}`]: visitIf([
ava.isInTestFile,
ava.isInTestNode
])(node => {
buildNotDeepEqualMessage(context, node);
}),
[`${callExpression}${notDeepEqual}${argumentsUndefined}`]: visitIf([
ava.isInTestFile,
ava.isInTestNode
])(node => {
buildNotDeepEqualMessage(context, node);
}),
[`${callExpression}${notDeepEqual}${argumentsTemplate}`]: visitIf([
ava.isInTestFile,
ava.isInTestNode
])(node => {
buildNotDeepEqualMessage(context, node);
})
});
};

module.exports = {
create,
meta: {
docs: {
url: util.getDocsUrl(__filename)
},
fixable: true,
messages: {
[MESSAGE_ID]: 'Avoid using `{{callee}}` with literal primitives'
},
type: 'suggestion'
}
};
Loading

0 comments on commit ff4f760

Please sign in to comment.