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

feat(rule): add no-focused-tests rule #82

Closed
wants to merge 2 commits into from
Closed
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
30 changes: 30 additions & 0 deletions docs/rules/no-focused-tests.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Disallow focused tests (no-focused-tests)

Inspired by the [`no-focused-tests` rule in `eslint-plugin-jest`](https://github.com/jest-community/eslint-plugin-jest/blob/19e3a6e7b71a25881b7b75531f2d8aad32d9d589/docs/rules/no-focused-tests.md), this rule reminds you to remove `.only` from your Cypress tests.

## Rule Details

This rule detects occurrences of `describe.only` and `it.only` in the source code.

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

```js
describe.only(('my describe block'), () => {
it('works', () => {});
});
describe(('my describe block'), () => {
it.only('works', () => {});
});
```

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

```js
describe(('my describe block'), () => {
it('works', () => {});
});
```

## When Not To Use It

If you want to run only one test case and/or describe block, you may not want to use this rule.
89 changes: 89 additions & 0 deletions lib/rules/no-focused-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
/**
* @fileoverview Disallow focused tests
* @author Jonathan Chaffer
*/
'use strict'

module.exports = {
meta: {
docs: {
description: 'Disallow focused tests',
category: 'Possible Errors',
recommended: true,
},
fixable: null, // or "code" or "whitespace"
schema: [],
messages: {
unexpected: 'Do not use focused tests',
},
},

create (context) {
return {
CallExpression (node) {
if (!isTestCaseCall(node) && !isDescribeCall(node)) {
return
}

const onlyNode = findOnlyNode(node)

if (!onlyNode) {
return
}

context.report({
node: onlyNode,
messageId: 'unexpected',
})
},
}
},
}

function nodeIsCalledBy (name, node) {
if (node.type === 'Identifier' && node.name === name) return true

if (
typeof node.callee === 'undefined' ||
typeof node.callee.object === 'undefined'
) {
return false
}

return nodeIsCalledBy(name, node.callee.object)
}

function isDescribeCall (node) {
return (
node.callee.type === 'MemberExpression' &&
nodeIsCalledBy('describe', node) &&
node.callee.property.type === 'Identifier'
)
}

function isTestCaseCall (node) {
return (
node.callee.type === 'MemberExpression' &&
nodeIsCalledBy('it', node) &&
node.callee.property.type === 'Identifier'
)
}

function findOnlyNode (node) {
const callee =
node.callee.type === 'TaggedTemplateExpression'
? node.callee.tag
: node.callee.type === 'CallExpression'
? node.callee.callee
: node.callee

if (callee.type === 'MemberExpression') {
if (callee.object.type === 'MemberExpression') {
return callee.object.property
}

return callee.property
}

return null
}
45 changes: 45 additions & 0 deletions tests/lib/rules/no-focused-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/**
* @fileoverview Disallow focused tests
* @author Jonathan Chaffer
*/
'use strict'

//------------------------------------------------------------------------------
// Requirements
//------------------------------------------------------------------------------

let rule = require('../../../lib/rules/no-focused-tests')

let RuleTester = require('eslint').RuleTester

//------------------------------------------------------------------------------
// Tests
//------------------------------------------------------------------------------

let ruleTester = new RuleTester()

const errors = [{ messageId: 'unexpected' }]
const parserOptions = { ecmaVersion: 6 }

ruleTester.run('no-focused-tests', rule, {

valid: [
{ code: 'it(() => {});', parserOptions },
{ code: 'describe(() => {});', parserOptions },
{ code: `describe((\'my describe block\'), () => {
it(\'works\', () => {});
});`, parserOptions },
{ code: '\'it.only(() => {})\'', parserOptions },
],

invalid: [
{ code: 'it.only(() => {});', parserOptions, errors },
{ code: 'describe.only(() => {});', parserOptions, errors },
{ code: `describe.only((\'my describe block\'), () => {
it(\'works\', () => {});
});`, parserOptions, errors },
{ code: `describe((\'my describe block\'), () => {
it.only(\'works\', () => {});
});`, parserOptions, errors },
],
})