eslint-plugin-jest 27.2.3 → 27.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/docs/rules/no-confusing-set-timeout.md +62 -0
- package/docs/rules/valid-title.md +9 -1
- package/lib/rules/expect-expect.js +3 -1
- package/lib/rules/no-confusing-set-timeout.js +65 -0
- package/lib/rules/no-test-return-statement.js +9 -3
- package/lib/rules/no-untyped-mock-factory.js +3 -1
- package/lib/rules/prefer-spy-on.js +6 -2
- package/lib/rules/unbound-method.js +1 -1
- package/lib/rules/valid-title.js +7 -1
- package/package.json +9 -12
package/README.md
CHANGED
|
@@ -220,6 +220,7 @@ set to warn in.\
|
|
|
220
220
|
| [no-commented-out-tests](docs/rules/no-commented-out-tests.md) | Disallow commented out tests | | ✅ | | | |
|
|
221
221
|
| [no-conditional-expect](docs/rules/no-conditional-expect.md) | Disallow calling `expect` conditionally | ✅ | | | | |
|
|
222
222
|
| [no-conditional-in-test](docs/rules/no-conditional-in-test.md) | Disallow conditional logic in tests | | | | | |
|
|
223
|
+
| [no-confusing-set-timeout](docs/rules/no-confusing-set-timeout.md) | Disallow confusing usages of jest.setTimeout | | | | | |
|
|
223
224
|
| [no-deprecated-functions](docs/rules/no-deprecated-functions.md) | Disallow use of deprecated functions | ✅ | | 🔧 | | |
|
|
224
225
|
| [no-disabled-tests](docs/rules/no-disabled-tests.md) | Disallow disabled tests | | ✅ | | | |
|
|
225
226
|
| [no-done-callback](docs/rules/no-done-callback.md) | Disallow using a callback in asynchronous tests and hooks | ✅ | | | 💡 | |
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Disallow confusing usages of jest.setTimeout (`no-confusing-set-timeout`)
|
|
2
|
+
|
|
3
|
+
<!-- end auto-generated rule header -->
|
|
4
|
+
|
|
5
|
+
While `jest.setTimeout` can be called multiple times anywhere within a single
|
|
6
|
+
test file only the last call before any test functions run will have an effect.
|
|
7
|
+
|
|
8
|
+
## Rule details
|
|
9
|
+
|
|
10
|
+
this rule checks for several confusing usages of `jest.setTimeout` that looks
|
|
11
|
+
like it applies to specific tests within the same file, such as:
|
|
12
|
+
|
|
13
|
+
- being called anywhere other than in global scope
|
|
14
|
+
- being called multiple times
|
|
15
|
+
- being called after other Jest functions like hooks, `describe`, `test`, or
|
|
16
|
+
`it`
|
|
17
|
+
|
|
18
|
+
Examples of **incorrect** code for this rule:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
describe('test foo', () => {
|
|
22
|
+
jest.setTimeout(1000);
|
|
23
|
+
it('test-description', () => {
|
|
24
|
+
// test logic;
|
|
25
|
+
});
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
describe('test bar', () => {
|
|
29
|
+
it('test-description', () => {
|
|
30
|
+
jest.setTimeout(1000);
|
|
31
|
+
// test logic;
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test('foo-bar', () => {
|
|
36
|
+
jest.setTimeout(1000);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('unit test', () => {
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
jest.setTimeout(1000);
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Examples of **correct** code for this rule:
|
|
47
|
+
|
|
48
|
+
```js
|
|
49
|
+
jest.setTimeout(500);
|
|
50
|
+
test('test test', () => {
|
|
51
|
+
// do some stuff
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```js
|
|
56
|
+
jest.setTimeout(1000);
|
|
57
|
+
describe('test bar bar', () => {
|
|
58
|
+
it('test-description', () => {
|
|
59
|
+
// test logic;
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
```
|
|
@@ -125,7 +125,8 @@ describe('foo', () => {
|
|
|
125
125
|
|
|
126
126
|
**accidentalSpace**
|
|
127
127
|
|
|
128
|
-
A `describe` / `test` block should not contain accidentalSpace
|
|
128
|
+
A `describe` / `test` block should not contain accidentalSpace, but can be
|
|
129
|
+
turned off via the `ignoreSpaces` option:
|
|
129
130
|
|
|
130
131
|
Examples of **incorrect** code for this rule
|
|
131
132
|
|
|
@@ -161,6 +162,7 @@ describe('foo', () => {
|
|
|
161
162
|
|
|
162
163
|
```ts
|
|
163
164
|
interface Options {
|
|
165
|
+
ignoreSpaces?: boolean;
|
|
164
166
|
ignoreTypeOfDescribeName?: boolean;
|
|
165
167
|
disallowedWords?: string[];
|
|
166
168
|
mustNotMatch?: Partial<Record<'describe' | 'test' | 'it', string>> | string;
|
|
@@ -168,6 +170,12 @@ interface Options {
|
|
|
168
170
|
}
|
|
169
171
|
```
|
|
170
172
|
|
|
173
|
+
#### `ignoreSpaces`
|
|
174
|
+
|
|
175
|
+
Default: `false`
|
|
176
|
+
|
|
177
|
+
When enabled, the leading and trailing spaces won't be checked.
|
|
178
|
+
|
|
171
179
|
#### `ignoreTypeOfDescribeName`
|
|
172
180
|
|
|
173
181
|
Default: `false`
|
|
@@ -20,7 +20,9 @@ var _utils2 = require("./utils");
|
|
|
20
20
|
*/
|
|
21
21
|
function matchesAssertFunctionName(nodeName, patterns) {
|
|
22
22
|
return patterns.some(p => new RegExp(`^${p.split('.').map(x => {
|
|
23
|
-
if (x === '**')
|
|
23
|
+
if (x === '**') {
|
|
24
|
+
return '[a-z\\d\\.]*';
|
|
25
|
+
}
|
|
24
26
|
return x.replace(/\*/gu, '[a-z\\d]*');
|
|
25
27
|
}).join('\\.')}(\\.|$)`, 'ui').test(nodeName));
|
|
26
28
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
var _utils = require("./utils");
|
|
8
|
+
function isJestSetTimeout(jestFnCall) {
|
|
9
|
+
return jestFnCall.type === 'jest' && jestFnCall.members.length === 1 && (0, _utils.isIdentifier)(jestFnCall.members[0], 'setTimeout');
|
|
10
|
+
}
|
|
11
|
+
var _default = (0, _utils.createRule)({
|
|
12
|
+
name: __filename,
|
|
13
|
+
meta: {
|
|
14
|
+
docs: {
|
|
15
|
+
category: 'Best Practices',
|
|
16
|
+
description: 'Disallow confusing usages of jest.setTimeout',
|
|
17
|
+
recommended: false
|
|
18
|
+
},
|
|
19
|
+
messages: {
|
|
20
|
+
globalSetTimeout: '`jest.setTimeout` should be call in `global` scope',
|
|
21
|
+
multipleSetTimeouts: 'Do not call `jest.setTimeout` multiple times, as only the last call will have an effect',
|
|
22
|
+
orderSetTimeout: '`jest.setTimeout` should be placed before any other jest methods'
|
|
23
|
+
},
|
|
24
|
+
type: 'problem',
|
|
25
|
+
schema: []
|
|
26
|
+
},
|
|
27
|
+
defaultOptions: [],
|
|
28
|
+
create(context) {
|
|
29
|
+
let seenJestTimeout = false;
|
|
30
|
+
let shouldEmitOrderSetTimeout = false;
|
|
31
|
+
return {
|
|
32
|
+
CallExpression(node) {
|
|
33
|
+
const scope = context.getScope();
|
|
34
|
+
const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
|
|
35
|
+
if (!jestFnCall) {
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
if (!isJestSetTimeout(jestFnCall)) {
|
|
39
|
+
shouldEmitOrderSetTimeout = true;
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
if (!['global', 'module'].includes(scope.type)) {
|
|
43
|
+
context.report({
|
|
44
|
+
messageId: 'globalSetTimeout',
|
|
45
|
+
node
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
if (shouldEmitOrderSetTimeout) {
|
|
49
|
+
context.report({
|
|
50
|
+
messageId: 'orderSetTimeout',
|
|
51
|
+
node
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
if (seenJestTimeout) {
|
|
55
|
+
context.report({
|
|
56
|
+
messageId: 'multipleSetTimeouts',
|
|
57
|
+
node
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
seenJestTimeout = true;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
exports.default = _default;
|
|
@@ -36,7 +36,9 @@ var _default = (0, _utils2.createRule)({
|
|
|
36
36
|
}
|
|
37
37
|
const body = getBody(node.arguments);
|
|
38
38
|
const returnStmt = body.find(t => t.type === _utils.AST_NODE_TYPES.ReturnStatement);
|
|
39
|
-
if (!returnStmt)
|
|
39
|
+
if (!returnStmt) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
40
42
|
context.report({
|
|
41
43
|
messageId: 'noReturnValue',
|
|
42
44
|
node: returnStmt
|
|
@@ -45,9 +47,13 @@ var _default = (0, _utils2.createRule)({
|
|
|
45
47
|
FunctionDeclaration(node) {
|
|
46
48
|
const declaredVariables = context.getDeclaredVariables(node);
|
|
47
49
|
const testCallExpressions = (0, _utils2.getTestCallExpressionsFromDeclaredVariables)(declaredVariables, context);
|
|
48
|
-
if (testCallExpressions.length === 0)
|
|
50
|
+
if (testCallExpressions.length === 0) {
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
49
53
|
const returnStmt = node.body.body.find(t => t.type === _utils.AST_NODE_TYPES.ReturnStatement);
|
|
50
|
-
if (!returnStmt)
|
|
54
|
+
if (!returnStmt) {
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
51
57
|
context.report({
|
|
52
58
|
messageId: 'noReturnValue',
|
|
53
59
|
node: returnStmt
|
|
@@ -61,9 +61,13 @@ var _default = (0, _utils2.createRule)({
|
|
|
61
61
|
left,
|
|
62
62
|
right
|
|
63
63
|
} = node;
|
|
64
|
-
if (left.type !== _utils.AST_NODE_TYPES.MemberExpression)
|
|
64
|
+
if (left.type !== _utils.AST_NODE_TYPES.MemberExpression) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
65
67
|
const jestFnCall = getJestFnCall(right);
|
|
66
|
-
if (!jestFnCall)
|
|
68
|
+
if (!jestFnCall) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
67
71
|
context.report({
|
|
68
72
|
node,
|
|
69
73
|
messageId: 'useJestSpyOn',
|
|
@@ -63,7 +63,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
63
63
|
}
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
|
-
(_baseSelectors$Member = baseSelectors.MemberExpression) === null || _baseSelectors$Member === void 0
|
|
66
|
+
(_baseSelectors$Member = baseSelectors.MemberExpression) === null || _baseSelectors$Member === void 0 || _baseSelectors$Member.call(baseSelectors, node);
|
|
67
67
|
}
|
|
68
68
|
};
|
|
69
69
|
}
|
package/lib/rules/valid-title.js
CHANGED
|
@@ -68,6 +68,10 @@ var _default = (0, _utils2.createRule)({
|
|
|
68
68
|
schema: [{
|
|
69
69
|
type: 'object',
|
|
70
70
|
properties: {
|
|
71
|
+
ignoreSpaces: {
|
|
72
|
+
type: 'boolean',
|
|
73
|
+
default: false
|
|
74
|
+
},
|
|
71
75
|
ignoreTypeOfDescribeName: {
|
|
72
76
|
type: 'boolean',
|
|
73
77
|
default: false
|
|
@@ -101,10 +105,12 @@ var _default = (0, _utils2.createRule)({
|
|
|
101
105
|
fixable: 'code'
|
|
102
106
|
},
|
|
103
107
|
defaultOptions: [{
|
|
108
|
+
ignoreSpaces: false,
|
|
104
109
|
ignoreTypeOfDescribeName: false,
|
|
105
110
|
disallowedWords: []
|
|
106
111
|
}],
|
|
107
112
|
create(context, [{
|
|
113
|
+
ignoreSpaces,
|
|
108
114
|
ignoreTypeOfDescribeName,
|
|
109
115
|
disallowedWords = [],
|
|
110
116
|
mustNotMatch,
|
|
@@ -159,7 +165,7 @@ var _default = (0, _utils2.createRule)({
|
|
|
159
165
|
return;
|
|
160
166
|
}
|
|
161
167
|
}
|
|
162
|
-
if (title.trim().length !== title.length) {
|
|
168
|
+
if (ignoreSpaces === false && title.trim().length !== title.length) {
|
|
163
169
|
context.report({
|
|
164
170
|
messageId: 'accidentalSpace',
|
|
165
171
|
node: argument,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-jest",
|
|
3
|
-
"version": "27.
|
|
3
|
+
"version": "27.4.0",
|
|
4
4
|
"description": "ESLint rules for Jest",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"eslint",
|
|
@@ -45,8 +45,7 @@
|
|
|
45
45
|
"arrowParens": "avoid",
|
|
46
46
|
"endOfLine": "auto",
|
|
47
47
|
"proseWrap": "always",
|
|
48
|
-
"singleQuote": true
|
|
49
|
-
"trailingComma": "all"
|
|
48
|
+
"singleQuote": true
|
|
50
49
|
},
|
|
51
50
|
"release": {
|
|
52
51
|
"branches": [
|
|
@@ -105,28 +104,26 @@
|
|
|
105
104
|
"@babel/preset-typescript": "^7.3.3",
|
|
106
105
|
"@commitlint/cli": "^17.0.3",
|
|
107
106
|
"@commitlint/config-conventional": "^17.0.3",
|
|
108
|
-
"@schemastore/package": "^0.0.
|
|
107
|
+
"@schemastore/package": "^0.0.10",
|
|
109
108
|
"@semantic-release/changelog": "^6.0.0",
|
|
110
109
|
"@semantic-release/git": "^10.0.0",
|
|
111
110
|
"@tsconfig/node14": "^14.1.0",
|
|
112
|
-
"@types/dedent": "^0.7.0",
|
|
113
111
|
"@types/eslint": "^8.4.6",
|
|
114
112
|
"@types/jest": "^29.0.0",
|
|
115
113
|
"@types/node": "^14.18.26",
|
|
116
|
-
"@types/prettier": "^2.0.0",
|
|
117
114
|
"@typescript-eslint/eslint-plugin": "^5.0.0",
|
|
118
115
|
"@typescript-eslint/parser": "^5.0.0",
|
|
119
116
|
"babel-jest": "^29.0.0",
|
|
120
117
|
"babel-plugin-replace-ts-export-assignment": "^0.0.2",
|
|
121
|
-
"dedent": "^
|
|
122
|
-
"eslint": "^
|
|
123
|
-
"eslint-config-prettier": "^
|
|
118
|
+
"dedent": "^1.5.0",
|
|
119
|
+
"eslint": "^7.0.0 || ^8.0.0",
|
|
120
|
+
"eslint-config-prettier": "^9.0.0",
|
|
124
121
|
"eslint-doc-generator": "^1.0.0",
|
|
125
122
|
"eslint-plugin-eslint-comments": "^3.1.2",
|
|
126
123
|
"eslint-plugin-eslint-plugin": "^5.0.6",
|
|
127
124
|
"eslint-plugin-import": "^2.25.1",
|
|
128
125
|
"eslint-plugin-node": "^11.0.0",
|
|
129
|
-
"eslint-plugin-prettier": "^
|
|
126
|
+
"eslint-plugin-prettier": "^5.0.0",
|
|
130
127
|
"eslint-remote-tester": "^3.0.0",
|
|
131
128
|
"eslint-remote-tester-repositories": "~1.0.0",
|
|
132
129
|
"husky": "^8.0.1",
|
|
@@ -136,7 +133,7 @@
|
|
|
136
133
|
"lint-staged": "^13.0.3",
|
|
137
134
|
"markdown-link-check": "^3.10.2",
|
|
138
135
|
"pinst": "^3.0.0",
|
|
139
|
-
"prettier": "^
|
|
136
|
+
"prettier": "^3.0.0",
|
|
140
137
|
"rimraf": "^5.0.0",
|
|
141
138
|
"semantic-release": "^21.0.0",
|
|
142
139
|
"semver": "^7.3.5",
|
|
@@ -156,7 +153,7 @@
|
|
|
156
153
|
"optional": true
|
|
157
154
|
}
|
|
158
155
|
},
|
|
159
|
-
"packageManager": "yarn@3.6.
|
|
156
|
+
"packageManager": "yarn@3.6.3",
|
|
160
157
|
"engines": {
|
|
161
158
|
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
|
|
162
159
|
},
|