eslint-plugin-jest 24.3.2 → 24.3.6

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 CHANGED
@@ -1,3 +1,34 @@
1
+ ## [24.3.6](https://github.com/jest-community/eslint-plugin-jest/compare/v24.3.5...v24.3.6) (2021-04-26)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * **no-conditional-expect:** check for expects in `catch`s on promises ([#819](https://github.com/jest-community/eslint-plugin-jest/issues/819)) ([1fee973](https://github.com/jest-community/eslint-plugin-jest/commit/1fee973429a74c60b14eead6a335623b4349b5f2))
7
+ * **valid-expect:** support async `expect` in ternary statements ([#833](https://github.com/jest-community/eslint-plugin-jest/issues/833)) ([7b7a396](https://github.com/jest-community/eslint-plugin-jest/commit/7b7a396e12c46d3087b467227887ed64854480c0))
8
+ * improve handling of `.each` calls and with tagged literals ([#814](https://github.com/jest-community/eslint-plugin-jest/issues/814)) ([040c605](https://github.com/jest-community/eslint-plugin-jest/commit/040c605cf7929a00980b3fa58331cd78ac6274f6))
9
+
10
+ ## [24.3.5](https://github.com/jest-community/eslint-plugin-jest/compare/v24.3.4...v24.3.5) (2021-04-10)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * **valid-describe:** support using `each` with modifiers ([#820](https://github.com/jest-community/eslint-plugin-jest/issues/820)) ([cbdbcef](https://github.com/jest-community/eslint-plugin-jest/commit/cbdbcef47984eb01509493bd5b2423f518a2663d))
16
+
17
+ ## [24.3.4](https://github.com/jest-community/eslint-plugin-jest/compare/v24.3.3...v24.3.4) (2021-04-05)
18
+
19
+
20
+ ### Bug Fixes
21
+
22
+ * support all variations of `describe`, `it`, & `test` ([#792](https://github.com/jest-community/eslint-plugin-jest/issues/792)) ([0968b55](https://github.com/jest-community/eslint-plugin-jest/commit/0968b557dd9cdb5cfcaf8a0d84e8a456825e6b25))
23
+
24
+ ## [24.3.3](https://github.com/jest-community/eslint-plugin-jest/compare/v24.3.2...v24.3.3) (2021-04-02)
25
+
26
+
27
+ ### Bug Fixes
28
+
29
+ * **no-duplicate-hooks:** support `describe.each` ([#797](https://github.com/jest-community/eslint-plugin-jest/issues/797)) ([243cb4f](https://github.com/jest-community/eslint-plugin-jest/commit/243cb4f970e40aa195a3bffa0528dbdbfef7c4f5)), closes [#642](https://github.com/jest-community/eslint-plugin-jest/issues/642)
30
+ * **prefer-expect-assertions:** support `.each` ([#798](https://github.com/jest-community/eslint-plugin-jest/issues/798)) ([f758243](https://github.com/jest-community/eslint-plugin-jest/commit/f75824359f2242f53997c59c238d83a59badeea3)), closes [#676](https://github.com/jest-community/eslint-plugin-jest/issues/676)
31
+
1
32
  ## [24.3.2](https://github.com/jest-community/eslint-plugin-jest/compare/v24.3.1...v24.3.2) (2021-03-16)
2
33
 
3
34
 
package/README.md CHANGED
@@ -214,6 +214,13 @@ ensure consistency and readability in jest test suites.
214
214
 
215
215
  https://github.com/dangreenisrael/eslint-plugin-jest-formatting
216
216
 
217
+ ### eslint-plugin-istanbul
218
+
219
+ A set of rules to enforce good practices for Istanbul, one of the code coverage
220
+ tools used by Jest.
221
+
222
+ https://github.com/istanbuljs/eslint-plugin-istanbul
223
+
217
224
  [recommended]: https://img.shields.io/badge/-recommended-lightgrey.svg
218
225
  [suggest]: https://img.shields.io/badge/-suggest-yellow.svg
219
226
  [fixable]: https://img.shields.io/badge/-fixable-green.svg
@@ -87,10 +87,10 @@ it('is money-like', () => {
87
87
 
88
88
  Examples of **correct** code for working with the HTTP assertions library
89
89
  [SuperTest](https://www.npmjs.com/package/supertest) with the
90
- `{ "assertFunctionNames": ["expect", "request.*.expect"] }` option:
90
+ `{ "assertFunctionNames": ["expect", "request.**.expect"] }` option:
91
91
 
92
92
  ```js
93
- /* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "request.*.expect"] }] */
93
+ /* eslint jest/expect-expect: ["error", { "assertFunctionNames": ["expect", "request.**.expect"] }] */
94
94
  const request = require('supertest');
95
95
  const express = require('express');
96
96
 
@@ -3,6 +3,9 @@
3
3
  This rule prevents the use of `expect` in conditional blocks, such as `if`s &
4
4
  `catch`s.
5
5
 
6
+ This includes using `expect` in callbacks to functions named `catch`, which are
7
+ assumed to be promises.
8
+
6
9
  ## Rule Details
7
10
 
8
11
  Jest considered a test to have failed if it throws an error, rather than on if
@@ -37,6 +40,10 @@ it('baz', async () => {
37
40
  expect(err).toMatchObject({ code: 'MODULE_NOT_FOUND' });
38
41
  }
39
42
  });
43
+
44
+ it('throws an error', async () => {
45
+ await foo().catch(error => expect(error).toBeInstanceOf(error));
46
+ });
40
47
  ```
41
48
 
42
49
  The following patterns are not warnings:
@@ -67,4 +74,8 @@ it('validates the request', () => {
67
74
  expect(validRequest).toHaveBeenCalledWith(request);
68
75
  }
69
76
  });
77
+
78
+ it('throws an error', async () => {
79
+ await expect(foo).rejects.toThrow(Error);
80
+ });
70
81
  ```
@@ -12,7 +12,7 @@ whenever you are using the exclusivity feature.
12
12
  ## Rule Details
13
13
 
14
14
  This rule looks for every `describe.only`, `it.only`, `test.only`, `fdescribe`,
15
- `fit` and `ftest` occurrences within the source code. Of course there are some
15
+ and `fit` occurrences within the source code. Of course there are some
16
16
  edge-cases which can’t be detected by this rule e.g.:
17
17
 
18
18
  ```js
@@ -31,13 +31,9 @@ test.only('foo', () => {});
31
31
  test['only']('bar', () => {});
32
32
  fdescribe('foo', () => {});
33
33
  fit('foo', () => {});
34
- ftest('bar', () => {});
35
34
  fit.each`
36
35
  table
37
36
  `();
38
- ftest.each`
39
- table
40
- `();
41
37
  ```
42
38
 
43
39
  These patterns would not be considered warnings:
@@ -56,13 +56,13 @@ var _default = (0, _utils.createRule)({
56
56
  return;
57
57
  }
58
58
 
59
- if ((0, _utils.isDescribe)(node)) {
59
+ if ((0, _utils.isDescribeCall)(node)) {
60
60
  describeNestingLevel++;
61
61
  }
62
62
 
63
- const funcNode = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee;
63
+ const funcNode = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
64
64
 
65
- if ((0, _utils.isTestCase)(node) && describeNestingLevel === 0 && !nodeName.includes(testKeyword)) {
65
+ if ((0, _utils.isTestCaseCall)(node) && describeNestingLevel === 0 && !nodeName.includes(testKeyword)) {
66
66
  const oppositeTestKeyword = getOppositeTestKeyword(testKeyword);
67
67
  context.report({
68
68
  messageId: 'consistentMethod',
@@ -75,7 +75,7 @@ var _default = (0, _utils.createRule)({
75
75
  });
76
76
  }
77
77
 
78
- if ((0, _utils.isTestCase)(node) && describeNestingLevel > 0 && !nodeName.includes(testKeywordWithinDescribe)) {
78
+ if ((0, _utils.isTestCaseCall)(node) && describeNestingLevel > 0 && !nodeName.includes(testKeywordWithinDescribe)) {
79
79
  const oppositeTestKeyword = getOppositeTestKeyword(testKeywordWithinDescribe);
80
80
  context.report({
81
81
  messageId: 'consistentMethodWithinDescribe',
@@ -90,7 +90,7 @@ var _default = (0, _utils.createRule)({
90
90
  },
91
91
 
92
92
  'CallExpression:exit'(node) {
93
- if ((0, _utils.isDescribe)(node) && !(0, _utils.isEachCall)(node)) {
93
+ if ((0, _utils.isDescribeCall)(node)) {
94
94
  describeNestingLevel--;
95
95
  }
96
96
  }
@@ -5,32 +5,20 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _experimentalUtils = require("@typescript-eslint/experimental-utils");
9
-
10
8
  var _utils = require("./utils");
11
9
 
12
10
  const hasStringAsFirstArgument = node => node.arguments[0] && (0, _utils.isStringNode)(node.arguments[0]);
13
11
 
14
12
  const findNodeNameAndArgument = node => {
15
- if (!((0, _utils.isTestCase)(node) || (0, _utils.isDescribe)(node))) {
16
- return null;
17
- }
18
-
19
- if ((0, _utils.isEachCall)(node)) {
20
- var _node$parent;
21
-
22
- if (((_node$parent = node.parent) === null || _node$parent === void 0 ? void 0 : _node$parent.type) === _experimentalUtils.AST_NODE_TYPES.CallExpression && hasStringAsFirstArgument(node.parent)) {
23
- return [node.callee.object.name, node.parent.arguments[0]];
24
- }
25
-
13
+ if (!((0, _utils.isTestCaseCall)(node) || (0, _utils.isDescribeCall)(node))) {
26
14
  return null;
27
15
  }
28
16
 
29
- if (node.callee.type !== _experimentalUtils.AST_NODE_TYPES.Identifier || !hasStringAsFirstArgument(node)) {
17
+ if (!hasStringAsFirstArgument(node)) {
30
18
  return null;
31
19
  }
32
20
 
33
- return [node.callee.name, node.arguments[0]];
21
+ return [(0, _utils.getNodeName)(node).split('.')[0], node.arguments[0]];
34
22
  };
35
23
 
36
24
  var _default = (0, _utils.createRule)({
@@ -85,7 +73,7 @@ var _default = (0, _utils.createRule)({
85
73
  let numberOfDescribeBlocks = 0;
86
74
  return {
87
75
  CallExpression(node) {
88
- if ((0, _utils.isDescribe)(node)) {
76
+ if ((0, _utils.isDescribeCall)(node)) {
89
77
  numberOfDescribeBlocks++;
90
78
 
91
79
  if (ignoreTopLevelDescribe && numberOfDescribeBlocks === 1) {
@@ -130,7 +118,7 @@ var _default = (0, _utils.createRule)({
130
118
  },
131
119
 
132
120
  'CallExpression:exit'(node) {
133
- if ((0, _utils.isDescribe)(node)) {
121
+ if ((0, _utils.isDescribeCall)(node)) {
134
122
  numberOfDescribeBlocks--;
135
123
  }
136
124
  }
@@ -5,8 +5,12 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
+ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
9
+
8
10
  var _utils = require("./utils");
9
11
 
12
+ const isCatchCall = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && (0, _utils.isSupportedAccessor)(node.callee.property, 'catch');
13
+
10
14
  var _default = (0, _utils.createRule)({
11
15
  name: __filename,
12
16
  meta: {
@@ -26,6 +30,7 @@ var _default = (0, _utils.createRule)({
26
30
  create(context) {
27
31
  let conditionalDepth = 0;
28
32
  let inTestCase = false;
33
+ let inPromiseCatch = false;
29
34
 
30
35
  const increaseConditionalDepth = () => inTestCase && conditionalDepth++;
31
36
 
@@ -42,22 +47,37 @@ var _default = (0, _utils.createRule)({
42
47
  },
43
48
 
44
49
  CallExpression(node) {
45
- if ((0, _utils.isTestCase)(node)) {
50
+ if ((0, _utils.isTestCaseCall)(node)) {
46
51
  inTestCase = true;
47
52
  }
48
53
 
54
+ if (isCatchCall(node)) {
55
+ inPromiseCatch = true;
56
+ }
57
+
49
58
  if (inTestCase && (0, _utils.isExpectCall)(node) && conditionalDepth > 0) {
50
59
  context.report({
51
60
  messageId: 'conditionalExpect',
52
61
  node
53
62
  });
54
63
  }
64
+
65
+ if (inPromiseCatch && (0, _utils.isExpectCall)(node)) {
66
+ context.report({
67
+ messageId: 'conditionalExpect',
68
+ node
69
+ });
70
+ }
55
71
  },
56
72
 
57
73
  'CallExpression:exit'(node) {
58
- if ((0, _utils.isTestCase)(node)) {
74
+ if ((0, _utils.isTestCaseCall)(node)) {
59
75
  inTestCase = false;
60
76
  }
77
+
78
+ if (isCatchCall(node)) {
79
+ inPromiseCatch = false;
80
+ }
61
81
  },
62
82
 
63
83
  CatchClause: increaseConditionalDepth,
@@ -18,7 +18,7 @@ const findCallbackArg = (node, isJestEach) => {
18
18
  return node.arguments[0];
19
19
  }
20
20
 
21
- if ((0, _utils.isTestCase)(node) && node.arguments.length >= 2) {
21
+ if ((0, _utils.isTestCaseCall)(node) && node.arguments.length >= 2) {
22
22
  return node.arguments[1];
23
23
  }
24
24
 
@@ -34,7 +34,7 @@ var _default = (0, _utils.createRule)({
34
34
  const hookContexts = [newHookContext()];
35
35
  return {
36
36
  CallExpression(node) {
37
- if ((0, _utils.isDescribe)(node)) {
37
+ if ((0, _utils.isDescribeCall)(node)) {
38
38
  hookContexts.push(newHookContext());
39
39
  }
40
40
 
@@ -55,7 +55,7 @@ var _default = (0, _utils.createRule)({
55
55
  },
56
56
 
57
57
  'CallExpression:exit'(node) {
58
- if ((0, _utils.isDescribe)(node)) {
58
+ if ((0, _utils.isDescribeCall)(node)) {
59
59
  hookContexts.pop();
60
60
  }
61
61
  }
@@ -41,7 +41,7 @@ var _default = (0, _utils.createRule)({
41
41
  },
42
42
 
43
43
  CallExpression(node) {
44
- if ((0, _utils.isTestCase)(node)) {
44
+ if ((0, _utils.isTestCaseCall)(node)) {
45
45
  hasTestCase = true;
46
46
  }
47
47
  },
@@ -9,16 +9,23 @@ var _experimentalUtils = require("@typescript-eslint/experimental-utils");
9
9
 
10
10
  var _utils = require("./utils");
11
11
 
12
- const validTestCaseNames = [_utils.TestCaseName.test, _utils.TestCaseName.it];
13
- const testFunctions = new Set([_utils.DescribeAlias.describe, ...validTestCaseNames]);
12
+ const findOnlyNode = node => {
13
+ const callee = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
14
14
 
15
- const isConcurrentExpression = expression => (0, _utils.isSupportedAccessor)(expression.property, _utils.TestCaseProperty.concurrent) && !!expression.parent && expression.parent.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression;
16
-
17
- const matchesTestFunction = object => 'name' in object && typeof object.name === 'string' && (object.name in _utils.TestCaseName || object.name in _utils.DescribeAlias);
15
+ if (callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression) {
16
+ if (callee.object.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression) {
17
+ if ((0, _utils.isSupportedAccessor)(callee.object.property, 'only')) {
18
+ return callee.object.property;
19
+ }
20
+ }
18
21
 
19
- const isCallToFocusedTestFunction = object => object.name.startsWith('f') && testFunctions.has(object.name.substring(1));
22
+ if ((0, _utils.isSupportedAccessor)(callee.property, 'only')) {
23
+ return callee.property;
24
+ }
25
+ }
20
26
 
21
- const isCallToTestOnlyFunction = callee => matchesTestFunction(callee.object) && (0, _utils.isSupportedAccessor)(isConcurrentExpression(callee) ? callee.parent.property : callee.property, 'only');
27
+ return null;
28
+ };
22
29
 
23
30
  var _default = (0, _utils.createRule)({
24
31
  name: __filename,
@@ -39,78 +46,36 @@ var _default = (0, _utils.createRule)({
39
46
  defaultOptions: [],
40
47
  create: context => ({
41
48
  CallExpression(node) {
42
- const callee = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee;
43
-
44
- if (callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression) {
45
- const calleeObject = callee.object;
46
-
47
- if (calleeObject.type === _experimentalUtils.AST_NODE_TYPES.Identifier && isCallToFocusedTestFunction(calleeObject)) {
48
- context.report({
49
- messageId: 'focusedTest',
50
- node: calleeObject,
51
- suggest: [{
52
- messageId: 'suggestRemoveFocus',
53
-
54
- fix(fixer) {
55
- return fixer.removeRange([calleeObject.range[0], calleeObject.range[0] + 1]);
56
- }
57
-
58
- }]
59
- });
60
- return;
61
- }
62
-
63
- if (calleeObject.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && isCallToTestOnlyFunction(calleeObject)) {
64
- context.report({
65
- messageId: 'focusedTest',
66
- node: isConcurrentExpression(calleeObject) ? callee.property : calleeObject.property,
67
- suggest: [{
68
- messageId: 'suggestRemoveFocus',
69
-
70
- fix(fixer) {
71
- if (calleeObject.property.type === _experimentalUtils.AST_NODE_TYPES.Identifier && calleeObject.property.name === 'only') {
72
- return fixer.removeRange([calleeObject.object.range[1], calleeObject.range[1]]);
73
- }
74
-
75
- return fixer.removeRange([calleeObject.range[1], callee.range[1]]);
76
- }
77
-
78
- }]
79
- });
80
- return;
81
- }
82
-
83
- if (isCallToTestOnlyFunction(callee)) {
84
- context.report({
85
- messageId: 'focusedTest',
86
- node: callee.property,
87
- suggest: [{
88
- messageId: 'suggestRemoveFocus',
89
-
90
- fix(fixer) {
91
- return fixer.removeRange([calleeObject.range[1], callee.range[1]]);
92
- }
93
-
94
- }]
95
- });
96
- return;
97
- }
49
+ if (!(0, _utils.isDescribeCall)(node) && !(0, _utils.isTestCaseCall)(node)) {
50
+ return;
98
51
  }
99
52
 
100
- if (callee.type === _experimentalUtils.AST_NODE_TYPES.Identifier && isCallToFocusedTestFunction(callee)) {
53
+ if ((0, _utils.getNodeName)(node).startsWith('f')) {
101
54
  context.report({
102
55
  messageId: 'focusedTest',
103
- node: callee,
56
+ node,
104
57
  suggest: [{
105
58
  messageId: 'suggestRemoveFocus',
106
-
107
- fix(fixer) {
108
- return fixer.removeRange([callee.range[0], callee.range[0] + 1]);
109
- }
110
-
59
+ fix: fixer => fixer.removeRange([node.range[0], node.range[0] + 1])
111
60
  }]
112
61
  });
62
+ return;
113
63
  }
64
+
65
+ const onlyNode = findOnlyNode(node);
66
+
67
+ if (!onlyNode) {
68
+ return;
69
+ }
70
+
71
+ context.report({
72
+ messageId: 'focusedTest',
73
+ node: onlyNode,
74
+ suggest: [{
75
+ messageId: 'suggestRemoveFocus',
76
+ fix: fixer => fixer.removeRange([onlyNode.range[0] - 1, onlyNode.range[1] + Number(onlyNode.type !== _experimentalUtils.AST_NODE_TYPES.Identifier)])
77
+ }]
78
+ });
114
79
  }
115
80
 
116
81
  })
@@ -37,7 +37,7 @@ var _default = (0, _utils.createRule)({
37
37
  CallExpression(node) {
38
38
  const currentLayer = contexts[contexts.length - 1];
39
39
 
40
- if ((0, _utils.isDescribe)(node)) {
40
+ if ((0, _utils.isDescribeCall)(node)) {
41
41
  contexts.push(newDescribeContext());
42
42
  }
43
43
 
@@ -53,7 +53,7 @@ var _default = (0, _utils.createRule)({
53
53
 
54
54
  const title = (0, _utils.getStringValue)(argument);
55
55
 
56
- if ((0, _utils.isTestCase)(node)) {
56
+ if ((0, _utils.isTestCaseCall)(node)) {
57
57
  if (currentLayer.testTitles.includes(title)) {
58
58
  context.report({
59
59
  messageId: 'multipleTestTitle',
@@ -64,7 +64,7 @@ var _default = (0, _utils.createRule)({
64
64
  currentLayer.testTitles.push(title);
65
65
  }
66
66
 
67
- if (!(0, _utils.isDescribe)(node)) {
67
+ if (!(0, _utils.isDescribeCall)(node)) {
68
68
  return;
69
69
  }
70
70
 
@@ -79,7 +79,7 @@ var _default = (0, _utils.createRule)({
79
79
  },
80
80
 
81
81
  'CallExpression:exit'(node) {
82
- if ((0, _utils.isDescribe)(node)) {
82
+ if ((0, _utils.isDescribeCall)(node)) {
83
83
  contexts.pop();
84
84
  }
85
85
  }
@@ -56,8 +56,12 @@ var _default = (0, _utils.createRule)({
56
56
 
57
57
  return {
58
58
  CallExpression(node) {
59
- if ((0, _utils.isTestCase)(node)) {
59
+ if ((0, _utils.isTestCaseCall)(node)) {
60
60
  stack.push(true);
61
+
62
+ if ((0, _utils.getNodeName)(node).endsWith('each')) {
63
+ stack.push(true);
64
+ }
61
65
  }
62
66
  },
63
67
 
@@ -30,7 +30,7 @@ const getBlockType = statement => {
30
30
  } // if it's not a variable, it will be callExpr, we only care about describe
31
31
 
32
32
 
33
- if (expr.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && (0, _utils.isDescribe)(expr)) {
33
+ if (expr.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && (0, _utils.isDescribeCall)(expr)) {
34
34
  return 'describe';
35
35
  }
36
36
  }
@@ -38,8 +38,6 @@ const getBlockType = statement => {
38
38
  return null;
39
39
  };
40
40
 
41
- const isEach = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && node.callee.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && node.callee.callee.property.type === _experimentalUtils.AST_NODE_TYPES.Identifier && node.callee.callee.property.name === 'each' && node.callee.callee.object.type === _experimentalUtils.AST_NODE_TYPES.Identifier && _utils.TestCaseName.hasOwnProperty(node.callee.callee.object.name);
42
-
43
41
  var _default = (0, _utils.createRule)({
44
42
  name: __filename,
45
43
  meta: {
@@ -75,7 +73,7 @@ var _default = (0, _utils.createRule)({
75
73
 
76
74
  const isCustomTestBlockFunction = node => additionalTestBlockFunctions.includes((0, _utils.getNodeName)(node) || '');
77
75
 
78
- const isTestBlock = node => (0, _utils.isTestCase)(node) || isCustomTestBlockFunction(node);
76
+ const isTestBlock = node => (0, _utils.isTestCaseCall)(node) || isCustomTestBlockFunction(node);
79
77
 
80
78
  return {
81
79
  CallExpression(node) {
@@ -104,7 +102,7 @@ var _default = (0, _utils.createRule)({
104
102
  'CallExpression:exit'(node) {
105
103
  const top = callStack[callStack.length - 1];
106
104
 
107
- if (top === 'test' && (isEach(node) || isTestBlock(node) && node.callee.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression) || top === 'template' && node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression) {
105
+ if (top === 'test' && isTestBlock(node) && node.callee.type !== _experimentalUtils.AST_NODE_TYPES.MemberExpression || top === 'template' && node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression) {
108
106
  callStack.pop();
109
107
  }
110
108
  },
@@ -30,10 +30,10 @@ var _default = (0, _utils.createRule)({
30
30
  return {
31
31
  CallExpression(node) {
32
32
  const nodeName = (0, _utils.getNodeName)(node.callee);
33
- if (!nodeName || !(0, _utils.isDescribe)(node) && !(0, _utils.isTestCase)(node)) return;
33
+ if (!nodeName || !(0, _utils.isDescribeCall)(node) && !(0, _utils.isTestCaseCall)(node)) return;
34
34
  const preferredNodeName = getPreferredNodeName(nodeName);
35
35
  if (!preferredNodeName) return;
36
- const funcNode = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee;
36
+ const funcNode = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
37
37
  context.report({
38
38
  messageId: 'usePreferredName',
39
39
  node: node.callee,
@@ -38,7 +38,7 @@ var _default = (0, _utils.createRule)({
38
38
  create(context) {
39
39
  return {
40
40
  CallExpression(node) {
41
- if (!(0, _utils.isTestCase)(node)) return;
41
+ if (!(0, _utils.isTestCaseCall)(node)) return;
42
42
  const body = getBody(node.arguments);
43
43
  const returnStmt = body.find(t => t.type === _experimentalUtils.AST_NODE_TYPES.ReturnStatement);
44
44
  if (!returnStmt) return;
@@ -35,7 +35,7 @@ var _default = (0, _utils.createRule)({
35
35
 
36
36
  return {
37
37
  CallExpression(node) {
38
- if ((0, _utils.isTestCase)(node)) {
38
+ if ((0, _utils.isTestCaseCall)(node)) {
39
39
  isTest = true;
40
40
  } else if (isTest && isThrowExpectCall(node)) {
41
41
  context.report({
@@ -67,7 +67,7 @@ var _default = (0, _utils.createRule)({
67
67
  },
68
68
 
69
69
  'CallExpression:exit'(node) {
70
- if ((0, _utils.isTestCase)(node)) {
70
+ if ((0, _utils.isTestCaseCall)(node)) {
71
71
  isTest = false;
72
72
  }
73
73
  },
@@ -55,12 +55,22 @@ var _default = (0, _utils.createRule)({
55
55
 
56
56
  create(context, [options]) {
57
57
  return {
58
- 'CallExpression[callee.name=/^(it|test)$/][arguments.1.body.body]'(node) {
59
- if (options.onlyFunctionsWithAsyncKeyword && !node.arguments[1].async) {
58
+ CallExpression(node) {
59
+ if (!(0, _utils.isTestCaseCall)(node)) {
60
60
  return;
61
61
  }
62
62
 
63
- const testFuncBody = node.arguments[1].body.body;
63
+ if (node.arguments.length < 2) {
64
+ return;
65
+ }
66
+
67
+ const [, testFn] = node.arguments;
68
+
69
+ if (!(0, _utils.isFunction)(testFn) || testFn.body.type !== _experimentalUtils.AST_NODE_TYPES.BlockStatement || options.onlyFunctionsWithAsyncKeyword && !testFn.async) {
70
+ return;
71
+ }
72
+
73
+ const testFuncBody = testFn.body.body;
64
74
 
65
75
  if (!isFirstLineExprStmt(testFuncBody)) {
66
76
  context.report({
@@ -68,7 +78,7 @@ var _default = (0, _utils.createRule)({
68
78
  node,
69
79
  suggest: suggestions.map(([messageId, text]) => ({
70
80
  messageId,
71
- fix: fixer => fixer.insertTextBeforeRange([node.arguments[1].body.range[0] + 1, node.arguments[1].body.range[1]], text)
81
+ fix: fixer => fixer.insertTextBeforeRange([testFn.body.range[0] + 1, testFn.body.range[1]], text)
72
82
  }))
73
83
  });
74
84
  return;
@@ -27,7 +27,7 @@ var _default = (0, _utils.createRule)({
27
27
  const hooksContext = [false];
28
28
  return {
29
29
  CallExpression(node) {
30
- if (!(0, _utils.isHook)(node) && (0, _utils.isTestCase)(node)) {
30
+ if (!(0, _utils.isHook)(node) && (0, _utils.isTestCaseCall)(node)) {
31
31
  hooksContext[hooksContext.length - 1] = true;
32
32
  }
33
33
 
@@ -18,11 +18,11 @@ function isEmptyFunction(node) {
18
18
  }
19
19
 
20
20
  function createTodoFixer(node, fixer) {
21
- const testName = (0, _utils.getNodeName)(node.callee).split('.').shift();
21
+ const testName = (0, _utils.getNodeName)(node).split('.').shift();
22
22
  return fixer.replaceText(node.callee, `${testName}.todo`);
23
23
  }
24
24
 
25
- const isTargetedTestCase = node => (0, _utils.isTestCase)(node) && [_utils.TestCaseName.it, _utils.TestCaseName.test, 'it.skip', 'test.skip'].includes((0, _utils.getNodeName)(node.callee));
25
+ const isTargetedTestCase = node => (0, _utils.isTestCaseCall)(node) && [_utils.TestCaseName.it, _utils.TestCaseName.test, 'it.skip', 'test.skip'].includes((0, _utils.getNodeName)(node));
26
26
 
27
27
  var _default = (0, _utils.createRule)({
28
28
  name: __filename,
@@ -28,13 +28,13 @@ var _default = (0, _utils.createRule)({
28
28
  let numberOfDescribeBlocks = 0;
29
29
  return {
30
30
  CallExpression(node) {
31
- if ((0, _utils.isDescribe)(node)) {
31
+ if ((0, _utils.isDescribeCall)(node)) {
32
32
  numberOfDescribeBlocks++;
33
33
  return;
34
34
  }
35
35
 
36
36
  if (numberOfDescribeBlocks === 0) {
37
- if ((0, _utils.isTestCase)(node)) {
37
+ if ((0, _utils.isTestCaseCall)(node)) {
38
38
  context.report({
39
39
  node,
40
40
  messageId: 'unexpectedTestCase'
@@ -53,7 +53,7 @@ var _default = (0, _utils.createRule)({
53
53
  },
54
54
 
55
55
  'CallExpression:exit'(node) {
56
- if ((0, _utils.isDescribe)(node) && !(0, _utils.isEachCall)(node)) {
56
+ if ((0, _utils.isDescribeCall)(node)) {
57
57
  numberOfDescribeBlocks--;
58
58
  }
59
59
  }
@@ -50,6 +50,8 @@ const tryCreateBaseRule = context => {
50
50
  }
51
51
  };
52
52
 
53
+ const DEFAULT_MESSAGE = 'This rule requires `@typescript-eslint/eslint-plugin`';
54
+
53
55
  var _default = (0, _utils.createRule)({
54
56
  defaultOptions: [{
55
57
  ignoreStatic: false
@@ -58,7 +60,8 @@ var _default = (0, _utils.createRule)({
58
60
  name: __filename,
59
61
  meta: {
60
62
  messages: {
61
- unbound: 'This rule requires `@typescript-eslint/eslint-plugin`'
63
+ unbound: DEFAULT_MESSAGE,
64
+ unboundWithoutThisAnnotation: DEFAULT_MESSAGE
62
65
  },
63
66
  schema: [],
64
67
  type: 'problem',
@@ -4,7 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.getNodeName = getNodeName;
7
- exports.scopeHasLocalReference = exports.getJestFunctionArguments = exports.isEachCall = exports.isDescribe = exports.isTestCase = exports.getTestCallExpressionsFromDeclaredVariables = 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.isDescribeCall = exports.isTestCaseCall = exports.getTestCallExpressionsFromDeclaredVariables = 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
 
@@ -390,48 +390,84 @@ const getTestCallExpressionsFromDeclaredVariables = declaredVariables => {
390
390
  references
391
391
  }) => acc.concat(references.map(({
392
392
  identifier
393
- }) => identifier.parent).filter(node => !!node && node.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && isTestCase(node))), []);
393
+ }) => identifier.parent).filter(node => !!node && node.type === _experimentalUtils.AST_NODE_TYPES.CallExpression && isTestCaseCall(node))), []);
394
394
  };
395
395
 
396
396
  exports.getTestCallExpressionsFromDeclaredVariables = getTestCallExpressionsFromDeclaredVariables;
397
397
 
398
- const isTestCase = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.Identifier && TestCaseName.hasOwnProperty(node.callee.name) || // e.g. it.each``()
399
- node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression && node.callee.tag.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && node.callee.tag.object.type === _experimentalUtils.AST_NODE_TYPES.Identifier && TestCaseName.hasOwnProperty(node.callee.tag.object.name) && isSupportedAccessor(node.callee.tag.property, TestCaseProperty.each) || // e.g. it.concurrent.{skip,only}
400
- node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && node.callee.property.type === _experimentalUtils.AST_NODE_TYPES.Identifier && TestCaseProperty.hasOwnProperty(node.callee.property.name) && (node.callee.object.type === _experimentalUtils.AST_NODE_TYPES.Identifier && TestCaseName.hasOwnProperty(node.callee.object.name) || node.callee.object.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && node.callee.object.object.type === _experimentalUtils.AST_NODE_TYPES.Identifier && TestCaseName.hasOwnProperty(node.callee.object.object.name));
398
+ const isTestCaseName = node => node.type === _experimentalUtils.AST_NODE_TYPES.Identifier && TestCaseName.hasOwnProperty(node.name);
401
399
 
402
- exports.isTestCase = isTestCase;
403
-
404
- const isDescribe = node => 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) || node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression && node.callee.tag.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && node.callee.tag.object.type === _experimentalUtils.AST_NODE_TYPES.Identifier && DescribeAlias.hasOwnProperty(node.callee.tag.object.name);
400
+ const isTestCaseProperty = node => isSupportedAccessor(node) && TestCaseProperty.hasOwnProperty(getAccessorValue(node));
405
401
  /**
406
- * Checks if the given node` is a call to `<describe|test|it>.each(...)`.
407
- * If `true`, the code must look like `<method>.each(...)`.
402
+ * Checks if the given `node` is a *call* to a test case function that would
403
+ * result in tests being run by `jest`.
404
+ *
405
+ * Note that `.each()` does not count as a call in this context, as it will not
406
+ * result in `jest` running any tests.
408
407
  *
409
- * @param {JestFunctionCallExpression<DescribeAlias | TestCaseName>} node
408
+ * @param {TSESTree.CallExpression} node
410
409
  *
411
- * @return {node is JestFunctionCallExpressionWithMemberExpressionCallee<DescribeAlias | TestCaseName, DescribeProperty.each | TestCaseProperty.each>}
410
+ * @return {node is JestFunctionCallExpression<TestCaseName>}
412
411
  */
413
412
 
414
413
 
415
- exports.isDescribe = isDescribe;
414
+ const isTestCaseCall = node => {
415
+ if (isTestCaseName(node.callee)) {
416
+ return true;
417
+ }
418
+
419
+ const callee = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
420
+
421
+ if (callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && isTestCaseProperty(callee.property)) {
422
+ // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
423
+ if (getAccessorValue(callee.property) === 'each' && node.callee.type !== _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression && node.callee.type !== _experimentalUtils.AST_NODE_TYPES.CallExpression) {
424
+ return false;
425
+ }
426
+
427
+ return callee.object.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression ? isTestCaseName(callee.object.object) : isTestCaseName(callee.object);
428
+ }
429
+
430
+ return false;
431
+ };
416
432
 
417
- const isEachCall = node => node.callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && isSupportedAccessor(node.callee.property, DescribeProperty.each);
433
+ exports.isTestCaseCall = isTestCaseCall;
434
+
435
+ const isDescribeAlias = node => node.type === _experimentalUtils.AST_NODE_TYPES.Identifier && DescribeAlias.hasOwnProperty(node.name);
436
+
437
+ const isDescribeProperty = node => isSupportedAccessor(node) && DescribeProperty.hasOwnProperty(getAccessorValue(node));
418
438
  /**
419
- * Gets the arguments of the given `JestFunctionCallExpression`.
439
+ * Checks if the given `node` is a *call* to a `describe` function that would
440
+ * result in a `describe` block being created by `jest`.
420
441
  *
421
- * If the `node` is an `each` call, then the arguments of the actual suite
422
- * are returned, rather then the `each` array argument.
442
+ * Note that `.each()` does not count as a call in this context, as it will not
443
+ * result in `jest` creating any `describe` blocks.
423
444
  *
424
- * @param {JestFunctionCallExpression<DescribeAlias | TestCaseName>} node
445
+ * @param {TSESTree.CallExpression} node
425
446
  *
426
- * @return {Expression[]}
447
+ * @return {node is JestFunctionCallExpression<TestCaseName>}
427
448
  */
428
449
 
429
450
 
430
- exports.isEachCall = isEachCall;
451
+ const isDescribeCall = node => {
452
+ if (isDescribeAlias(node.callee)) {
453
+ return true;
454
+ }
431
455
 
432
- 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;
456
+ const callee = node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression ? node.callee.tag : node.callee.type === _experimentalUtils.AST_NODE_TYPES.CallExpression ? node.callee.callee : node.callee;
457
+
458
+ if (callee.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression && isDescribeProperty(callee.property)) {
459
+ // if we're an `each()`, ensure we're the outer CallExpression (i.e `.each()()`)
460
+ if (getAccessorValue(callee.property) === 'each' && node.callee.type !== _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression && node.callee.type !== _experimentalUtils.AST_NODE_TYPES.CallExpression) {
461
+ return false;
462
+ }
463
+
464
+ return callee.object.type === _experimentalUtils.AST_NODE_TYPES.MemberExpression ? isDescribeAlias(callee.object.object) : isDescribeAlias(callee.object);
465
+ }
466
+
467
+ return false;
468
+ };
433
469
 
434
- exports.getJestFunctionArguments = getJestFunctionArguments;
470
+ exports.isDescribeCall = isDescribeCall;
435
471
 
436
472
  const collectReferences = scope => {
437
473
  const locals = new Set();
@@ -41,25 +41,23 @@ var _default = (0, _utils.createRule)({
41
41
  create(context) {
42
42
  return {
43
43
  CallExpression(node) {
44
- if (!(0, _utils.isDescribe)(node) || node.callee.type === _experimentalUtils.AST_NODE_TYPES.TaggedTemplateExpression) {
44
+ if (!(0, _utils.isDescribeCall)(node)) {
45
45
  return;
46
46
  }
47
47
 
48
- const nodeArguments = (0, _utils.getJestFunctionArguments)(node);
49
-
50
- if (nodeArguments.length < 1) {
48
+ if (node.arguments.length < 1) {
51
49
  return context.report({
52
50
  messageId: 'nameAndCallback',
53
51
  loc: node.loc
54
52
  });
55
53
  }
56
54
 
57
- const [, callback] = nodeArguments;
55
+ const [, callback] = node.arguments;
58
56
 
59
57
  if (!callback) {
60
58
  context.report({
61
59
  messageId: 'nameAndCallback',
62
- loc: paramsLocation(nodeArguments)
60
+ loc: paramsLocation(node.arguments)
63
61
  });
64
62
  return;
65
63
  }
@@ -67,7 +65,7 @@ var _default = (0, _utils.createRule)({
67
65
  if (!(0, _utils.isFunction)(callback)) {
68
66
  context.report({
69
67
  messageId: 'secondArgumentMustBeFunction',
70
- loc: paramsLocation(nodeArguments)
68
+ loc: paramsLocation(node.arguments)
71
69
  });
72
70
  return;
73
71
  }
@@ -79,7 +77,7 @@ var _default = (0, _utils.createRule)({
79
77
  });
80
78
  }
81
79
 
82
- if (!(0, _utils.isEachCall)(node) && callback.params.length) {
80
+ if (!(0, _utils.getNodeName)(node).endsWith('each') && callback.params.length) {
83
81
  context.report({
84
82
  messageId: 'unexpectedDescribeArgument',
85
83
  loc: paramsLocation(callback.params)
@@ -46,7 +46,17 @@ const getParentIfThenified = node => {
46
46
  return node;
47
47
  };
48
48
 
49
- const isAcceptableReturnNode = (node, allowReturn) => allowReturn && node.type === _experimentalUtils.AST_NODE_TYPES.ReturnStatement || [_experimentalUtils.AST_NODE_TYPES.ArrowFunctionExpression, _experimentalUtils.AST_NODE_TYPES.AwaitExpression].includes(node.type);
49
+ const isAcceptableReturnNode = (node, allowReturn) => {
50
+ if (allowReturn && node.type === _experimentalUtils.AST_NODE_TYPES.ReturnStatement) {
51
+ return true;
52
+ }
53
+
54
+ if (node.type === _experimentalUtils.AST_NODE_TYPES.ConditionalExpression && node.parent) {
55
+ return isAcceptableReturnNode(node.parent, allowReturn);
56
+ }
57
+
58
+ return [_experimentalUtils.AST_NODE_TYPES.ArrowFunctionExpression, _experimentalUtils.AST_NODE_TYPES.AwaitExpression].includes(node.type);
59
+ };
50
60
 
51
61
  const isNoAssertionsParentNode = node => node.type === _experimentalUtils.AST_NODE_TYPES.ExpressionStatement || node.type === _experimentalUtils.AST_NODE_TYPES.AwaitExpression && node.parent !== undefined && node.parent.type === _experimentalUtils.AST_NODE_TYPES.ExpressionStatement;
52
62
 
@@ -132,11 +132,11 @@ var _default = (0, _utils.createRule)({
132
132
  const mustMatchPatterns = compileMatcherPatterns(mustMatch !== null && mustMatch !== void 0 ? mustMatch : {});
133
133
  return {
134
134
  CallExpression(node) {
135
- if (!(0, _utils.isDescribe)(node) && !(0, _utils.isTestCase)(node)) {
135
+ if (!(0, _utils.isDescribeCall)(node) && !(0, _utils.isTestCaseCall)(node)) {
136
136
  return;
137
137
  }
138
138
 
139
- const [argument] = (0, _utils.getJestFunctionArguments)(node);
139
+ const [argument] = node.arguments;
140
140
 
141
141
  if (!argument) {
142
142
  return;
@@ -147,7 +147,7 @@ var _default = (0, _utils.createRule)({
147
147
  return;
148
148
  }
149
149
 
150
- if (argument.type !== _experimentalUtils.AST_NODE_TYPES.TemplateLiteral && !(ignoreTypeOfDescribeName && (0, _utils.isDescribe)(node))) {
150
+ if (argument.type !== _experimentalUtils.AST_NODE_TYPES.TemplateLiteral && !(ignoreTypeOfDescribeName && (0, _utils.isDescribeCall)(node))) {
151
151
  context.report({
152
152
  messageId: 'titleMustBeString',
153
153
  loc: argument.loc
@@ -163,7 +163,7 @@ var _default = (0, _utils.createRule)({
163
163
  context.report({
164
164
  messageId: 'emptyTitle',
165
165
  data: {
166
- jestFunctionName: (0, _utils.isDescribe)(node) ? _utils.DescribeAlias.describe : _utils.TestCaseName.test
166
+ jestFunctionName: (0, _utils.isDescribeCall)(node) ? _utils.DescribeAlias.describe : _utils.TestCaseName.test
167
167
  },
168
168
  node
169
169
  });
@@ -193,7 +193,7 @@ var _default = (0, _utils.createRule)({
193
193
  });
194
194
  }
195
195
 
196
- const nodeName = trimFXprefix((0, _utils.getNodeName)(node.callee));
196
+ const nodeName = trimFXprefix((0, _utils.getNodeName)(node));
197
197
  const [firstWord] = title.split(' ');
198
198
 
199
199
  if (firstWord.toLowerCase() === nodeName) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-jest",
3
- "version": "24.3.2",
3
+ "version": "24.3.6",
4
4
  "description": "Eslint rules for Jest",
5
5
  "keywords": [
6
6
  "eslint",
@@ -108,7 +108,7 @@
108
108
  "eslint-plugin-import": "^2.20.2",
109
109
  "eslint-plugin-node": "^11.0.0",
110
110
  "eslint-plugin-prettier": "^3.0.0",
111
- "husky": "^5.1.3",
111
+ "husky": "^6.0.0",
112
112
  "is-ci": "^3.0.0",
113
113
  "jest": "^26.0.1",
114
114
  "jest-runner-eslint": "^0.10.0",