@depup/eslint-plugin-jest 29.15.1-depup.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.
Files changed (158) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +31 -0
  3. package/changes.json +10 -0
  4. package/docs/rules/consistent-test-it.md +96 -0
  5. package/docs/rules/expect-expect.md +152 -0
  6. package/docs/rules/max-expects.md +78 -0
  7. package/docs/rules/max-nested-describe.md +134 -0
  8. package/docs/rules/no-alias-methods.md +57 -0
  9. package/docs/rules/no-commented-out-tests.md +68 -0
  10. package/docs/rules/no-conditional-expect.md +142 -0
  11. package/docs/rules/no-conditional-in-test.md +123 -0
  12. package/docs/rules/no-confusing-set-timeout.md +64 -0
  13. package/docs/rules/no-deprecated-functions.md +59 -0
  14. package/docs/rules/no-disabled-tests.md +72 -0
  15. package/docs/rules/no-done-callback.md +100 -0
  16. package/docs/rules/no-duplicate-hooks.md +79 -0
  17. package/docs/rules/no-error-equal.md +37 -0
  18. package/docs/rules/no-export.md +52 -0
  19. package/docs/rules/no-focused-tests.md +67 -0
  20. package/docs/rules/no-hooks.md +178 -0
  21. package/docs/rules/no-identical-title.md +59 -0
  22. package/docs/rules/no-interpolation-in-snapshots.md +67 -0
  23. package/docs/rules/no-jasmine-globals.md +69 -0
  24. package/docs/rules/no-large-snapshots.md +180 -0
  25. package/docs/rules/no-mocks-import.md +34 -0
  26. package/docs/rules/no-restricted-jest-methods.md +53 -0
  27. package/docs/rules/no-restricted-matchers.md +64 -0
  28. package/docs/rules/no-standalone-expect.md +106 -0
  29. package/docs/rules/no-test-prefixes.md +42 -0
  30. package/docs/rules/no-test-return-statement.md +50 -0
  31. package/docs/rules/no-unnecessary-assertion.md +41 -0
  32. package/docs/rules/no-unneeded-async-expect-function.md +41 -0
  33. package/docs/rules/no-untyped-mock-factory.md +74 -0
  34. package/docs/rules/padding-around-after-all-blocks.md +34 -0
  35. package/docs/rules/padding-around-after-each-blocks.md +38 -0
  36. package/docs/rules/padding-around-all.md +20 -0
  37. package/docs/rules/padding-around-before-all-blocks.md +37 -0
  38. package/docs/rules/padding-around-before-each-blocks.md +38 -0
  39. package/docs/rules/padding-around-describe-blocks.md +42 -0
  40. package/docs/rules/padding-around-expect-groups.md +44 -0
  41. package/docs/rules/padding-around-test-blocks.md +48 -0
  42. package/docs/rules/prefer-called-with.md +39 -0
  43. package/docs/rules/prefer-comparison-matcher.md +62 -0
  44. package/docs/rules/prefer-each.md +58 -0
  45. package/docs/rules/prefer-ending-with-an-expect.md +170 -0
  46. package/docs/rules/prefer-equality-matcher.md +36 -0
  47. package/docs/rules/prefer-expect-assertions.md +230 -0
  48. package/docs/rules/prefer-expect-resolves.md +62 -0
  49. package/docs/rules/prefer-hooks-in-order.md +137 -0
  50. package/docs/rules/prefer-hooks-on-top.md +124 -0
  51. package/docs/rules/prefer-importing-jest-globals.md +85 -0
  52. package/docs/rules/prefer-jest-mocked.md +40 -0
  53. package/docs/rules/prefer-lowercase-title.md +128 -0
  54. package/docs/rules/prefer-mock-promise-shorthand.md +41 -0
  55. package/docs/rules/prefer-mock-return-shorthand.md +50 -0
  56. package/docs/rules/prefer-snapshot-hint.md +192 -0
  57. package/docs/rules/prefer-spy-on.md +46 -0
  58. package/docs/rules/prefer-strict-equal.md +29 -0
  59. package/docs/rules/prefer-to-be.md +63 -0
  60. package/docs/rules/prefer-to-contain.md +53 -0
  61. package/docs/rules/prefer-to-have-been-called-times.md +43 -0
  62. package/docs/rules/prefer-to-have-been-called.md +35 -0
  63. package/docs/rules/prefer-to-have-length.md +41 -0
  64. package/docs/rules/prefer-todo.md +33 -0
  65. package/docs/rules/require-hook.md +187 -0
  66. package/docs/rules/require-to-throw-message.md +43 -0
  67. package/docs/rules/require-top-level-describe.md +86 -0
  68. package/docs/rules/unbound-method.md +61 -0
  69. package/docs/rules/valid-describe-callback.md +69 -0
  70. package/docs/rules/valid-expect-in-promise.md +79 -0
  71. package/docs/rules/valid-expect-with-promise.md +43 -0
  72. package/docs/rules/valid-expect.md +155 -0
  73. package/docs/rules/valid-mock-module-path.md +72 -0
  74. package/docs/rules/valid-title.md +319 -0
  75. package/index.d.ts +28 -0
  76. package/lib/globals.json +15 -0
  77. package/lib/index.js +85 -0
  78. package/lib/rules/consistent-test-it.js +101 -0
  79. package/lib/rules/expect-expect.js +102 -0
  80. package/lib/rules/max-expects.js +70 -0
  81. package/lib/rules/max-nested-describe.js +59 -0
  82. package/lib/rules/no-alias-methods.js +62 -0
  83. package/lib/rules/no-commented-out-tests.js +44 -0
  84. package/lib/rules/no-conditional-expect.js +80 -0
  85. package/lib/rules/no-conditional-in-test.js +63 -0
  86. package/lib/rules/no-confusing-set-timeout.js +61 -0
  87. package/lib/rules/no-deprecated-functions.js +81 -0
  88. package/lib/rules/no-disabled-tests.js +57 -0
  89. package/lib/rules/no-done-callback.js +120 -0
  90. package/lib/rules/no-duplicate-hooks.js +52 -0
  91. package/lib/rules/no-error-equal.js +41 -0
  92. package/lib/rules/no-export.js +61 -0
  93. package/lib/rules/no-focused-tests.js +63 -0
  94. package/lib/rules/no-hooks.js +51 -0
  95. package/lib/rules/no-identical-title.js +73 -0
  96. package/lib/rules/no-interpolation-in-snapshots.js +43 -0
  97. package/lib/rules/no-jasmine-globals.js +140 -0
  98. package/lib/rules/no-large-snapshots.js +100 -0
  99. package/lib/rules/no-mocks-import.js +46 -0
  100. package/lib/rules/no-restricted-jest-methods.js +53 -0
  101. package/lib/rules/no-restricted-matchers.js +60 -0
  102. package/lib/rules/no-standalone-expect.js +114 -0
  103. package/lib/rules/no-test-prefixes.js +48 -0
  104. package/lib/rules/no-test-return-statement.js +62 -0
  105. package/lib/rules/no-unnecessary-assertion.js +87 -0
  106. package/lib/rules/no-unneeded-async-expect-function.js +57 -0
  107. package/lib/rules/no-untyped-mock-factory.js +61 -0
  108. package/lib/rules/padding-around-after-all-blocks.js +17 -0
  109. package/lib/rules/padding-around-after-each-blocks.js +17 -0
  110. package/lib/rules/padding-around-all.js +15 -0
  111. package/lib/rules/padding-around-before-all-blocks.js +17 -0
  112. package/lib/rules/padding-around-before-each-blocks.js +17 -0
  113. package/lib/rules/padding-around-describe-blocks.js +17 -0
  114. package/lib/rules/padding-around-expect-groups.js +21 -0
  115. package/lib/rules/padding-around-test-blocks.js +17 -0
  116. package/lib/rules/prefer-called-with.js +47 -0
  117. package/lib/rules/prefer-comparison-matcher.js +111 -0
  118. package/lib/rules/prefer-each.js +77 -0
  119. package/lib/rules/prefer-ending-with-an-expect.js +102 -0
  120. package/lib/rules/prefer-equality-matcher.js +87 -0
  121. package/lib/rules/prefer-expect-assertions.js +237 -0
  122. package/lib/rules/prefer-expect-resolves.js +47 -0
  123. package/lib/rules/prefer-hooks-in-order.js +67 -0
  124. package/lib/rules/prefer-hooks-on-top.js +41 -0
  125. package/lib/rules/prefer-importing-jest-globals.js +126 -0
  126. package/lib/rules/prefer-jest-mocked.js +66 -0
  127. package/lib/rules/prefer-lowercase-title.js +128 -0
  128. package/lib/rules/prefer-mock-promise-shorthand.js +88 -0
  129. package/lib/rules/prefer-mock-return-shorthand.js +122 -0
  130. package/lib/rules/prefer-snapshot-hint.js +111 -0
  131. package/lib/rules/prefer-spy-on.js +80 -0
  132. package/lib/rules/prefer-strict-equal.js +46 -0
  133. package/lib/rules/prefer-to-be.js +98 -0
  134. package/lib/rules/prefer-to-contain.js +82 -0
  135. package/lib/rules/prefer-to-have-been-called-times.js +70 -0
  136. package/lib/rules/prefer-to-have-been-called.js +59 -0
  137. package/lib/rules/prefer-to-have-length.js +57 -0
  138. package/lib/rules/prefer-todo.js +72 -0
  139. package/lib/rules/require-hook.js +93 -0
  140. package/lib/rules/require-to-throw-message.js +45 -0
  141. package/lib/rules/require-top-level-describe.js +86 -0
  142. package/lib/rules/unbound-method.js +86 -0
  143. package/lib/rules/utils/accessors.js +127 -0
  144. package/lib/rules/utils/ast-utils.js +59 -0
  145. package/lib/rules/utils/detectJestVersion.js +24 -0
  146. package/lib/rules/utils/followTypeAssertionChain.js +10 -0
  147. package/lib/rules/utils/index.js +71 -0
  148. package/lib/rules/utils/misc.js +168 -0
  149. package/lib/rules/utils/padding.js +308 -0
  150. package/lib/rules/utils/parseJestFnCall.js +325 -0
  151. package/lib/rules/utils/ts.js +73 -0
  152. package/lib/rules/valid-describe-callback.js +94 -0
  153. package/lib/rules/valid-expect-in-promise.js +311 -0
  154. package/lib/rules/valid-expect-with-promise.js +54 -0
  155. package/lib/rules/valid-expect.js +302 -0
  156. package/lib/rules/valid-mock-module-path.js +90 -0
  157. package/lib/rules/valid-title.js +252 -0
  158. package/package.json +164 -0
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("@typescript-eslint/utils");
8
+ var _utils2 = require("./utils");
9
+ const canBe = (firstArgumentType, flag) => {
10
+ if (firstArgumentType.isUnion()) {
11
+ return firstArgumentType.types.some(typ => typ.flags & flag);
12
+ }
13
+ return firstArgumentType.flags & flag;
14
+ };
15
+ var _default = exports.default = (0, _utils2.createRule)({
16
+ name: __filename,
17
+ meta: {
18
+ docs: {
19
+ description: 'Disallow unnecessary assertions based on types',
20
+ requiresTypeChecking: true
21
+ },
22
+ messages: {
23
+ unnecessaryAssertion: 'Unnecessary assertion, subject cannot be {{ thing }}',
24
+ noStrictNullCheck: 'This rule requires the `strictNullChecks` compiler option to be turned on to function correctly.'
25
+ },
26
+ type: 'suggestion',
27
+ schema: []
28
+ },
29
+ defaultOptions: [],
30
+ create(context) {
31
+ const services = _utils.ESLintUtils.getParserServices(context);
32
+ const compilerOptions = services.program.getCompilerOptions();
33
+ const isStrictNullChecks = compilerOptions.strictNullChecks || compilerOptions.strict && compilerOptions.strictNullChecks !== false;
34
+ if (!isStrictNullChecks) {
35
+ context.report({
36
+ loc: {
37
+ start: {
38
+ column: 0,
39
+ line: 0
40
+ },
41
+ end: {
42
+ column: 0,
43
+ line: 0
44
+ }
45
+ },
46
+ messageId: 'noStrictNullCheck'
47
+ });
48
+ }
49
+
50
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
51
+ const {
52
+ TypeFlags
53
+ } = require('typescript');
54
+ return {
55
+ CallExpression(node) {
56
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
57
+ if (jestFnCall?.type !== 'expect' || jestFnCall.head.node.parent.type !== _utils.AST_NODE_TYPES.CallExpression) {
58
+ return;
59
+ }
60
+ const matcherName = (0, _utils2.getAccessorValue)(jestFnCall.matcher);
61
+ if (!['toBeNull', 'toBeDefined', 'toBeUndefined', 'toBeNaN'].includes(matcherName)) {
62
+ return;
63
+ }
64
+
65
+ // todo: we should support resolving promise types
66
+ if (jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) !== 'not')) {
67
+ return;
68
+ }
69
+ const [argument] = jestFnCall.head.node.parent.arguments;
70
+ let desiredType = TypeFlags.Any | TypeFlags.Unknown;
71
+
72
+ // add in the appropriate type flag based on the matcher being used
73
+ desiredType |= matcherName === 'toBeNaN' ? TypeFlags.NumberLike : matcherName === 'toBeNull' ? TypeFlags.Null : TypeFlags.Undefined;
74
+ if (canBe(services.getTypeAtLocation(argument), desiredType)) {
75
+ return;
76
+ }
77
+ context.report({
78
+ messageId: 'unnecessaryAssertion',
79
+ data: {
80
+ thing: matcherName === 'toBeNaN' ? 'a number' : matcherName === 'toBeNull' ? 'null' : 'undefined'
81
+ },
82
+ node
83
+ });
84
+ }
85
+ };
86
+ }
87
+ });
@@ -0,0 +1,57 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("@typescript-eslint/utils");
8
+ var _utils2 = require("./utils");
9
+ var _default = exports.default = (0, _utils2.createRule)({
10
+ name: __filename,
11
+ meta: {
12
+ docs: {
13
+ description: 'Disallow unnecessary async function wrapper for expected promises'
14
+ },
15
+ fixable: 'code',
16
+ messages: {
17
+ noAsyncWrapperForExpectedPromise: 'Unnecessary async function wrapper'
18
+ },
19
+ schema: [],
20
+ type: 'suggestion'
21
+ },
22
+ defaultOptions: [],
23
+ create(context) {
24
+ return {
25
+ CallExpression(node) {
26
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
27
+ if (jestFnCall?.type !== 'expect') {
28
+ return;
29
+ }
30
+ const {
31
+ parent
32
+ } = jestFnCall.head.node;
33
+ if (parent.type !== _utils.AST_NODE_TYPES.CallExpression) {
34
+ return;
35
+ }
36
+ const [awaitNode] = parent.arguments;
37
+ if (!awaitNode || !(0, _utils2.isFunction)(awaitNode) || !awaitNode.async || awaitNode.body.type !== _utils.AST_NODE_TYPES.BlockStatement || awaitNode.body.body.length !== 1) {
38
+ return;
39
+ }
40
+ const [callback] = awaitNode.body.body;
41
+ if (callback.type === _utils.AST_NODE_TYPES.ExpressionStatement && callback.expression.type === _utils.AST_NODE_TYPES.AwaitExpression && callback.expression.argument.type === _utils.AST_NODE_TYPES.CallExpression) {
42
+ const innerAsyncFuncCall = callback.expression.argument;
43
+ context.report({
44
+ node: awaitNode,
45
+ messageId: 'noAsyncWrapperForExpectedPromise',
46
+ fix(fixer) {
47
+ const {
48
+ sourceCode
49
+ } = context;
50
+ return [fixer.replaceTextRange([awaitNode.range[0], awaitNode.range[1]], sourceCode.getText(innerAsyncFuncCall))];
51
+ }
52
+ });
53
+ }
54
+ }
55
+ };
56
+ }
57
+ });
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("@typescript-eslint/utils");
8
+ var _utils2 = require("./utils");
9
+ var _default = exports.default = (0, _utils2.createRule)({
10
+ name: __filename,
11
+ meta: {
12
+ docs: {
13
+ description: 'Disallow using `jest.mock()` factories without an explicit type parameter'
14
+ },
15
+ messages: {
16
+ addTypeParameterToModuleMock: 'Add a type parameter to the mock factory such as `typeof import({{ moduleName }})`'
17
+ },
18
+ fixable: 'code',
19
+ schema: [],
20
+ type: 'suggestion'
21
+ },
22
+ defaultOptions: [],
23
+ create(context) {
24
+ return {
25
+ CallExpression(node) {
26
+ const {
27
+ callee,
28
+ typeArguments
29
+ } = node;
30
+ if (callee.type !== _utils.AST_NODE_TYPES.MemberExpression) {
31
+ return;
32
+ }
33
+ const {
34
+ property
35
+ } = callee;
36
+ if (node.arguments.length === 2 && (0, _utils2.isTypeOfJestFnCall)(node, context, ['jest']) && (0, _utils2.isSupportedAccessor)(property) && ['mock', 'doMock'].includes((0, _utils2.getAccessorValue)(property))) {
37
+ const [nameNode, factoryNode] = node.arguments;
38
+ const hasTypeParameter = typeArguments !== undefined && typeArguments.params.length > 0;
39
+ const hasReturnType = (0, _utils2.isFunction)(factoryNode) && factoryNode.returnType !== undefined;
40
+ if (hasTypeParameter || hasReturnType) {
41
+ return;
42
+ }
43
+ const moduleName = (0, _utils2.findModuleName)(nameNode);
44
+ context.report({
45
+ messageId: 'addTypeParameterToModuleMock',
46
+ data: {
47
+ moduleName: moduleName?.raw ?? './module-name'
48
+ },
49
+ node,
50
+ fix(fixer) {
51
+ if (!moduleName) {
52
+ return [];
53
+ }
54
+ return [fixer.insertTextAfter(callee, `<typeof import(${moduleName.raw})>`)];
55
+ }
56
+ });
57
+ }
58
+ }
59
+ };
60
+ }
61
+ });
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: _padding.StatementType.AfterAllToken
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: _padding.StatementType.AfterAllToken,
15
+ nextStatementType: _padding.StatementType.Any
16
+ }];
17
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `afterAll` blocks', config);
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: _padding.StatementType.AfterEachToken
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: _padding.StatementType.AfterEachToken,
15
+ nextStatementType: _padding.StatementType.Any
16
+ }];
17
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `afterEach` blocks', config);
@@ -0,0 +1,15 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _paddingAroundAfterAllBlocks = require("./padding-around-after-all-blocks");
8
+ var _paddingAroundAfterEachBlocks = require("./padding-around-after-each-blocks");
9
+ var _paddingAroundBeforeAllBlocks = require("./padding-around-before-all-blocks");
10
+ var _paddingAroundBeforeEachBlocks = require("./padding-around-before-each-blocks");
11
+ var _paddingAroundDescribeBlocks = require("./padding-around-describe-blocks");
12
+ var _paddingAroundExpectGroups = require("./padding-around-expect-groups");
13
+ var _paddingAroundTestBlocks = require("./padding-around-test-blocks");
14
+ var _padding = require("./utils/padding");
15
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around Jest functions', [..._paddingAroundAfterAllBlocks.config, ..._paddingAroundAfterEachBlocks.config, ..._paddingAroundBeforeAllBlocks.config, ..._paddingAroundBeforeEachBlocks.config, ..._paddingAroundDescribeBlocks.config, ..._paddingAroundExpectGroups.config, ..._paddingAroundTestBlocks.config]);
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: _padding.StatementType.BeforeAllToken
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: _padding.StatementType.BeforeAllToken,
15
+ nextStatementType: _padding.StatementType.Any
16
+ }];
17
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `beforeAll` blocks', config);
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: _padding.StatementType.BeforeEachToken
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: _padding.StatementType.BeforeEachToken,
15
+ nextStatementType: _padding.StatementType.Any
16
+ }];
17
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `beforeEach` blocks', config);
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: [_padding.StatementType.DescribeToken, _padding.StatementType.FdescribeToken, _padding.StatementType.XdescribeToken]
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: [_padding.StatementType.DescribeToken, _padding.StatementType.FdescribeToken, _padding.StatementType.XdescribeToken],
15
+ nextStatementType: _padding.StatementType.Any
16
+ }];
17
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `describe` blocks', config);
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: _padding.StatementType.ExpectToken
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: _padding.StatementType.ExpectToken,
15
+ nextStatementType: _padding.StatementType.Any
16
+ }, {
17
+ paddingType: _padding.PaddingType.Any,
18
+ prevStatementType: _padding.StatementType.ExpectToken,
19
+ nextStatementType: _padding.StatementType.ExpectToken
20
+ }];
21
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `expect` groups', config);
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = exports.config = void 0;
7
+ var _padding = require("./utils/padding");
8
+ const config = exports.config = [{
9
+ paddingType: _padding.PaddingType.Always,
10
+ prevStatementType: _padding.StatementType.Any,
11
+ nextStatementType: [_padding.StatementType.TestToken, _padding.StatementType.ItToken, _padding.StatementType.FitToken, _padding.StatementType.XitToken, _padding.StatementType.XtestToken]
12
+ }, {
13
+ paddingType: _padding.PaddingType.Always,
14
+ prevStatementType: [_padding.StatementType.TestToken, _padding.StatementType.ItToken, _padding.StatementType.FitToken, _padding.StatementType.XitToken, _padding.StatementType.XtestToken],
15
+ nextStatementType: _padding.StatementType.Any
16
+ }];
17
+ var _default = exports.default = (0, _padding.createPaddingRule)(__filename, 'Enforce padding around `test` and `it` blocks', config);
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("./utils");
8
+ var _default = exports.default = (0, _utils.createRule)({
9
+ name: __filename,
10
+ meta: {
11
+ docs: {
12
+ description: 'Suggest using `toHaveBeenCalledWith()`'
13
+ },
14
+ messages: {
15
+ preferCalledWith: 'Prefer {{ matcherName }}With(/* expected args */)'
16
+ },
17
+ type: 'suggestion',
18
+ schema: []
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ return {
23
+ CallExpression(node) {
24
+ const jestFnCall = (0, _utils.parseJestFnCall)(node, context);
25
+ if (jestFnCall?.type !== 'expect') {
26
+ return;
27
+ }
28
+ if (jestFnCall.modifiers.some(nod => (0, _utils.getAccessorValue)(nod) === 'not')) {
29
+ return;
30
+ }
31
+ const {
32
+ matcher
33
+ } = jestFnCall;
34
+ const matcherName = (0, _utils.getAccessorValue)(matcher);
35
+ if (['toBeCalled', 'toHaveBeenCalled'].includes(matcherName)) {
36
+ context.report({
37
+ data: {
38
+ matcherName
39
+ },
40
+ messageId: 'preferCalledWith',
41
+ node: matcher
42
+ });
43
+ }
44
+ }
45
+ };
46
+ }
47
+ });
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("@typescript-eslint/utils");
8
+ var _utils2 = require("./utils");
9
+ const isString = node => {
10
+ return (0, _utils2.isStringNode)(node) || node.type === _utils.AST_NODE_TYPES.TemplateLiteral;
11
+ };
12
+ const isComparingToString = expression => {
13
+ return isString(expression.left) || isString(expression.right);
14
+ };
15
+ const invertOperator = operator => {
16
+ switch (operator) {
17
+ case '>':
18
+ return '<=';
19
+ case '<':
20
+ return '>=';
21
+ case '>=':
22
+ return '<';
23
+ case '<=':
24
+ return '>';
25
+ }
26
+ return null;
27
+ };
28
+ const determineMatcher = (operator, negated) => {
29
+ const op = negated ? invertOperator(operator) : operator;
30
+ switch (op) {
31
+ case '>':
32
+ return 'toBeGreaterThan';
33
+ case '<':
34
+ return 'toBeLessThan';
35
+ case '>=':
36
+ return 'toBeGreaterThanOrEqual';
37
+ case '<=':
38
+ return 'toBeLessThanOrEqual';
39
+ }
40
+ return null;
41
+ };
42
+ var _default = exports.default = (0, _utils2.createRule)({
43
+ name: __filename,
44
+ meta: {
45
+ docs: {
46
+ description: 'Suggest using the built-in comparison matchers'
47
+ },
48
+ messages: {
49
+ useToBeComparison: 'Prefer using `{{ preferredMatcher }}` instead'
50
+ },
51
+ fixable: 'code',
52
+ type: 'suggestion',
53
+ schema: []
54
+ },
55
+ defaultOptions: [],
56
+ create(context) {
57
+ return {
58
+ CallExpression(node) {
59
+ const jestFnCall = (0, _utils2.parseJestFnCall)(node, context);
60
+ if (jestFnCall?.type !== 'expect' || jestFnCall.args.length === 0) {
61
+ return;
62
+ }
63
+ const {
64
+ parent: expect
65
+ } = jestFnCall.head.node;
66
+ if (expect.type !== _utils.AST_NODE_TYPES.CallExpression) {
67
+ return;
68
+ }
69
+ const {
70
+ arguments: [comparison],
71
+ range: [, expectCallEnd]
72
+ } = expect;
73
+ const {
74
+ matcher
75
+ } = jestFnCall;
76
+ const matcherArg = (0, _utils2.getFirstMatcherArg)(jestFnCall);
77
+ if (comparison.type !== _utils.AST_NODE_TYPES.BinaryExpression || isComparingToString(comparison) || !_utils2.EqualityMatcher.hasOwnProperty((0, _utils2.getAccessorValue)(matcher)) || !(0, _utils2.isBooleanLiteral)(matcherArg)) {
78
+ return;
79
+ }
80
+ const [modifier] = jestFnCall.modifiers;
81
+ const hasNot = jestFnCall.modifiers.some(nod => (0, _utils2.getAccessorValue)(nod) === 'not');
82
+ const preferredMatcher = determineMatcher(comparison.operator, matcherArg.value === hasNot);
83
+ if (!preferredMatcher) {
84
+ return;
85
+ }
86
+ context.report({
87
+ fix(fixer) {
88
+ const {
89
+ sourceCode
90
+ } = context;
91
+
92
+ // preserve the existing modifier if it's not a negation
93
+ const modifierText = modifier && (0, _utils2.getAccessorValue)(modifier) !== 'not' ? `.${(0, _utils2.getAccessorValue)(modifier)}` : '';
94
+ return [
95
+ // replace the comparison argument with the left-hand side of the comparison
96
+ fixer.replaceText(comparison, sourceCode.getText(comparison.left)),
97
+ // replace the current matcher & modifier with the preferred matcher
98
+ fixer.replaceTextRange([expectCallEnd, matcher.parent.range[1]], `${modifierText}.${preferredMatcher}`),
99
+ // replace the matcher argument with the right-hand side of the comparison
100
+ fixer.replaceText(matcherArg, sourceCode.getText(comparison.right))];
101
+ },
102
+ messageId: 'useToBeComparison',
103
+ data: {
104
+ preferredMatcher
105
+ },
106
+ node: matcher
107
+ });
108
+ }
109
+ };
110
+ }
111
+ });
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ var _utils = require("./utils");
8
+ var _default = exports.default = (0, _utils.createRule)({
9
+ name: __filename,
10
+ meta: {
11
+ docs: {
12
+ description: 'Prefer using `.each` rather than manual loops'
13
+ },
14
+ messages: {
15
+ preferEach: 'prefer using `{{ fn }}.each` rather than a manual loop'
16
+ },
17
+ type: 'suggestion',
18
+ schema: []
19
+ },
20
+ defaultOptions: [],
21
+ create(context) {
22
+ const jestFnCalls = [];
23
+ let inTestCaseCall = false;
24
+ const recommendFn = () => {
25
+ if (jestFnCalls.length === 1 && jestFnCalls[0] === 'test') {
26
+ return 'it';
27
+ }
28
+ return 'describe';
29
+ };
30
+ const enterForLoop = () => {
31
+ if (jestFnCalls.length === 0 || inTestCaseCall) {
32
+ return;
33
+ }
34
+ jestFnCalls.length = 0;
35
+ };
36
+ const exitForLoop = node => {
37
+ if (jestFnCalls.length === 0 || inTestCaseCall) {
38
+ return;
39
+ }
40
+ context.report({
41
+ node,
42
+ messageId: 'preferEach',
43
+ data: {
44
+ fn: recommendFn()
45
+ }
46
+ });
47
+ jestFnCalls.length = 0;
48
+ };
49
+ return {
50
+ ForStatement: enterForLoop,
51
+ 'ForStatement:exit': exitForLoop,
52
+ ForInStatement: enterForLoop,
53
+ 'ForInStatement:exit': exitForLoop,
54
+ ForOfStatement: enterForLoop,
55
+ 'ForOfStatement:exit': exitForLoop,
56
+ CallExpression(node) {
57
+ const {
58
+ type: jestFnCallType
59
+ } = (0, _utils.parseJestFnCall)(node, context) ?? {};
60
+ if (jestFnCallType === 'hook' || jestFnCallType === 'describe' || jestFnCallType === 'test') {
61
+ jestFnCalls.push(jestFnCallType);
62
+ }
63
+ if (jestFnCallType === 'test') {
64
+ inTestCaseCall = true;
65
+ }
66
+ },
67
+ 'CallExpression:exit'(node) {
68
+ const {
69
+ type: jestFnCallType
70
+ } = (0, _utils.parseJestFnCall)(node, context) ?? {};
71
+ if (jestFnCallType === 'test') {
72
+ inTestCaseCall = false;
73
+ }
74
+ }
75
+ };
76
+ }
77
+ });