Skip to content

Commit

Permalink
feat: add prefer-to-contain rule (#174)
Browse files Browse the repository at this point in the history
Fixes #100
  • Loading branch information
katakonst authored and SimenB committed Oct 14, 2018
1 parent 9466959 commit 83a4c48
Show file tree
Hide file tree
Showing 5 changed files with 385 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Expand Up @@ -97,6 +97,7 @@ for more information about extending configuration files.
| [prefer-strict-equal][] | Suggest using `toStrictEqual()` | | ![fixable-green][] |
| [prefer-to-be-null][] | Suggest using `toBeNull()` | | ![fixable-green][] |
| [prefer-to-be-undefined][] | Suggest using `toBeUndefined()` | | ![fixable-green][] |
| [prefer-to-contain][] | Suggest using `toContain()` | | ![fixable-green][] |
| [prefer-to-have-length][] | Suggest using `toHaveLength()` | ![recommended][] | ![fixable-green][] |
| [prefer-inline-snapshots][] | Suggest using `toMatchInlineSnapshot()` | | ![fixable-green][] |
| [require-tothrow-message][] | Require that `toThrow()` and `toThrowError` includes a message | | |
Expand Down Expand Up @@ -126,6 +127,7 @@ for more information about extending configuration files.
[prefer-strict-equal]: docs/rules/prefer-strict-equal.md
[prefer-to-be-null]: docs/rules/prefer-to-be-null.md
[prefer-to-be-undefined]: docs/rules/prefer-to-be-undefined.md
[prefer-to-contain]: docs/rules/prefer-to-contain.md
[prefer-to-have-length]: docs/rules/prefer-to-have-length.md
[prefer-inline-snapshots]: docs/rules/prefer-inline-snapshots.md
[require-tothrow-message]: docs/rules/require-tothrow-message.md
Expand Down
47 changes: 47 additions & 0 deletions docs/rules/prefer-to-contain.md
@@ -0,0 +1,47 @@
# Suggest using `toContain()` (prefer-to-contain)

In order to have a better failure message, `toContain()` should be used upon
asserting expectations on an array containing an object.

## Rule details

This rule triggers a warning if `toBe()` or `isEqual()` is used to assert object
inclusion in an array

```js
expect(a.includes(b)).toBe(true);
```

```js
expect(a.includes(b)).not.toBe(true);
```

```js
expect(a.includes(b)).toBe(false);
```

### Default configuration

The following patterns are considered a warning:

```js
expect(a.includes(b)).toBe(true);
```

```js
expect(a.includes(b)).not.toBe(true);
```

```js
expect(a.includes(b)).toBe(false);
```

The following patterns are not a warning:

```js
expect(a).toContain(b);
```

```js
expect(a).not.toContain(b);
```
2 changes: 2 additions & 0 deletions index.js
Expand Up @@ -14,6 +14,7 @@ const noTestPrefixes = require('./rules/no-test-prefixes');
const noTestReturnStatement = require('./rules/no-test-return-statement');
const preferToBeNull = require('./rules/prefer-to-be-null');
const preferToBeUndefined = require('./rules/prefer-to-be-undefined');
const preferToContain = require('./rules/prefer-to-contain');
const preferToHaveLength = require('./rules/prefer-to-have-length');
const validDescribe = require('./rules/valid-describe');
const validExpect = require('./rules/valid-expect');
Expand Down Expand Up @@ -84,6 +85,7 @@ module.exports = {
'no-test-return-statement': noTestReturnStatement,
'prefer-to-be-null': preferToBeNull,
'prefer-to-be-undefined': preferToBeUndefined,
'prefer-to-contain': preferToContain,
'prefer-to-have-length': preferToHaveLength,
'valid-describe': validDescribe,
'valid-expect': validExpect,
Expand Down
207 changes: 207 additions & 0 deletions rules/__tests__/prefer-to-contain.test.js
@@ -0,0 +1,207 @@
'use strict';

const RuleTester = require('eslint').RuleTester;
const rule = require('../prefer-to-contain');

const ruleTester = new RuleTester();

ruleTester.run('prefer-to-contain', rule, {
valid: [
'expect(a).toContain(b);',
"expect(a.name).toBe('b');",
'expect(a).toBe(true);',
`expect(a).toEqual(b)`,
`expect(a.test(c)).toEqual(b)`,
`expect(a.includes(b)).toEqual()`,
`expect(a.includes(b)).toEqual("test")`,
`expect(a.includes(b)).toBe("test")`,
`expect(a.includes()).toEqual()`,
`expect(a.includes()).toEqual(true)`,
`expect(a.includes(b,c)).toBe(true)`,
`expect([{a:1}]).toContain({a:1})`,
`expect([1].includes(1)).toEqual`,
`expect([1].includes).toEqual`,
`expect([1].includes).not`,
`expect(a.test(b)).resolves.toEqual(true)`,
`expect(a.test(b)).resolves.not.toEqual(true)`,
`expect(a).not.toContain(b)`,
],
invalid: [
{
code: 'expect(a.includes(b)).toEqual(true);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).toContain(b);',
},
{
code: 'expect(a.includes(b)).toEqual(false);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).not.toContain(b);',
},
{
code: 'expect(a.includes(b)).not.toEqual(false);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).toContain(b);',
},
{
code: 'expect(a.includes(b)).not.toEqual(true);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).not.toContain(b);',
},
{
code: 'expect(a.includes(b)).toBe(true);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).toContain(b);',
},
{
code: 'expect(a.includes(b)).toBe(false);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).not.toContain(b);',
},
{
code: 'expect(a.includes(b)).not.toBe(false);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).toContain(b);',
},
{
code: 'expect(a.includes(b)).not.toBe(true);',
errors: [
{
message: 'Use toContain() instead',
column: 23,
line: 1,
},
],
output: 'expect(a).not.toContain(b);',
},
{
code: 'expect(a.test(t).includes(b.test(p))).toEqual(true);',
errors: [
{
message: 'Use toContain() instead',
column: 39,
line: 1,
},
],
output: 'expect(a.test(t)).toContain(b.test(p));',
},
{
code: 'expect(a.test(t).includes(b.test(p))).toEqual(false);',
errors: [
{
message: 'Use toContain() instead',
column: 39,
line: 1,
},
],
output: 'expect(a.test(t)).not.toContain(b.test(p));',
},
{
code: 'expect(a.test(t).includes(b.test(p))).not.toEqual(true);',
errors: [
{
message: 'Use toContain() instead',
column: 39,
line: 1,
},
],
output: 'expect(a.test(t)).not.toContain(b.test(p));',
},
{
code: 'expect(a.test(t).includes(b.test(p))).not.toEqual(false);',
errors: [
{
message: 'Use toContain() instead',
column: 39,
line: 1,
},
],
output: 'expect(a.test(t)).toContain(b.test(p));',
},
{
code: 'expect([{a:1}].includes({a:1})).toBe(true);',
errors: [
{
message: 'Use toContain() instead',
column: 33,
line: 1,
},
],
output: 'expect([{a:1}]).toContain({a:1});',
},
{
code: 'expect([{a:1}].includes({a:1})).toBe(false);',
errors: [
{
message: 'Use toContain() instead',
column: 33,
line: 1,
},
],
output: 'expect([{a:1}]).not.toContain({a:1});',
},
{
code: 'expect([{a:1}].includes({a:1})).not.toBe(true);',
errors: [
{
message: 'Use toContain() instead',
column: 33,
line: 1,
},
],
output: 'expect([{a:1}]).not.toContain({a:1});',
},
{
code: 'expect([{a:1}].includes({a:1})).not.toBe(false);',
errors: [
{
message: 'Use toContain() instead',
column: 33,
line: 1,
},
],
output: 'expect([{a:1}]).toContain({a:1});',
},
],
});

0 comments on commit 83a4c48

Please sign in to comment.