eslint-plugin-jest 22.21.0 → 23.0.3
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/CHANGELOG.md +29 -2
- package/README.md +12 -14
- package/docs/rules/{require-tothrow-message.md → require-to-throw-message.md} +0 -0
- package/docs/rules/valid-title.md +78 -0
- package/lib/__tests__/__snapshots__/rules.test.ts.snap +94 -0
- package/lib/__tests__/rules.test.js +19 -2
- package/lib/index.js +9 -3
- package/lib/rules/expect-expect.js +5 -25
- package/lib/rules/lowercase-name.js +4 -12
- package/lib/rules/no-alias-methods.js +3 -2
- package/lib/rules/no-export.js +13 -30
- package/lib/rules/no-focused-tests.js +3 -1
- package/lib/rules/no-identical-title.js +1 -10
- package/lib/rules/no-jasmine-globals.js +10 -4
- package/lib/rules/no-mocks-import.js +1 -10
- package/lib/rules/no-test-callback.js +16 -15
- package/lib/rules/no-test-return-statement.js +1 -10
- package/lib/rules/no-truthy-falsy.js +3 -2
- package/lib/rules/prefer-called-with.js +4 -4
- package/lib/rules/prefer-expect-assertions.js +1 -11
- package/lib/rules/prefer-inline-snapshots.js +3 -1
- package/lib/rules/prefer-spy-on.js +5 -14
- package/lib/rules/prefer-strict-equal.js +3 -2
- package/lib/rules/prefer-to-be-null.js +3 -2
- package/lib/rules/prefer-to-be-undefined.js +3 -2
- package/lib/rules/prefer-to-contain.js +10 -23
- package/lib/rules/prefer-to-have-length.js +6 -12
- package/lib/rules/prefer-todo.js +3 -15
- package/lib/rules/{require-tothrow-message.js → require-to-throw-message.js} +7 -8
- package/lib/rules/utils.js +36 -50
- package/lib/rules/valid-describe.js +9 -29
- package/lib/rules/valid-expect-in-promise.js +4 -14
- package/lib/rules/valid-expect.js +5 -4
- package/lib/rules/valid-title.js +48 -15
- package/package.json +27 -13
- package/docs/rules/no-empty-title.md +0 -36
- package/lib/rules/no-empty-title.js +0 -60
|
@@ -7,14 +7,6 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _utils = require("./utils");
|
|
9
9
|
|
|
10
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
11
|
-
|
|
12
|
-
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
13
|
-
|
|
14
|
-
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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; }
|
|
15
|
-
|
|
16
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
|
-
|
|
18
10
|
var _default = (0, _utils.createRule)({
|
|
19
11
|
name: __filename,
|
|
20
12
|
meta: {
|
|
@@ -24,7 +16,8 @@ var _default = (0, _utils.createRule)({
|
|
|
24
16
|
recommended: false
|
|
25
17
|
},
|
|
26
18
|
messages: {
|
|
27
|
-
illegalTestCallback: 'Illegal usage of test callback'
|
|
19
|
+
illegalTestCallback: 'Illegal usage of test callback',
|
|
20
|
+
useAwaitInsteadOfCallback: 'Use await instead of callback in async functions'
|
|
28
21
|
},
|
|
29
22
|
fixable: 'code',
|
|
30
23
|
schema: [],
|
|
@@ -39,22 +32,30 @@ var _default = (0, _utils.createRule)({
|
|
|
39
32
|
return;
|
|
40
33
|
}
|
|
41
34
|
|
|
42
|
-
const
|
|
43
|
-
callback = _node$arguments[1];
|
|
35
|
+
const [, callback] = node.arguments;
|
|
44
36
|
|
|
45
37
|
if (!(0, _utils.isFunction)(callback) || callback.params.length !== 1) {
|
|
46
38
|
return;
|
|
47
39
|
}
|
|
48
40
|
|
|
49
|
-
const
|
|
50
|
-
|
|
41
|
+
const [argument] = callback.params;
|
|
42
|
+
|
|
43
|
+
if (callback.async) {
|
|
44
|
+
context.report({
|
|
45
|
+
node: argument,
|
|
46
|
+
messageId: 'useAwaitInsteadOfCallback'
|
|
47
|
+
});
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
51
50
|
|
|
52
51
|
context.report({
|
|
53
52
|
node: argument,
|
|
54
53
|
messageId: 'illegalTestCallback',
|
|
55
54
|
|
|
56
55
|
fix(fixer) {
|
|
57
|
-
const
|
|
56
|
+
const {
|
|
57
|
+
body
|
|
58
|
+
} = callback;
|
|
58
59
|
/* istanbul ignore if https://github.com/typescript-eslint/typescript-eslint/issues/734 */
|
|
59
60
|
|
|
60
61
|
if (!body) {
|
|
@@ -90,7 +91,7 @@ var _default = (0, _utils.createRule)({
|
|
|
90
91
|
let replaceBefore = true;
|
|
91
92
|
|
|
92
93
|
if (body.type === 'BlockStatement') {
|
|
93
|
-
const keyword =
|
|
94
|
+
const keyword = 'return';
|
|
94
95
|
beforeReplacement = `${keyword} ${beforeReplacement}{`;
|
|
95
96
|
afterReplacement += '}';
|
|
96
97
|
replaceBefore = false;
|
|
@@ -7,20 +7,11 @@ exports.default = void 0;
|
|
|
7
7
|
|
|
8
8
|
var _utils = require("./utils");
|
|
9
9
|
|
|
10
|
-
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
|
|
11
|
-
|
|
12
|
-
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
|
|
13
|
-
|
|
14
|
-
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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; }
|
|
15
|
-
|
|
16
|
-
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
|
|
17
|
-
|
|
18
10
|
const RETURN_STATEMENT = 'ReturnStatement';
|
|
19
11
|
const BLOCK_STATEMENT = 'BlockStatement';
|
|
20
12
|
|
|
21
13
|
const getBody = args => {
|
|
22
|
-
const
|
|
23
|
-
secondArg = _args[1];
|
|
14
|
+
const [, secondArg] = args;
|
|
24
15
|
|
|
25
16
|
if (secondArg && (0, _utils.isFunction)(secondArg) && secondArg.body && secondArg.body.type === BLOCK_STATEMENT) {
|
|
26
17
|
return secondArg.body.body;
|
|
@@ -31,8 +31,9 @@ var _default = (0, _utils.createRule)({
|
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const
|
|
35
|
-
|
|
34
|
+
const {
|
|
35
|
+
matcher
|
|
36
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
36
37
|
|
|
37
38
|
if (!matcher || !['toBeTruthy', 'toBeFalsy'].includes(matcher.name)) {
|
|
38
39
|
return;
|
|
@@ -30,10 +30,10 @@ var _default = (0, _utils.createRule)({
|
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
const {
|
|
34
|
+
modifier,
|
|
35
|
+
matcher
|
|
36
|
+
} = (0, _utils.parseExpectCall)(node); // Could check resolves/rejects here but not a likely idiom.
|
|
37
37
|
|
|
38
38
|
if (matcher && !modifier) {
|
|
39
39
|
if (['toBeCalled', 'toHaveBeenCalled'].includes(matcher.name)) {
|
|
@@ -9,14 +9,6 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
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) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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
12
|
const isExpectAssertionsOrHasAssertionsCall = expression => {
|
|
21
13
|
if (expression.type !== _experimentalUtils.AST_NODE_TYPES.CallExpression || expression.callee.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression || !(0, _utils.isSupportedAccessor)(expression.callee.object, 'expect') || !(0, _utils.isSupportedAccessor)(expression.callee.property)) {
|
|
22
14
|
return false;
|
|
@@ -28,9 +20,7 @@ const isExpectAssertionsOrHasAssertionsCall = expression => {
|
|
|
28
20
|
return expectAssertionName === 'hasAssertions';
|
|
29
21
|
}
|
|
30
22
|
|
|
31
|
-
const
|
|
32
|
-
arg = _expression$arguments[0];
|
|
33
|
-
|
|
23
|
+
const [arg] = expression.arguments;
|
|
34
24
|
return expression.arguments && expression.arguments.length === 1 && arg.type === _experimentalUtils.AST_NODE_TYPES.Literal && typeof arg.value === 'number' && Number.isInteger(arg.value);
|
|
35
25
|
};
|
|
36
26
|
|
|
@@ -30,7 +30,9 @@ var _default = (0, _utils.createRule)({
|
|
|
30
30
|
create(context) {
|
|
31
31
|
return {
|
|
32
32
|
CallExpression(node) {
|
|
33
|
-
const
|
|
33
|
+
const {
|
|
34
|
+
callee
|
|
35
|
+
} = node;
|
|
34
36
|
|
|
35
37
|
if (callee.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression || callee.property.type !== _experimentalUtils.AST_NODE_TYPES.Identifier) {
|
|
36
38
|
return;
|
|
@@ -9,14 +9,6 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
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) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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
12
|
const findNodeObject = node => {
|
|
21
13
|
if ('object' in node) {
|
|
22
14
|
return node.object;
|
|
@@ -67,8 +59,10 @@ var _default = (0, _utils.createRule)({
|
|
|
67
59
|
create(context) {
|
|
68
60
|
return {
|
|
69
61
|
AssignmentExpression(node) {
|
|
70
|
-
const
|
|
71
|
-
|
|
62
|
+
const {
|
|
63
|
+
left,
|
|
64
|
+
right
|
|
65
|
+
} = node;
|
|
72
66
|
if (left.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression) return;
|
|
73
67
|
const jestFnCall = getJestFnCall(right);
|
|
74
68
|
if (!jestFnCall) return;
|
|
@@ -78,10 +72,7 @@ var _default = (0, _utils.createRule)({
|
|
|
78
72
|
|
|
79
73
|
fix(fixer) {
|
|
80
74
|
const leftPropQuote = left.property.type === _experimentalUtils.AST_NODE_TYPES.Identifier ? "'" : '';
|
|
81
|
-
|
|
82
|
-
const _jestFnCall$arguments = _slicedToArray(jestFnCall.arguments, 1),
|
|
83
|
-
arg = _jestFnCall$arguments[0];
|
|
84
|
-
|
|
75
|
+
const [arg] = jestFnCall.arguments;
|
|
85
76
|
const argSource = arg && context.getSourceCode().getText(arg);
|
|
86
77
|
const mockImplementation = argSource ? `.mockImplementation(${argSource})` : '.mockImplementation()';
|
|
87
78
|
return [fixer.insertTextBefore(left, `jest.spyOn(`), fixer.replaceTextRange([left.object.range[1], left.property.range[0]], `, ${leftPropQuote}`), fixer.replaceTextRange([left.property.range[1], jestFnCall.range[1]], `${leftPropQuote})${mockImplementation}`)];
|
|
@@ -31,8 +31,9 @@ var _default = (0, _utils.createRule)({
|
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const
|
|
35
|
-
|
|
34
|
+
const {
|
|
35
|
+
matcher
|
|
36
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
36
37
|
|
|
37
38
|
if (matcher && (0, _utils.isParsedEqualityMatcherCall)(matcher, _utils.EqualityMatcher.toEqual)) {
|
|
38
39
|
context.report({
|
|
@@ -46,8 +46,9 @@ var _default = (0, _utils.createRule)({
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const {
|
|
50
|
+
matcher
|
|
51
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
51
52
|
|
|
52
53
|
if (matcher && isNullEqualityMatcher(matcher)) {
|
|
53
54
|
context.report({
|
|
@@ -46,8 +46,9 @@ var _default = (0, _utils.createRule)({
|
|
|
46
46
|
return;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
-
const
|
|
50
|
-
|
|
49
|
+
const {
|
|
50
|
+
matcher
|
|
51
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
51
52
|
|
|
52
53
|
if (matcher && isUndefinedEqualityMatcher(matcher)) {
|
|
53
54
|
context.report({
|
|
@@ -9,14 +9,6 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
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) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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
12
|
const isBooleanLiteral = node => node.type === _experimentalUtils.AST_NODE_TYPES.Literal && typeof node.value === 'boolean';
|
|
21
13
|
|
|
22
14
|
/**
|
|
@@ -60,9 +52,7 @@ const buildToContainFuncExpectation = negated => negated ? `${_utils.ModifierNam
|
|
|
60
52
|
const findPropertyDotToken = (member, sourceCode) => sourceCode.getFirstTokenBetween(member.object, member.property, token => token.value === '.');
|
|
61
53
|
|
|
62
54
|
const getNegationFixes = (node, modifier, matcher, sourceCode, fixer, fileName) => {
|
|
63
|
-
const
|
|
64
|
-
containArg = _node$arguments[0];
|
|
65
|
-
|
|
55
|
+
const [containArg] = node.arguments;
|
|
66
56
|
const negationPropertyDot = findPropertyDotToken(modifier.node, sourceCode);
|
|
67
57
|
const toContainFunc = buildToContainFuncExpectation((0, _utils.followTypeAssertionChain)(matcher.arguments[0]).value);
|
|
68
58
|
/* istanbul ignore if */
|
|
@@ -75,9 +65,7 @@ const getNegationFixes = (node, modifier, matcher, sourceCode, fixer, fileName)
|
|
|
75
65
|
};
|
|
76
66
|
|
|
77
67
|
const getCommonFixes = (node, sourceCode, fileName) => {
|
|
78
|
-
const
|
|
79
|
-
containArg = _node$arguments2[0];
|
|
80
|
-
|
|
68
|
+
const [containArg] = node.arguments;
|
|
81
69
|
const includesCallee = node.callee;
|
|
82
70
|
const propertyDot = findPropertyDotToken(includesCallee, sourceCode);
|
|
83
71
|
const closingParenthesis = sourceCode.getTokenAfter(containArg);
|
|
@@ -116,11 +104,13 @@ var _default = (0, _utils.createRule)({
|
|
|
116
104
|
return;
|
|
117
105
|
}
|
|
118
106
|
|
|
119
|
-
const
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
107
|
+
const {
|
|
108
|
+
expect: {
|
|
109
|
+
arguments: [includesCall]
|
|
110
|
+
},
|
|
111
|
+
matcher,
|
|
112
|
+
modifier
|
|
113
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
124
114
|
|
|
125
115
|
if (!matcher || modifier && modifier.name !== _utils.ModifierName.not || !isBooleanEqualityMatcher(matcher) || !isFixableIncludesCallExpression(includesCall)) {
|
|
126
116
|
return;
|
|
@@ -137,10 +127,7 @@ var _default = (0, _utils.createRule)({
|
|
|
137
127
|
}
|
|
138
128
|
|
|
139
129
|
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
|
-
|
|
130
|
+
const [containArg] = includesCall.arguments;
|
|
144
131
|
fixArr.push(fixer.replaceText(matcher.node.property, toContainFunc));
|
|
145
132
|
fixArr.push(fixer.replaceText(matcher.arguments[0], sourceCode.getText(containArg)));
|
|
146
133
|
return fixArr;
|
|
@@ -9,14 +9,6 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
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) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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
12
|
var _default = (0, _utils.createRule)({
|
|
21
13
|
name: __filename,
|
|
22
14
|
meta: {
|
|
@@ -41,10 +33,12 @@ var _default = (0, _utils.createRule)({
|
|
|
41
33
|
return;
|
|
42
34
|
}
|
|
43
35
|
|
|
44
|
-
const
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
36
|
+
const {
|
|
37
|
+
expect: {
|
|
38
|
+
arguments: [argument]
|
|
39
|
+
},
|
|
40
|
+
matcher
|
|
41
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
48
42
|
|
|
49
43
|
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
44
|
return;
|
package/lib/rules/prefer-todo.js
CHANGED
|
@@ -9,14 +9,6 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
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) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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
12
|
function isFunctionBodyEmpty(node) {
|
|
21
13
|
/* istanbul ignore if https://github.com/typescript-eslint/typescript-eslint/issues/734 */
|
|
22
14
|
if (!node.body) {
|
|
@@ -27,9 +19,7 @@ function isFunctionBodyEmpty(node) {
|
|
|
27
19
|
}
|
|
28
20
|
|
|
29
21
|
function isTestBodyEmpty(node) {
|
|
30
|
-
const
|
|
31
|
-
fn = _node$arguments[1];
|
|
32
|
-
|
|
22
|
+
const [, fn] = node.arguments;
|
|
33
23
|
return fn && (0, _utils.isFunction)(fn) && isFunctionBodyEmpty(fn);
|
|
34
24
|
}
|
|
35
25
|
|
|
@@ -61,11 +51,9 @@ var _default = (0, _utils.createRule)({
|
|
|
61
51
|
create(context) {
|
|
62
52
|
return {
|
|
63
53
|
CallExpression(node) {
|
|
64
|
-
const
|
|
65
|
-
firstArg = _node$arguments2[0],
|
|
66
|
-
secondArg = _node$arguments2[1];
|
|
54
|
+
const [firstArg, secondArg] = node.arguments;
|
|
67
55
|
|
|
68
|
-
if (!isTargetedTestCase(node) || !(0, _utils.isStringNode)(firstArg)) {
|
|
56
|
+
if (!firstArg || !isTargetedTestCase(node) || !(0, _utils.isStringNode)(firstArg)) {
|
|
69
57
|
return;
|
|
70
58
|
}
|
|
71
59
|
|
|
@@ -16,7 +16,7 @@ var _default = (0, _utils.createRule)({
|
|
|
16
16
|
recommended: false
|
|
17
17
|
},
|
|
18
18
|
messages: {
|
|
19
|
-
|
|
19
|
+
addErrorMessage: 'Add an error message to {{ propertyName }}()'
|
|
20
20
|
},
|
|
21
21
|
type: 'suggestion',
|
|
22
22
|
schema: []
|
|
@@ -30,19 +30,18 @@ var _default = (0, _utils.createRule)({
|
|
|
30
30
|
return;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
const
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
const {
|
|
34
|
+
matcher,
|
|
35
|
+
modifier
|
|
36
|
+
} = (0, _utils.parseExpectCall)(node);
|
|
36
37
|
|
|
37
38
|
if (matcher && matcher.arguments && matcher.arguments.length === 0 && ['toThrow', 'toThrowError'].includes(matcher.name) && (!modifier || !(modifier.name === _utils.ModifierName.not || modifier.negation))) {
|
|
38
39
|
// Look for `toThrow` calls with no arguments.
|
|
39
40
|
context.report({
|
|
40
|
-
messageId: '
|
|
41
|
-
// todo: rename to 'addErrorMessage'
|
|
41
|
+
messageId: 'addErrorMessage',
|
|
42
42
|
data: {
|
|
43
|
-
|
|
43
|
+
matcherName: matcher.name
|
|
44
44
|
},
|
|
45
|
-
// todo: rename to 'matcherName'
|
|
46
45
|
node: matcher.node.property
|
|
47
46
|
});
|
|
48
47
|
}
|
package/lib/rules/utils.js
CHANGED
|
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getNodeName = getNodeName;
|
|
7
|
-
exports.scopeHasLocalReference = exports.isDescribe = exports.isTestCase = exports.isHook = exports.isFunction = exports.TestCaseProperty = exports.DescribeProperty = exports.HookName = exports.TestCaseName = exports.DescribeAlias = exports.parseExpectCall = exports.isParsedEqualityMatcherCall = exports.EqualityMatcher = exports.ModifierName = exports.isExpectMember = exports.isExpectCall = exports.getAccessorValue = exports.isSupportedAccessor = exports.hasOnlyOneArgument = exports.getStringValue = exports.isStringNode = exports.followTypeAssertionChain = exports.createRule = void 0;
|
|
7
|
+
exports.scopeHasLocalReference = exports.getJestFunctionArguments = exports.isDescribeEach = exports.isDescribe = exports.isTestCase = exports.isHook = exports.isFunction = exports.TestCaseProperty = exports.DescribeProperty = exports.HookName = exports.TestCaseName = exports.DescribeAlias = exports.parseExpectCall = exports.isParsedEqualityMatcherCall = exports.EqualityMatcher = exports.ModifierName = exports.isExpectMember = exports.isExpectCall = exports.getAccessorValue = exports.isSupportedAccessor = exports.hasOnlyOneArgument = exports.getStringValue = exports.isStringNode = exports.followTypeAssertionChain = exports.createRule = void 0;
|
|
8
8
|
|
|
9
9
|
var _path = require("path");
|
|
10
10
|
|
|
@@ -401,67 +401,53 @@ exports.isTestCase = isTestCase;
|
|
|
401
401
|
const isDescribe = node => {
|
|
402
402
|
return node.callee.type === _experimentalUtils.AST_NODE_TYPES.Identifier && DescribeAlias.hasOwnProperty(node.callee.name) || node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && node.callee.object.type === _experimentalUtils.AST_NODE_TYPES.Identifier && DescribeAlias.hasOwnProperty(node.callee.object.name) && node.callee.property.type === _experimentalUtils.AST_NODE_TYPES.Identifier && DescribeProperty.hasOwnProperty(node.callee.property.name);
|
|
403
403
|
};
|
|
404
|
+
/**
|
|
405
|
+
* Checks if the given `describe` is a call to `describe.each`.
|
|
406
|
+
*
|
|
407
|
+
* @param {JestFunctionCallExpression<DescribeAlias>} node
|
|
408
|
+
* @return {node is JestFunctionCallExpression<DescribeAlias, DescribeProperty.each>}
|
|
409
|
+
*/
|
|
410
|
+
|
|
404
411
|
|
|
405
412
|
exports.isDescribe = isDescribe;
|
|
406
413
|
|
|
414
|
+
const isDescribeEach = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, DescribeProperty.each);
|
|
415
|
+
/**
|
|
416
|
+
* Gets the arguments of the given `JestFunctionCallExpression`.
|
|
417
|
+
*
|
|
418
|
+
* If the `node` is an `each` call, then the arguments of the actual suite
|
|
419
|
+
* are returned, rather then the `each` array argument.
|
|
420
|
+
*
|
|
421
|
+
* @param {JestFunctionCallExpression<DescribeAlias | TestCaseName>} node
|
|
422
|
+
*
|
|
423
|
+
* @return {Expression[]}
|
|
424
|
+
*/
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
exports.isDescribeEach = isDescribeEach;
|
|
428
|
+
|
|
429
|
+
const getJestFunctionArguments = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, DescribeProperty.each) && node.parent && node.parent.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.parent.arguments : node.arguments;
|
|
430
|
+
|
|
431
|
+
exports.getJestFunctionArguments = getJestFunctionArguments;
|
|
432
|
+
|
|
407
433
|
const collectReferences = scope => {
|
|
408
434
|
const locals = new Set();
|
|
409
435
|
const unresolved = new Set();
|
|
410
436
|
let currentScope = scope;
|
|
411
437
|
|
|
412
438
|
while (currentScope !== null) {
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
const isReferenceDefined = ref.defs.some(def => {
|
|
421
|
-
return def.type !== 'ImplicitGlobalVariable';
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
if (isReferenceDefined) {
|
|
425
|
-
locals.add(ref.name);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
} catch (err) {
|
|
429
|
-
_didIteratorError = true;
|
|
430
|
-
_iteratorError = err;
|
|
431
|
-
} finally {
|
|
432
|
-
try {
|
|
433
|
-
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
434
|
-
_iterator.return();
|
|
435
|
-
}
|
|
436
|
-
} finally {
|
|
437
|
-
if (_didIteratorError) {
|
|
438
|
-
throw _iteratorError;
|
|
439
|
-
}
|
|
439
|
+
for (const ref of currentScope.variables) {
|
|
440
|
+
const isReferenceDefined = ref.defs.some(def => {
|
|
441
|
+
return def.type !== 'ImplicitGlobalVariable';
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
if (isReferenceDefined) {
|
|
445
|
+
locals.add(ref.name);
|
|
440
446
|
}
|
|
441
447
|
}
|
|
442
448
|
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
var _iteratorError2 = undefined;
|
|
446
|
-
|
|
447
|
-
try {
|
|
448
|
-
for (var _iterator2 = currentScope.through[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
|
|
449
|
-
const ref = _step2.value;
|
|
450
|
-
unresolved.add(ref.identifier.name);
|
|
451
|
-
}
|
|
452
|
-
} catch (err) {
|
|
453
|
-
_didIteratorError2 = true;
|
|
454
|
-
_iteratorError2 = err;
|
|
455
|
-
} finally {
|
|
456
|
-
try {
|
|
457
|
-
if (!_iteratorNormalCompletion2 && _iterator2.return != null) {
|
|
458
|
-
_iterator2.return();
|
|
459
|
-
}
|
|
460
|
-
} finally {
|
|
461
|
-
if (_didIteratorError2) {
|
|
462
|
-
throw _iteratorError2;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
449
|
+
for (const ref of currentScope.through) {
|
|
450
|
+
unresolved.add(ref.identifier.name);
|
|
465
451
|
}
|
|
466
452
|
|
|
467
453
|
currentScope = currentScope.upper;
|
|
@@ -9,18 +9,8 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
|
|
|
9
9
|
|
|
10
10
|
var _utils = require("./utils");
|
|
11
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) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } 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
12
|
const paramsLocation = params => {
|
|
21
|
-
const
|
|
22
|
-
first = _params[0];
|
|
23
|
-
|
|
13
|
+
const [first] = params;
|
|
24
14
|
const last = params[params.length - 1];
|
|
25
15
|
return {
|
|
26
16
|
start: first.loc.start,
|
|
@@ -28,8 +18,6 @@ const paramsLocation = params => {
|
|
|
28
18
|
};
|
|
29
19
|
};
|
|
30
20
|
|
|
31
|
-
const isDescribeEach = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && (0, _utils.isSupportedAccessor)(node.callee.property, 'each');
|
|
32
|
-
|
|
33
21
|
var _default = (0, _utils.createRule)({
|
|
34
22
|
name: __filename,
|
|
35
23
|
meta: {
|
|
@@ -41,7 +29,6 @@ var _default = (0, _utils.createRule)({
|
|
|
41
29
|
},
|
|
42
30
|
messages: {
|
|
43
31
|
nameAndCallback: 'Describe requires name and callback arguments',
|
|
44
|
-
firstArgumentMustBeName: 'First argument must be name',
|
|
45
32
|
secondArgumentMustBeFunction: 'Second argument must be function',
|
|
46
33
|
noAsyncDescribeCallback: 'No async describe callback',
|
|
47
34
|
unexpectedDescribeArgument: 'Unexpected argument(s) in describe callback',
|
|
@@ -54,32 +41,25 @@ var _default = (0, _utils.createRule)({
|
|
|
54
41
|
create(context) {
|
|
55
42
|
return {
|
|
56
43
|
CallExpression(node) {
|
|
57
|
-
if (!(0, _utils.isDescribe)(node)
|
|
44
|
+
if (!(0, _utils.isDescribe)(node)) {
|
|
58
45
|
return;
|
|
59
46
|
}
|
|
60
47
|
|
|
61
|
-
|
|
48
|
+
const nodeArguments = (0, _utils.getJestFunctionArguments)(node);
|
|
49
|
+
|
|
50
|
+
if (nodeArguments.length < 1) {
|
|
62
51
|
return context.report({
|
|
63
52
|
messageId: 'nameAndCallback',
|
|
64
53
|
loc: node.loc
|
|
65
54
|
});
|
|
66
55
|
}
|
|
67
56
|
|
|
68
|
-
const
|
|
69
|
-
name = _node$arguments[0],
|
|
70
|
-
callback = _node$arguments[1];
|
|
71
|
-
|
|
72
|
-
if (!(0, _utils.isStringNode)(name)) {
|
|
73
|
-
context.report({
|
|
74
|
-
messageId: 'firstArgumentMustBeName',
|
|
75
|
-
loc: paramsLocation(node.arguments)
|
|
76
|
-
});
|
|
77
|
-
}
|
|
57
|
+
const [, callback] = nodeArguments;
|
|
78
58
|
|
|
79
59
|
if (!callback) {
|
|
80
60
|
context.report({
|
|
81
61
|
messageId: 'nameAndCallback',
|
|
82
|
-
loc: paramsLocation(
|
|
62
|
+
loc: paramsLocation(nodeArguments)
|
|
83
63
|
});
|
|
84
64
|
return;
|
|
85
65
|
}
|
|
@@ -87,7 +67,7 @@ var _default = (0, _utils.createRule)({
|
|
|
87
67
|
if (!(0, _utils.isFunction)(callback)) {
|
|
88
68
|
context.report({
|
|
89
69
|
messageId: 'secondArgumentMustBeFunction',
|
|
90
|
-
loc: paramsLocation(
|
|
70
|
+
loc: paramsLocation(nodeArguments)
|
|
91
71
|
});
|
|
92
72
|
return;
|
|
93
73
|
}
|
|
@@ -99,7 +79,7 @@ var _default = (0, _utils.createRule)({
|
|
|
99
79
|
});
|
|
100
80
|
}
|
|
101
81
|
|
|
102
|
-
if (callback.params.length) {
|
|
82
|
+
if (!(0, _utils.isDescribeEach)(node) && callback.params.length) {
|
|
103
83
|
context.report({
|
|
104
84
|
messageId: 'unexpectedDescribeArgument',
|
|
105
85
|
loc: paramsLocation(callback.params)
|