-
Notifications
You must be signed in to change notification settings - Fork 237
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add
no-confusing-set-time
rule (#1425)
* feat: add no-confusing-set-time rule * fix: cr problems * fix: ci * feat: reactor rule * chore: fix lint * fix: ci problems * fix: cr problems * fix: ci * docs: regenerate --------- Co-authored-by: Simen Bekkhus <[email protected]> Co-authored-by: Gareth Jones <[email protected]>
- Loading branch information
1 parent
1b96756
commit ff8e482
Showing
6 changed files
with
393 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
# Disallow confusing usages of jest.setTimeout (`no-confusing-set-timeout`) | ||
|
||
<!-- end auto-generated rule header --> | ||
|
||
While `jest.setTimeout` can be called multiple times anywhere within a single | ||
test file only the last call before any test functions run will have an effect. | ||
|
||
## Rule details | ||
|
||
this rule checks for several confusing usages of `jest.setTimeout` that looks | ||
like it applies to specific tests within the same file, such as: | ||
|
||
- being called anywhere other than in global scope | ||
- being called multiple times | ||
- being called after other Jest functions like hooks, `describe`, `test`, or | ||
`it` | ||
|
||
Examples of **incorrect** code for this rule: | ||
|
||
```js | ||
describe('test foo', () => { | ||
jest.setTimeout(1000); | ||
it('test-description', () => { | ||
// test logic; | ||
}); | ||
}); | ||
|
||
describe('test bar', () => { | ||
it('test-description', () => { | ||
jest.setTimeout(1000); | ||
// test logic; | ||
}); | ||
}); | ||
|
||
test('foo-bar', () => { | ||
jest.setTimeout(1000); | ||
}); | ||
|
||
describe('unit test', () => { | ||
beforeEach(() => { | ||
jest.setTimeout(1000); | ||
}); | ||
}); | ||
``` | ||
|
||
Examples of **correct** code for this rule: | ||
|
||
```js | ||
jest.setTimeout(500); | ||
test('test test', () => { | ||
// do some stuff | ||
}); | ||
``` | ||
|
||
```js | ||
jest.setTimeout(1000); | ||
describe('test bar bar', () => { | ||
it('test-description', () => { | ||
// test logic; | ||
}); | ||
}); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,258 @@ | ||
import { TSESLint } from '@typescript-eslint/utils'; | ||
import dedent from 'dedent'; | ||
import rule from '../no-confusing-set-timeout'; | ||
import { espreeParser } from './test-utils'; | ||
|
||
const ruleTester = new TSESLint.RuleTester({ | ||
parser: espreeParser, | ||
parserOptions: { | ||
ecmaVersion: 2020, | ||
}, | ||
}); | ||
|
||
ruleTester.run('no-confusing-set-timeout', rule, { | ||
valid: [ | ||
dedent` | ||
jest.setTimeout(1000); | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
dedent` | ||
jest.setTimeout(1000); | ||
window.setTimeout(6000) | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('test foo', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
{ | ||
code: dedent` | ||
import { handler } from 'dep/mod'; | ||
jest.setTimeout(800); | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
parserOptions: { sourceType: 'module' }, | ||
}, | ||
dedent` | ||
function handler() {} | ||
jest.setTimeout(800); | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
dedent` | ||
const { handler } = require('dep/mod'); | ||
jest.setTimeout(800); | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
dedent` | ||
jest.setTimeout(1000); | ||
window.setTimeout(60000); | ||
`, | ||
'window.setTimeout(60000);', | ||
'setTimeout(1000);', | ||
dedent` | ||
jest.setTimeout(1000); | ||
test('test case', () => { | ||
setTimeout(() => { | ||
Promise.resolv(); | ||
}, 5000); | ||
}); | ||
`, | ||
dedent` | ||
test('test case', () => { | ||
setTimeout(() => { | ||
Promise.resolv(); | ||
}, 5000); | ||
}); | ||
`, | ||
], | ||
invalid: [ | ||
{ | ||
code: dedent` | ||
jest.setTimeout(1000); | ||
setTimeout(1000); | ||
window.setTimeout(1000); | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
jest.setTimeout(800); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'orderSetTimeout', | ||
line: 9, | ||
column: 1, | ||
}, | ||
{ | ||
messageId: 'multipleSetTimeouts', | ||
line: 9, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
describe('A', () => { | ||
jest.setTimeout(800); | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'globalSetTimeout', | ||
line: 2, | ||
column: 3, | ||
}, | ||
{ | ||
messageId: 'orderSetTimeout', | ||
line: 2, | ||
column: 3, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
describe('B', () => { | ||
it('B.1', async () => { | ||
await new Promise((resolve) => { | ||
jest.setTimeout(1000); | ||
setTimeout(resolve, 10000).unref(); | ||
}); | ||
}); | ||
it('B.2', async () => { | ||
await new Promise((resolve) => { setTimeout(resolve, 10000).unref(); }); | ||
}); | ||
}); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'globalSetTimeout', | ||
line: 4, | ||
column: 7, | ||
}, | ||
{ | ||
messageId: 'orderSetTimeout', | ||
line: 4, | ||
column: 7, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
test('test-suite', () => { | ||
jest.setTimeout(1000); | ||
}); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'globalSetTimeout', | ||
line: 2, | ||
column: 3, | ||
}, | ||
{ | ||
messageId: 'orderSetTimeout', | ||
line: 2, | ||
column: 3, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
jest.setTimeout(1000); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'orderSetTimeout', | ||
line: 6, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
import { jest } from '@jest/globals'; | ||
{ | ||
jest.setTimeout(800); | ||
} | ||
describe('A', () => { | ||
beforeEach(async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.1', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
it('A.2', async () => { await new Promise(resolve => { setTimeout(resolve, 10000).unref(); });}); | ||
}); | ||
`, | ||
parserOptions: { sourceType: 'module' }, | ||
errors: [ | ||
{ | ||
messageId: 'globalSetTimeout', | ||
line: 3, | ||
column: 3, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
jest.setTimeout(800); | ||
jest.setTimeout(900); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'multipleSetTimeouts', | ||
line: 2, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
expect(1 + 2).toEqual(3); | ||
jest.setTimeout(800); | ||
`, | ||
errors: [ | ||
{ | ||
messageId: 'orderSetTimeout', | ||
line: 2, | ||
column: 1, | ||
}, | ||
], | ||
}, | ||
{ | ||
code: dedent` | ||
import { jest as Jest } from '@jest/globals'; | ||
{ | ||
Jest.setTimeout(800); | ||
} | ||
`, | ||
parserOptions: { sourceType: 'module' }, | ||
errors: [ | ||
{ | ||
messageId: 'globalSetTimeout', | ||
line: 3, | ||
column: 3, | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
Oops, something went wrong.