Skip to content
This repository has been archived by the owner on Aug 18, 2020. It is now read-only.

Commit

Permalink
Adds jest/no-if
Browse files Browse the repository at this point in the history
  • Loading branch information
Matt Seccafien committed Mar 22, 2019
1 parent ed1239b commit bdf93cd
Show file tree
Hide file tree
Showing 4 changed files with 371 additions and 4 deletions.
34 changes: 34 additions & 0 deletions docs/rules/jest/no-if.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Prevent if statements in tests. (jest/no-if)
This rule prevents the use of if statements in tests.

## Rule Details

If statments in tests is usually an indication that a test is attempting to cover too much. Each branch of code executing within an if statement will likely be better served by a test devoted to it.

Examples of **incorrect** code for this rule:

```js
it('foo', () => {
if('bar') {
// an if statement here is invalid
// you are probably testing too much
}
})

```

Examples of **correct** code for this rule:

```js
it('foo', () => {
// only test the 'foo' case
})

it('bar', () => {
// test the 'bar' case separately
})
```

## When Not To Use It

If you do not wish to prevent the use of if statements in tests, you can safely disable this rule.
93 changes: 93 additions & 0 deletions lib/rules/jest/no-if.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const {docsUrl} = require('../../utilities');

const TEST_FUNCTION_NAMES = [
'it',
'xit',
'fit',
'test',
'xtest',
'describe',
'fdescribe',
'xdescribe',
];

module.exports = {
meta: {
docs: {
description: 'Prevent if statements in tests.',
category: 'Best Practices',
recommended: false,
uri: docsUrl('jest/no-if'),
},
messages: {
noIf: [
'Tests should not contain if statements.',
'This is usually an indication that you',
'are attempting to test too much at once',
'and may want to consider breaking the if',
'statement out into a separate test.',
].join(' '),
},
},

create(context) {
let inCallExpression = false;

return {
CallExpression(node) {
if (notTestFunction(node) || hasEmptyBody(node)) {
return;
}
inCallExpression = true;
},
IfStatement(node) {
if (!inCallExpression) {
return;
}

context.report({
messageId: 'noIf',
node,
});
},
'CallExpression:exit': () => {
inCallExpression = false;
},
};
},
};

function notTestFunction(node) {
const method = getMethodName(node);
return !matchTestFunctionName(method);
}

function matchTestFunctionName(functionName) {
return TEST_FUNCTION_NAMES.includes(functionName);
}

function hasEmptyBody(node) {
return (
node.arguments &&
node.arguments.length === 2 &&
node.arguments[1].type === 'ArrowFunctionExpression' &&
node.arguments[1].body &&
node.arguments[1].body.body &&
node.arguments[1].body.body.length === 0
);
}

function getMethodName({callee}) {
switch (callee.type) {
case 'CallExpression':
return callee.callee.object
? callee.callee.object.name
: callee.callee.name;
case 'Identifier':
return callee.name;
case 'MemberExpression':
return callee.object.name;
default:
return false;
}
}
240 changes: 240 additions & 0 deletions tests/lib/rules/jest/no-if.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
const {RuleTester} = require('eslint');
const rule = require('../../../../lib/rules/jest/no-if');
require('babel-eslint');

const parser = 'babel-eslint';
const ruleTester = new RuleTester();

ruleTester.run('no-if', rule, {
valid: [
{
code: `if(foo) {}`,
},
{
code: `it('foo', () => {})`,
parser,
},
{
code: `foo('bar', () => {
if(baz) {}
})`,
parser,
},
],
invalid: [
{
code: `it('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `it.skip('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `it.only('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `xit('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `fit('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `describe('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `describe.skip('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `describe.only('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `xdescribe.only('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `fdescribe.only('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `test('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `test.skip('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `test.only('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `xtest('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `ftest('foo', () => {
if('bar') {}
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `describe('foo', () => {
it('bar', () => {
if('bar') {}
})
})`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
{
code: `describe('foo', () => {
it('bar', () => {
if('bar') {}
})
it('baz', () => {
if('qux') {}
if('quux') {}
})
})`,
parser,
errors: [
{
messageId: 'noIf',
},
{
messageId: 'noIf',
},
{
messageId: 'noIf',
},
],
},
{
code: `describe('foo', () => {
if('bar') {}
})
if('baz') {}
`,
parser,
errors: [
{
messageId: 'noIf',
},
],
},
],
});
8 changes: 4 additions & 4 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3320,10 +3320,10 @@ mem@^1.1.0:
dependencies:
mimic-fn "^1.0.0"

merge@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da"
integrity sha1-dTHjnUlJwoGma4xabgJl6LBYlNo=
merge@1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145"
integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==

micromatch@^2.1.5:
version "2.3.11"
Expand Down

0 comments on commit bdf93cd

Please sign in to comment.