eslint-plugin-jest 22.15.0 → 22.17.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 +42 -40
- package/docs/rules/prefer-to-be-null.md +7 -2
- package/docs/rules/prefer-to-be-undefined.md +7 -2
- package/docs/rules/prefer-to-contain.md +8 -10
- package/docs/rules/prefer-to-have-length.md +7 -3
- package/docs/rules/require-top-level-describe.md +52 -0
- package/lib/__tests__/rules.test.js +5 -4
- package/lib/index.js +2 -3
- package/lib/rules/consistent-test-it.js +7 -7
- package/lib/rules/expect-expect.js +3 -3
- package/lib/rules/lowercase-name.js +3 -3
- package/lib/rules/no-alias-methods.js +18 -14
- package/lib/rules/no-commented-out-tests.js +2 -2
- package/lib/rules/no-disabled-tests.js +4 -4
- package/lib/rules/no-duplicate-hooks.js +5 -5
- package/lib/rules/no-empty-title.js +8 -14
- package/lib/rules/no-expect-resolves.js +3 -3
- package/lib/rules/no-export.js +3 -3
- package/lib/rules/no-focused-tests.js +4 -4
- package/lib/rules/no-hooks.js +3 -3
- package/lib/rules/no-identical-title.js +9 -9
- package/lib/rules/no-if.js +5 -5
- package/lib/rules/no-jasmine-globals.js +4 -4
- package/lib/rules/no-jest-import.js +2 -2
- package/lib/rules/no-large-snapshots.js +25 -18
- package/lib/rules/no-mocks-import.js +18 -7
- package/lib/rules/no-standalone-expect.js +8 -8
- package/lib/rules/no-test-callback.js +5 -5
- package/lib/rules/no-test-prefixes.js +4 -4
- package/lib/rules/no-test-return-statement.js +4 -4
- package/lib/rules/no-truthy-falsy.js +31 -19
- package/lib/rules/no-try-expect.js +5 -5
- package/lib/rules/prefer-called-with.js +23 -11
- package/lib/rules/prefer-expect-assertions.js +45 -34
- package/lib/rules/prefer-inline-snapshots.js +2 -2
- package/lib/rules/prefer-spy-on.js +4 -4
- package/lib/rules/prefer-strict-equal.js +10 -12
- package/lib/rules/prefer-to-be-null.js +34 -16
- package/lib/rules/prefer-to-be-undefined.js +34 -16
- package/lib/rules/prefer-to-contain.js +112 -51
- package/lib/rules/prefer-to-have-length.js +47 -14
- package/lib/rules/prefer-todo.js +13 -17
- package/lib/rules/require-top-level-describe.js +66 -0
- package/lib/rules/require-tothrow-message.js +20 -15
- package/lib/rules/utils.js +486 -0
- package/lib/rules/valid-describe.js +36 -44
- package/lib/rules/valid-expect-in-promise.js +71 -66
- package/lib/rules/valid-expect.js +140 -173
- package/package.json +6 -5
- package/lib/rules/tsUtils.js +0 -250
- package/lib/rules/util.js +0 -100
|
@@ -5,7 +5,9 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
9
|
+
|
|
10
|
+
var _utils = require("./utils");
|
|
9
11
|
|
|
10
12
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
11
13
|
|
|
@@ -15,84 +17,143 @@ function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d =
|
|
|
15
17
|
|
|
16
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
19
|
|
|
18
|
-
const
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
20
|
+
const isBooleanLiteral = node => node.type === _experimentalUtils.AST_NODE_TYPES.Literal && typeof node.value === 'boolean';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Checks if the given `ParsedExpectMatcher` is a call to one of the equality matchers,
|
|
24
|
+
* with a boolean literal as the sole argument.
|
|
25
|
+
*
|
|
26
|
+
* @example javascript
|
|
27
|
+
* toBe(true);
|
|
28
|
+
* toEqual(false);
|
|
29
|
+
*
|
|
30
|
+
* @param {ParsedExpectMatcher} matcher
|
|
31
|
+
*
|
|
32
|
+
* @return {matcher is ParsedBooleanEqualityMatcher}
|
|
33
|
+
*/
|
|
34
|
+
const isBooleanEqualityMatcher = matcher => (0, _utils.isParsedEqualityMatcherCall)(matcher) && isBooleanLiteral((0, _utils.followTypeAssertionChain)(matcher.arguments[0]));
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Checks if the given `node` is a `CallExpression` representing the calling
|
|
38
|
+
* of an `includes`-like method that can be 'fixed' (using `toContain`).
|
|
39
|
+
*
|
|
40
|
+
* @param {CallExpression} node
|
|
41
|
+
*
|
|
42
|
+
* @return {node is FixableIncludesCallExpression}
|
|
43
|
+
*
|
|
44
|
+
* @todo support `['includes']()` syntax (remove last property.type check to begin)
|
|
45
|
+
* @todo break out into `isMethodCall<Name extends string>(node: TSESTree.Node, method: Name)` util-fn
|
|
46
|
+
*/
|
|
47
|
+
const isFixableIncludesCallExpression = node => node.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && (0, _utils.isSupportedAccessor)(node.callee.property, 'includes') && node.callee.property.type === _experimentalUtils.AST_NODE_TYPES.Identifier && (0, _utils.hasOnlyOneArgument)(node);
|
|
48
|
+
|
|
49
|
+
const buildToContainFuncExpectation = negated => negated ? `${_utils.ModifierName.not}.toContain` : 'toContain';
|
|
50
|
+
/**
|
|
51
|
+
* Finds the first `.` character token between the `object` & `property` of the given `member` expression.
|
|
52
|
+
*
|
|
53
|
+
* @param {TSESTree.MemberExpression} member
|
|
54
|
+
* @param {SourceCode} sourceCode
|
|
55
|
+
*
|
|
56
|
+
* @return {Token | null}
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
const findPropertyDotToken = (member, sourceCode) => sourceCode.getFirstTokenBetween(member.object, member.property, token => token.value === '.');
|
|
61
|
+
|
|
62
|
+
const getNegationFixes = (node, modifier, matcher, sourceCode, fixer, fileName) => {
|
|
63
|
+
const _node$arguments = _slicedToArray(node.arguments, 1),
|
|
64
|
+
containArg = _node$arguments[0];
|
|
65
|
+
|
|
66
|
+
const negationPropertyDot = findPropertyDotToken(modifier.node, sourceCode);
|
|
67
|
+
const toContainFunc = buildToContainFuncExpectation((0, _utils.followTypeAssertionChain)(matcher.arguments[0]).value);
|
|
68
|
+
/* istanbul ignore if */
|
|
69
|
+
|
|
70
|
+
if (negationPropertyDot === null) {
|
|
71
|
+
throw new Error(`Unexpected null when attempting to fix ${fileName} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
|
|
72
|
+
}
|
|
38
73
|
|
|
39
|
-
return [fixer.remove(negationPropertyDot), fixer.remove(
|
|
74
|
+
return [fixer.remove(negationPropertyDot), fixer.remove(modifier.node.property), fixer.replaceText(matcher.node.property, toContainFunc), fixer.replaceText(matcher.arguments[0], sourceCode.getText(containArg))];
|
|
40
75
|
};
|
|
41
76
|
|
|
42
|
-
const getCommonFixes = (node, sourceCode,
|
|
43
|
-
const _node$
|
|
44
|
-
containArg = _node$
|
|
77
|
+
const getCommonFixes = (node, sourceCode, fileName) => {
|
|
78
|
+
const _node$arguments2 = _slicedToArray(node.arguments, 1),
|
|
79
|
+
containArg = _node$arguments2[0];
|
|
45
80
|
|
|
46
|
-
const
|
|
47
|
-
const propertyDot =
|
|
81
|
+
const includesCallee = node.callee;
|
|
82
|
+
const propertyDot = findPropertyDotToken(includesCallee, sourceCode);
|
|
48
83
|
const closingParenthesis = sourceCode.getTokenAfter(containArg);
|
|
49
84
|
const openParenthesis = sourceCode.getTokenBefore(containArg);
|
|
50
|
-
|
|
51
|
-
|
|
85
|
+
/* istanbul ignore if */
|
|
86
|
+
|
|
87
|
+
if (propertyDot === null || closingParenthesis === null || openParenthesis === null) {
|
|
88
|
+
throw new Error(`Unexpected null when attempting to fix ${fileName} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
return [containArg, includesCallee.property, propertyDot, closingParenthesis, openParenthesis];
|
|
92
|
+
}; // expect(array.includes(<value>)[not.]{toBe,toEqual}(<boolean>)
|
|
93
|
+
|
|
52
94
|
|
|
53
|
-
var _default = {
|
|
95
|
+
var _default = (0, _utils.createRule)({
|
|
96
|
+
name: __filename,
|
|
54
97
|
meta: {
|
|
55
98
|
docs: {
|
|
56
|
-
|
|
99
|
+
category: 'Best Practices',
|
|
100
|
+
description: 'Suggest using `toContain()`',
|
|
101
|
+
recommended: false
|
|
57
102
|
},
|
|
58
103
|
messages: {
|
|
59
104
|
useToContain: 'Use toContain() instead'
|
|
60
105
|
},
|
|
61
106
|
fixable: 'code',
|
|
107
|
+
type: 'suggestion',
|
|
62
108
|
schema: []
|
|
63
109
|
},
|
|
110
|
+
defaultOptions: [],
|
|
64
111
|
|
|
65
112
|
create(context) {
|
|
66
113
|
return {
|
|
67
114
|
CallExpression(node) {
|
|
68
|
-
if (!(
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const sourceCode = context.getSourceCode();
|
|
72
|
-
let fixArr = getCommonFixes(node, sourceCode, fixer);
|
|
115
|
+
if (!(0, _utils.isExpectCall)(node)) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
73
118
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
119
|
+
const _parseExpectCall = (0, _utils.parseExpectCall)(node),
|
|
120
|
+
_parseExpectCall$expe = _slicedToArray(_parseExpectCall.expect.arguments, 1),
|
|
121
|
+
includesCall = _parseExpectCall$expe[0],
|
|
122
|
+
matcher = _parseExpectCall.matcher,
|
|
123
|
+
modifier = _parseExpectCall.modifier;
|
|
77
124
|
|
|
78
|
-
|
|
125
|
+
if (!matcher || modifier && modifier.name !== _utils.ModifierName.not || !isBooleanEqualityMatcher(matcher) || !isFixableIncludesCallExpression(includesCall)) {
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
79
128
|
|
|
80
|
-
|
|
81
|
-
|
|
129
|
+
context.report({
|
|
130
|
+
fix(fixer) {
|
|
131
|
+
const sourceCode = context.getSourceCode();
|
|
132
|
+
const fileName = context.getFilename();
|
|
133
|
+
const fixArr = getCommonFixes(includesCall, sourceCode, fileName).map(target => fixer.remove(target));
|
|
82
134
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
},
|
|
135
|
+
if (modifier && modifier.name === _utils.ModifierName.not) {
|
|
136
|
+
return getNegationFixes(includesCall, modifier, matcher, sourceCode, fixer, fileName).concat(fixArr);
|
|
137
|
+
}
|
|
87
138
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
139
|
+
const toContainFunc = buildToContainFuncExpectation(!(0, _utils.followTypeAssertionChain)(matcher.arguments[0]).value);
|
|
140
|
+
|
|
141
|
+
const _includesCall$argumen = _slicedToArray(includesCall.arguments, 1),
|
|
142
|
+
containArg = _includesCall$argumen[0];
|
|
143
|
+
|
|
144
|
+
fixArr.push(fixer.replaceText(matcher.node.property, toContainFunc));
|
|
145
|
+
fixArr.push(fixer.replaceText(matcher.arguments[0], sourceCode.getText(containArg)));
|
|
146
|
+
return fixArr;
|
|
147
|
+
},
|
|
148
|
+
|
|
149
|
+
messageId: 'useToContain',
|
|
150
|
+
node: (modifier || matcher).node.property
|
|
151
|
+
});
|
|
92
152
|
}
|
|
93
153
|
|
|
94
154
|
};
|
|
95
155
|
}
|
|
96
156
|
|
|
97
|
-
};
|
|
157
|
+
});
|
|
158
|
+
|
|
98
159
|
exports.default = _default;
|
|
@@ -5,38 +5,71 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _utils = require("./utils");
|
|
11
|
+
|
|
12
|
+
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
13
|
+
|
|
14
|
+
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
15
|
+
|
|
16
|
+
function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
|
|
17
|
+
|
|
18
|
+
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
|
+
|
|
20
|
+
var _default = (0, _utils.createRule)({
|
|
21
|
+
name: __filename,
|
|
11
22
|
meta: {
|
|
12
23
|
docs: {
|
|
13
|
-
|
|
24
|
+
category: 'Best Practices',
|
|
25
|
+
description: 'Suggest using `toHaveLength()`',
|
|
26
|
+
recommended: false
|
|
14
27
|
},
|
|
15
28
|
messages: {
|
|
16
29
|
useToHaveLength: 'Use toHaveLength() instead'
|
|
17
30
|
},
|
|
18
31
|
fixable: 'code',
|
|
32
|
+
type: 'suggestion',
|
|
19
33
|
schema: []
|
|
20
34
|
},
|
|
35
|
+
defaultOptions: [],
|
|
21
36
|
|
|
22
37
|
create(context) {
|
|
23
38
|
return {
|
|
24
39
|
CallExpression(node) {
|
|
25
|
-
if (!(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
40
|
+
if (!(0, _utils.isExpectCall)(node)) {
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const _parseExpectCall = (0, _utils.parseExpectCall)(node),
|
|
45
|
+
_parseExpectCall$expe = _slicedToArray(_parseExpectCall.expect.arguments, 1),
|
|
46
|
+
argument = _parseExpectCall$expe[0],
|
|
47
|
+
matcher = _parseExpectCall.matcher;
|
|
48
|
+
|
|
49
|
+
if (!matcher || !(0, _utils.isParsedEqualityMatcherCall)(matcher) || !argument || argument.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression || !(0, _utils.isSupportedAccessor)(argument.property, 'length') || argument.property.type !== _experimentalUtils.AST_NODE_TYPES.Identifier) {
|
|
50
|
+
return;
|
|
35
51
|
}
|
|
52
|
+
|
|
53
|
+
context.report({
|
|
54
|
+
fix(fixer) {
|
|
55
|
+
const propertyDot = context.getSourceCode().getFirstTokenBetween(argument.object, argument.property, token => token.value === '.');
|
|
56
|
+
/* istanbul ignore if */
|
|
57
|
+
|
|
58
|
+
if (propertyDot === null) {
|
|
59
|
+
throw new Error(`Unexpected null when attempting to fix ${context.getFilename()} - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return [fixer.remove(propertyDot), fixer.remove(argument.property), fixer.replaceText(matcher.node.property, 'toHaveLength')];
|
|
63
|
+
},
|
|
64
|
+
|
|
65
|
+
messageId: 'useToHaveLength',
|
|
66
|
+
node: matcher.node.property
|
|
67
|
+
});
|
|
36
68
|
}
|
|
37
69
|
|
|
38
70
|
};
|
|
39
71
|
}
|
|
40
72
|
|
|
41
|
-
};
|
|
73
|
+
});
|
|
74
|
+
|
|
42
75
|
exports.default = _default;
|
package/lib/rules/prefer-todo.js
CHANGED
|
@@ -7,7 +7,7 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
9
9
|
|
|
10
|
-
var
|
|
10
|
+
var _utils = require("./utils");
|
|
11
11
|
|
|
12
12
|
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
13
13
|
|
|
@@ -17,12 +17,8 @@ function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d =
|
|
|
17
17
|
|
|
18
18
|
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
19
19
|
|
|
20
|
-
function isOnlyTestTitle(node) {
|
|
21
|
-
return node.arguments.length === 1;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
20
|
function isFunctionBodyEmpty(node) {
|
|
25
|
-
/* istanbul ignore
|
|
21
|
+
/* istanbul ignore if https://github.com/typescript-eslint/typescript-eslint/issues/734 */
|
|
26
22
|
if (!node.body) {
|
|
27
23
|
throw new Error(`Unexpected null while performing prefer-todo - please file a github issue at https://github.com/jest-community/eslint-plugin-jest`);
|
|
28
24
|
}
|
|
@@ -34,21 +30,17 @@ function isTestBodyEmpty(node) {
|
|
|
34
30
|
const _node$arguments = _slicedToArray(node.arguments, 2),
|
|
35
31
|
fn = _node$arguments[1];
|
|
36
32
|
|
|
37
|
-
return fn && (0,
|
|
33
|
+
return fn && (0, _utils.isFunction)(fn) && isFunctionBodyEmpty(fn);
|
|
38
34
|
}
|
|
39
35
|
|
|
40
36
|
function addTodo(node, fixer) {
|
|
41
|
-
const testName = (0,
|
|
37
|
+
const testName = (0, _utils.getNodeName)(node.callee).split('.').shift();
|
|
42
38
|
return fixer.replaceText(node.callee, `${testName}.todo`);
|
|
43
39
|
}
|
|
44
40
|
|
|
45
|
-
|
|
46
|
-
return node.arguments[0] && (0, _tsUtils.isStringNode)(node.arguments[0]);
|
|
47
|
-
}
|
|
41
|
+
const isTargetedTestCase = node => (0, _utils.isTestCase)(node) && ['it', 'test', 'it.skip', 'test.skip'].includes((0, _utils.getNodeName)(node.callee));
|
|
48
42
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
var _default = (0, _tsUtils.createRule)({
|
|
43
|
+
var _default = (0, _utils.createRule)({
|
|
52
44
|
name: __filename,
|
|
53
45
|
meta: {
|
|
54
46
|
docs: {
|
|
@@ -69,7 +61,11 @@ var _default = (0, _tsUtils.createRule)({
|
|
|
69
61
|
create(context) {
|
|
70
62
|
return {
|
|
71
63
|
CallExpression(node) {
|
|
72
|
-
|
|
64
|
+
const _node$arguments2 = _slicedToArray(node.arguments, 2),
|
|
65
|
+
firstArg = _node$arguments2[0],
|
|
66
|
+
secondArg = _node$arguments2[1];
|
|
67
|
+
|
|
68
|
+
if (!isTargetedTestCase(node) || !(0, _utils.isStringNode)(firstArg)) {
|
|
73
69
|
return;
|
|
74
70
|
}
|
|
75
71
|
|
|
@@ -77,11 +73,11 @@ var _default = (0, _tsUtils.createRule)({
|
|
|
77
73
|
context.report({
|
|
78
74
|
messageId: 'todoOverEmpty',
|
|
79
75
|
node,
|
|
80
|
-
fix: fixer => [fixer.removeRange([
|
|
76
|
+
fix: fixer => [fixer.removeRange([firstArg.range[1], secondArg.range[1]]), addTodo(node, fixer)]
|
|
81
77
|
});
|
|
82
78
|
}
|
|
83
79
|
|
|
84
|
-
if (
|
|
80
|
+
if ((0, _utils.hasOnlyOneArgument)(node)) {
|
|
85
81
|
context.report({
|
|
86
82
|
messageId: 'todoOverUnimplemented',
|
|
87
83
|
node,
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.default = void 0;
|
|
7
|
+
|
|
8
|
+
var _utils = require("./utils");
|
|
9
|
+
|
|
10
|
+
var _default = (0, _utils.createRule)({
|
|
11
|
+
name: __filename,
|
|
12
|
+
meta: {
|
|
13
|
+
docs: {
|
|
14
|
+
category: 'Best Practices',
|
|
15
|
+
description: 'Prevents test cases and hooks to be outside of a describe block',
|
|
16
|
+
recommended: false
|
|
17
|
+
},
|
|
18
|
+
messages: {
|
|
19
|
+
unexpectedTestCase: 'All test cases must be wrapped in a describe block.',
|
|
20
|
+
unexpectedHook: 'All hooks must be wrapped in a describe block.'
|
|
21
|
+
},
|
|
22
|
+
type: 'suggestion',
|
|
23
|
+
schema: []
|
|
24
|
+
},
|
|
25
|
+
defaultOptions: [],
|
|
26
|
+
|
|
27
|
+
create(context) {
|
|
28
|
+
let numberOfDescribeBlocks = 0;
|
|
29
|
+
return {
|
|
30
|
+
CallExpression(node) {
|
|
31
|
+
if ((0, _utils.isDescribe)(node)) {
|
|
32
|
+
numberOfDescribeBlocks++;
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (numberOfDescribeBlocks === 0) {
|
|
37
|
+
if ((0, _utils.isTestCase)(node)) {
|
|
38
|
+
context.report({
|
|
39
|
+
node,
|
|
40
|
+
messageId: 'unexpectedTestCase'
|
|
41
|
+
});
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if ((0, _utils.isHook)(node)) {
|
|
46
|
+
context.report({
|
|
47
|
+
node,
|
|
48
|
+
messageId: 'unexpectedHook'
|
|
49
|
+
});
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
'CallExpression:exit'(node) {
|
|
56
|
+
if ((0, _utils.isDescribe)(node)) {
|
|
57
|
+
numberOfDescribeBlocks--;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
exports.default = _default;
|
|
@@ -5,41 +5,45 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var _utils = require("./utils");
|
|
9
9
|
|
|
10
|
-
var _default = {
|
|
10
|
+
var _default = (0, _utils.createRule)({
|
|
11
|
+
name: __filename,
|
|
11
12
|
meta: {
|
|
12
13
|
docs: {
|
|
13
|
-
|
|
14
|
+
category: 'Best Practices',
|
|
15
|
+
description: 'Require a message for `toThrow()`',
|
|
16
|
+
recommended: false
|
|
14
17
|
},
|
|
15
18
|
messages: {
|
|
16
19
|
requireRethrow: 'Add an error message to {{ propertyName }}()'
|
|
17
20
|
},
|
|
21
|
+
type: 'suggestion',
|
|
18
22
|
schema: []
|
|
19
23
|
},
|
|
24
|
+
defaultOptions: [],
|
|
20
25
|
|
|
21
26
|
create(context) {
|
|
22
27
|
return {
|
|
23
28
|
CallExpression(node) {
|
|
24
|
-
if (!(0,
|
|
29
|
+
if (!(0, _utils.isExpectCall)(node)) {
|
|
25
30
|
return;
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
const _parseExpectCall = (0, _utils.parseExpectCall)(node),
|
|
34
|
+
matcher = _parseExpectCall.matcher,
|
|
35
|
+
modifier = _parseExpectCall.modifier;
|
|
29
36
|
|
|
30
|
-
if (
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
const propertyName = (0, _util.method)(targetNode) && (0, _util.method)(targetNode).name; // Look for `toThrow` calls with no arguments.
|
|
35
|
-
|
|
36
|
-
if (['toThrow', 'toThrowError'].includes(propertyName) && !(0, _util.argument)(targetNode)) {
|
|
37
|
+
if (matcher && matcher.arguments && matcher.arguments.length === 0 && ['toThrow', 'toThrowError'].includes(matcher.name) && (!modifier || !(modifier.name === _utils.ModifierName.not || modifier.negation))) {
|
|
38
|
+
// Look for `toThrow` calls with no arguments.
|
|
37
39
|
context.report({
|
|
38
40
|
messageId: 'requireRethrow',
|
|
41
|
+
// todo: rename to 'addErrorMessage'
|
|
39
42
|
data: {
|
|
40
|
-
propertyName
|
|
43
|
+
propertyName: matcher.name
|
|
41
44
|
},
|
|
42
|
-
|
|
45
|
+
// todo: rename to 'matcherName'
|
|
46
|
+
node: matcher.node.property
|
|
43
47
|
});
|
|
44
48
|
}
|
|
45
49
|
}
|
|
@@ -47,5 +51,6 @@ var _default = {
|
|
|
47
51
|
};
|
|
48
52
|
}
|
|
49
53
|
|
|
50
|
-
};
|
|
54
|
+
});
|
|
55
|
+
|
|
51
56
|
exports.default = _default;
|