Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement rules for preferences for true/false/null #359

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ Rule | Recommended | Options
[prefer-promise-strategies][] | 1 |
[prefer-toHaveBeenCalledWith][] | 1 |
[prefer-toBeUndefined][] | 0 | `['always', 'never']`
[prefer-toBeNull][] | 0 | `['always', 'never']`
[prefer-toBeTrue][] | 0 | `['always', 'never']`
[prefer-toBeFalse][] | 0 | `['always', 'never']`


For example, using the recommended configuration, the `no-focused-tests` rule
Expand Down Expand Up @@ -135,6 +138,9 @@ See [configuring rules][] for more information.
[prefer-promise-strategies]: docs/rules/prefer-promise-strategies.md
[prefer-toHaveBeenCalledWith]: docs/rules/prefer-toHaveBeenCalledWith.md
[prefer-toBeUndefined]: docs/rules/prefer-toBeUndefined.md
[prefer-toBeNull]: docs/rules/prefer-toBeNull.md
[prefer-toBeTrue]: docs/rules/prefer-toBeTrue.md
[prefer-toBeFalse]: docs/rules/prefer-toBeFalse.md

[configuring rules]: http://eslint.org/docs/user-guide/configuring#configuring-rules

Expand Down
51 changes: 51 additions & 0 deletions docs/rules/prefer-toBeFalse.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Prefer toBeFalse

This rule recommends using `toBeFalse` instead of the more generic matcher
`toBe(false)`.

## Rule details

This rule forces a codebase to be consistent when expecting values to be
`false` in unit tests.

## Options

### always

The `"always"` option (default) prefers `toBeFalse()`. Select this option
if you'd like developers to use a matcher that tests specifically for
`false`.

Examples of *incorrect* code for the `"always"` option:

```js
expect(value).toBe(false);
expect(value).toBe(false, 'with an explanation');
```

Examples of *correct* code for the `"always"` option:

```js
expect(value).toBeFalse();
expect(value).toBeFalse('with an explanation');
```

### never

The `"never"` option prefers `toBe(false)`. Select this option if you'd
like developers to use the `toBe` matcher consistently, whether testing
for `false` or not.

Examples of *incorrect* code for the `"never"` option:

```js
expect(value).toBeFalse();
expect(value).toBeFalse('with an explanation');
```

Examples of *correct* code for the `"never"` option:

```js
expect(value).toBe(false);
expect(value).toBe(false, 'with an explanation');
```
51 changes: 51 additions & 0 deletions docs/rules/prefer-toBeNull.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Prefer toBeNull

This rule recommends using `toBeNull` instead of the more generic matcher
`toBe(null)`.

## Rule details

This rule forces a codebase to be consistent when expecting values to be
`null` in unit tests.

## Options

### always

The `"always"` option (default) prefers `toBeNull()`. Select this option
if you'd like developers to use a matcher that tests specifically for
`null`.

Examples of *incorrect* code for the `"always"` option:

```js
expect(value).toBe(null);
expect(value).toBe(null, 'with an explanation');
```

Examples of *correct* code for the `"always"` option:

```js
expect(value).toBeNull();
expect(value).toBeNull('with an explanation');
```

### never

The `"never"` option prefers `toBe(null)`. Select this option if you'd
like developers to use the `toBe` matcher consistently, whether testing
for `null` or not.

Examples of *incorrect* code for the `"never"` option:

```js
expect(value).toBeNull();
expect(value).toBeNull('with an explanation');
```

Examples of *correct* code for the `"never"` option:

```js
expect(value).toBe(null);
expect(value).toBe(null, 'with an explanation');
```
51 changes: 51 additions & 0 deletions docs/rules/prefer-toBeTrue.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Prefer toBeTrue

This rule recommends using `toBeTrue` instead of the more generic matcher
`toBe(true)`.

## Rule details

This rule forces a codebase to be consistent when expecting values to be
`true` in unit tests.

## Options

### always

The `"always"` option (default) prefers `toBeTrue()`. Select this option
if you'd like developers to use a matcher that tests specifically for
`true`.

Examples of *incorrect* code for the `"always"` option:

```js
expect(value).toBe(true);
expect(value).toBe(true, 'with an explanation');
```

Examples of *correct* code for the `"always"` option:

```js
expect(value).toBeTrue();
expect(value).toBeTrue('with an explanation');
```

### never

The `"never"` option prefers `toBe(true)`. Select this option if you'd
like developers to use the `toBe` matcher consistently, whether testing
for `true` or not.

Examples of *incorrect* code for the `"never"` option:

```js
expect(value).toBeTrue();
expect(value).toBeTrue('with an explanation');
```

Examples of *correct* code for the `"never"` option:

```js
expect(value).toBe(true);
expect(value).toBe(true, 'with an explanation');
```
5 changes: 4 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ module.exports = {
'prefer-jasmine-matcher': require('./lib/rules/prefer-jasmine-matcher'),
'prefer-promise-strategies': require('./lib/rules/prefer-promise-strategies'),
'prefer-toHaveBeenCalledWith': require('./lib/rules/prefer-toHaveBeenCalledWith'),
'prefer-toBeUndefined': require('./lib/rules/prefer-toBeUndefined')
'prefer-toBeUndefined': require('./lib/rules/prefer-toBeUndefined'),
'prefer-toBeNull': require('./lib/rules/prefer-toBeNull'),
'prefer-toBeTrue': require('./lib/rules/prefer-toBeTrue'),
'prefer-toBeFalse': require('./lib/rules/prefer-toBeFalse')
},
configs: {
recommended: {
Expand Down
55 changes: 55 additions & 0 deletions lib/rules/prefer-toBeFalse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict'

/**
* @fileoverview Prefer toBeTrue instead of toBe(true)
* @author Osama Yousry
*/

module.exports = {
meta: {
schema: [
{
enum: ['always', 'never']
}
],
fixable: 'code'
},
create: function (context) {
const always = context.options[0] !== 'never'

return {
CallExpression: function (node) {
if (always) {
if (node.callee.type === 'MemberExpression' && node.callee.property.name === 'toBe' &&
node.arguments[0] && node.arguments[0].type === 'Literal' && node.arguments[0].value === false) {
context.report({
message: 'Prefer toBeFalse() to expect false',
node: node.callee.property,
fix: function (fixer) {
if (node.arguments.length === 1) {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[0].end], 'toBeFalse(')
} else {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[1].start], 'toBeFalse(')
}
}
})
}
} else {
if (node.callee.type === 'MemberExpression' && node.callee.property.name === 'toBeFalse') {
context.report({
message: 'Prefer toBe(false) to expect false',
node: node.callee.property,
fix: function (fixer) {
if (node.arguments.length === 0) {
return fixer.replaceTextRange([node.callee.property.start, node.end], 'toBe(false)')
} else {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[0].start], 'toBe(false, ')
}
}
})
}
}
}
}
}
}
55 changes: 55 additions & 0 deletions lib/rules/prefer-toBeNull.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict'

/**
* @fileoverview Prefer toBeNull instead of toBe(null)
* @author Osama Yousry
*/

module.exports = {
meta: {
schema: [
{
enum: ['always', 'never']
}
],
fixable: 'code'
},
create: function (context) {
const always = context.options[0] !== 'never'

return {
CallExpression: function (node) {
if (always) {
if (node.callee.type === 'MemberExpression' && node.callee.property.name === 'toBe' &&
node.arguments[0] && node.arguments[0].type === 'Literal' && node.arguments[0].value === null) {
context.report({
message: 'Prefer toBeNull() to expect null',
node: node.callee.property,
fix: function (fixer) {
if (node.arguments.length === 1) {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[0].end], 'toBeNull(')
} else {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[1].start], 'toBeNull(')
}
}
})
}
} else {
if (node.callee.type === 'MemberExpression' && node.callee.property.name === 'toBeNull') {
context.report({
message: 'Prefer toBe(null) to expect null',
node: node.callee.property,
fix: function (fixer) {
if (node.arguments.length === 0) {
return fixer.replaceTextRange([node.callee.property.start, node.end], 'toBe(null)')
} else {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[0].start], 'toBe(null, ')
}
}
})
}
}
}
}
}
}
55 changes: 55 additions & 0 deletions lib/rules/prefer-toBeTrue.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict'

/**
* @fileoverview Prefer toBeTrue instead of toBe(true)
* @author Osama Yousry
*/

module.exports = {
meta: {
schema: [
{
enum: ['always', 'never']
}
],
fixable: 'code'
},
create: function (context) {
const always = context.options[0] !== 'never'

return {
CallExpression: function (node) {
if (always) {
if (node.callee.type === 'MemberExpression' && node.callee.property.name === 'toBe' &&
node.arguments[0] && node.arguments[0].type === 'Literal' && node.arguments[0].value === true) {
context.report({
message: 'Prefer toBeTrue() to expect true',
node: node.callee.property,
fix: function (fixer) {
if (node.arguments.length === 1) {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[0].end], 'toBeTrue(')
} else {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[1].start], 'toBeTrue(')
}
}
})
}
} else {
if (node.callee.type === 'MemberExpression' && node.callee.property.name === 'toBeTrue') {
context.report({
message: 'Prefer toBe(true) to expect true',
node: node.callee.property,
fix: function (fixer) {
if (node.arguments.length === 0) {
return fixer.replaceTextRange([node.callee.property.start, node.end], 'toBe(true)')
} else {
return fixer.replaceTextRange([node.callee.property.start, node.arguments[0].start], 'toBe(true, ')
}
}
})
}
}
}
}
}
}
Loading