Skip to content

Commit

Permalink
feat(no-focused-tests): add autofix (#424)
Browse files Browse the repository at this point in the history
* feat(no-focused-tests): add autofix

* fix(no-focused-tests): set fixable to true by default

* chore: remove unused type import

* docs(option): added an option for no-focused-tests rule

---------

Co-authored-by: Verite Mugabo <mugaboverite@gmail.com>
  • Loading branch information
luxass and veritem committed Apr 13, 2024
1 parent b082ce6 commit 07be616
Show file tree
Hide file tree
Showing 3 changed files with 189 additions and 6 deletions.
32 changes: 32 additions & 0 deletions docs/rules/no-focused-tests.md
Expand Up @@ -31,3 +31,35 @@ test('it', () => {
/* ... */
})
```

### Options

This rule have a `fixable` option that is enabled by default; It tell this plugin to fix tests for you. If you don't want this rule to auto fix your tests, you can disable it in your `eslint.config.js` file using the following configuration.

```ts
import vitest from 'eslint-plugin-vitest'

export default [
{
files: ['**/*.ts', '**/*.js'], // or any other pattern
plugins: {
vitest,
},
rules: {
...vitest.configs.recommended.all,
'vitest/no-focused-tests': ['error', { 'fixable': false }]
},
settings: {
vitest: {
typecheck: true
}
},
languageOptions: {
parser: parser,
globals: {
...vitest.environments.env.globals
}
}
}
]
```
42 changes: 36 additions & 6 deletions src/rules/no-focused-tests.ts
Expand Up @@ -3,7 +3,11 @@ import { createEslintRule } from '../utils'

export type MessageIds = 'noFocusedTests'
export const RULE_NAME = 'no-focused-tests'
export type Options = []
export type Options = [
Partial<{
fixable: boolean
}>
]

const isTestOrDescribe = (node: TSESTree.Expression) => {
return node.type === 'Identifier' && ['it', 'test', 'describe'].includes(node.name)
Expand All @@ -22,13 +26,29 @@ export default createEslintRule<Options, MessageIds>({
recommended: 'strict'
},
fixable: 'code',
schema: [],
schema: [
{
type: 'object',
properties: {
fixable: {
type: 'boolean',
default: true
}
},
additionalProperties: false
}
],
messages: {
noFocusedTests: 'Focused tests are not allowed.'
}
},
defaultOptions: [],
defaultOptions: [{ fixable: true }],
create: (context) => {
const config = context.options[0] ?? {
fixable: true
}
const fixable = config.fixable

return {
ExpressionStatement(node) {
if (node.expression.type === 'CallExpression') {
Expand All @@ -40,7 +60,8 @@ export default createEslintRule<Options, MessageIds>({
) {
context.report({
node: callee.property,
messageId: 'noFocusedTests'
messageId: 'noFocusedTests',
fix: fixer => fixable ? fixer.removeRange([callee.property.range[0] - 1, callee.property.range[1]]) : null
})
}

Expand All @@ -55,7 +76,8 @@ export default createEslintRule<Options, MessageIds>({
) {
context.report({
node: tagCall.property,
messageId: 'noFocusedTests'
messageId: 'noFocusedTests',
fix: fixer => fixable ? fixer.removeRange([tagCall.property.range[0] - 1, tagCall.property.range[1]]) : null
})
}
}
Expand All @@ -73,9 +95,17 @@ export default createEslintRule<Options, MessageIds>({
&& callee.property.type === 'Identifier'
&& callee.property.name === 'each'
) {
const onlyCallee = callee.object.property

context.report({
node: callee.object.property,
messageId: 'noFocusedTests'
messageId: 'noFocusedTests',
fix: fixer => fixable
? fixer.removeRange([
onlyCallee.range[0] - 1,
onlyCallee.range[1]
])
: null
})
}
}
Expand Down
121 changes: 121 additions & 0 deletions tests/no-focused-tests.test.ts
Expand Up @@ -6,6 +6,9 @@ ruleTester.run(RULE_NAME, rule, {

invalid: [
{
options: [{
fixable: false
}],
code: 'it.only("test", () => {});',
errors: [
{
Expand All @@ -19,6 +22,9 @@ ruleTester.run(RULE_NAME, rule, {
output: 'it.only("test", () => {});'
},
{
options: [{
fixable: false
}],
code: 'describe.only("test", () => {});',
errors: [
{
Expand All @@ -32,6 +38,9 @@ ruleTester.run(RULE_NAME, rule, {
output: 'describe.only("test", () => {});'
},
{
options: [{
fixable: false
}],
code: 'test.only("test", () => {});',
errors: [
{
Expand All @@ -45,6 +54,9 @@ ruleTester.run(RULE_NAME, rule, {
output: 'test.only("test", () => {});'
},
{
options: [{
fixable: false
}],
code: 'it.only.each([])("test", () => {});',
errors: [
{
Expand All @@ -58,6 +70,9 @@ ruleTester.run(RULE_NAME, rule, {
output: 'it.only.each([])("test", () => {});'
},
{
options: [{
fixable: false
}],
code: 'test.only.each``("test", () => {});',
errors: [
{
Expand All @@ -71,6 +86,9 @@ ruleTester.run(RULE_NAME, rule, {
output: 'test.only.each``("test", () => {});'
},
{
options: [{
fixable: false
}],
code: 'it.only.each``("test", () => {});',
errors: [
{
Expand All @@ -85,3 +103,106 @@ ruleTester.run(RULE_NAME, rule, {
}
]
})

ruleTester.run(RULE_NAME, rule, {
valid: ['it("test", () => {});', 'describe("test group", () => {});'],

invalid: [
{
options: [{
fixable: true
}],
code: 'it.only("test", () => {});',
errors: [
{
column: 4,
endColumn: 8,
endLine: 1,
line: 1,
messageId: 'noFocusedTests'
}
],
output: 'it("test", () => {});'
},
{
options: [{
fixable: true
}],
code: 'describe.only("test", () => {});',
errors: [
{
column: 10,
endColumn: 14,
endLine: 1,
line: 1,
messageId: 'noFocusedTests'
}
],
output: 'describe("test", () => {});'
},
{
options: [{
fixable: true
}],
code: 'test.only("test", () => {});',
errors: [
{
column: 6,
endColumn: 10,
endLine: 1,
line: 1,
messageId: 'noFocusedTests'
}
],
output: 'test("test", () => {});'
},
{
options: [{
fixable: true
}],
code: 'it.only.each([])("test", () => {});',
errors: [
{
column: 4,
endColumn: 8,
endLine: 1,
line: 1,
messageId: 'noFocusedTests'
}
],
output: 'it.each([])("test", () => {});'
},
{
options: [{
fixable: true
}],
code: 'test.only.each``("test", () => {});',
errors: [
{
column: 6,
endColumn: 10,
endLine: 1,
line: 1,
messageId: 'noFocusedTests'
}
],
output: 'test.each``("test", () => {});'
},
{
options: [{
fixable: true
}],
code: 'it.only.each``("test", () => {});',
errors: [
{
column: 4,
endColumn: 8,
endLine: 1,
line: 1,
messageId: 'noFocusedTests'
}
],
output: 'it.each``("test", () => {});'
}
]
})

0 comments on commit 07be616

Please sign in to comment.