eslint-plugin-jest 27.0.0-next.2 → 27.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -225,6 +225,7 @@ installations requiring long-term consistency.
225
225
  | [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow explicitly returning from tests | | |
226
226
  | [prefer-called-with](docs/rules/prefer-called-with.md) | Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` | | |
227
227
  | [prefer-comparison-matcher](docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | ![fixable][] |
228
+ | [prefer-each](docs/rules/prefer-each.md) | Prefer using `.each` rather than manual loops | | |
228
229
  | [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in equality matchers | | ![suggest][] |
229
230
  | [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | ![suggest][] |
230
231
  | [prefer-expect-resolves](docs/rules/prefer-expect-resolves.md) | Prefer `await expect(...).resolves` over `expect(await ...)` syntax | | ![fixable][] |
@@ -20,13 +20,12 @@ This rule can also autofix a number of these deprecations for you.
20
20
 
21
21
  ### `jest.resetModuleRegistry`
22
22
 
23
- This function was renamed to `resetModules` in Jest 15, and is scheduled for
24
- removal in Jest 27.
23
+ This function was renamed to `resetModules` in Jest 15 and removed in Jest 27.
25
24
 
26
25
  ### `jest.addMatchers`
27
26
 
28
- This function was replaced with `expect.extend` in Jest 17, and is scheduled for
29
- removal in Jest 27.
27
+ This function was replaced with `expect.extend` in Jest 17 and removed in
28
+ Jest 27.
30
29
 
31
30
  ### `require.requireActual` & `require.requireMock`
32
31
 
@@ -41,10 +40,10 @@ the release of Jest 26 saw them removed from the `require` function altogether.
41
40
 
42
41
  ### `jest.runTimersToTime`
43
42
 
44
- This function was renamed to `advanceTimersByTime` in Jest 22, and is scheduled
45
- for removal in Jest 27.
43
+ This function was renamed to `advanceTimersByTime` in Jest 22 and removed in
44
+ Jest 27.
46
45
 
47
46
  ### `jest.genMockFromModule`
48
47
 
49
48
  This function was renamed to `createMockFromModule` in Jest 26, and is scheduled
50
- for removal in a future version of Jest.
49
+ for removal in Jest 30.
@@ -0,0 +1,54 @@
1
+ # Prefer using `.each` rather than manual loops (`prefer-each`)
2
+
3
+ Reports where you might be able to use `.each` instead of native loops.
4
+
5
+ ## Rule details
6
+
7
+ This rule triggers a warning if you use test case functions like `describe`,
8
+ `test`, and `it`, in a native loop - generally you should be able to use `.each`
9
+ instead which gives better output and makes it easier to run specific cases.
10
+
11
+ Examples of **incorrect** code for this rule:
12
+
13
+ ```js
14
+ for (const number of getNumbers()) {
15
+ it('is greater than five', function () {
16
+ expect(number).toBeGreaterThan(5);
17
+ });
18
+ }
19
+
20
+ for (const [input, expected] of data) {
21
+ beforeEach(() => setupSomething(input));
22
+
23
+ test(`results in ${expected}`, () => {
24
+ expect(doSomething()).toBe(expected);
25
+ });
26
+ }
27
+ ```
28
+
29
+ Examples of **correct** code for this rule:
30
+
31
+ ```js
32
+ it.each(getNumbers())(
33
+ 'only returns numbers that are greater than seven',
34
+ number => {
35
+ expect(number).toBeGreaterThan(7);
36
+ },
37
+ );
38
+
39
+ describe.each(data)('when input is %s', ([input, expected]) => {
40
+ beforeEach(() => setupSomething(input));
41
+
42
+ test(`results in ${expected}`, () => {
43
+ expect(doSomething()).toBe(expected);
44
+ });
45
+ });
46
+
47
+ // we don't warn on loops _in_ test functions because those typically involve
48
+ // complex setup that is better done in the test function itself
49
+ it('returns numbers that are greater than five', () => {
50
+ for (const number of getNumbers()) {
51
+ expect(number).toBeGreaterThan(5);
52
+ }
53
+ });
54
+ ```
@@ -33,8 +33,7 @@ var _default = (0, _utils2.createRule)({
33
33
  docs: {
34
34
  category: 'Best Practices',
35
35
  description: 'Avoid using a callback in asynchronous tests and hooks',
36
- recommended: 'error',
37
- suggestion: true
36
+ recommended: 'error'
38
37
  },
39
38
  messages: {
40
39
  noDoneCallback: 'Return a Promise instead of relying on callback parameter',
@@ -15,8 +15,7 @@ var _default = (0, _utils2.createRule)({
15
15
  docs: {
16
16
  category: 'Best Practices',
17
17
  description: 'Disallow focused tests',
18
- recommended: 'error',
19
- suggestion: true
18
+ recommended: 'error'
20
19
  },
21
20
  messages: {
22
21
  focusedTest: 'Unexpected focused test.',
@@ -7,6 +7,14 @@ exports.default = void 0;
7
7
 
8
8
  var _utils = require("./utils");
9
9
 
10
+ const isChainRestricted = (chain, restriction) => {
11
+ if (_utils.ModifierName.hasOwnProperty(restriction) || restriction.endsWith('.not')) {
12
+ return chain.startsWith(restriction);
13
+ }
14
+
15
+ return chain === restriction;
16
+ };
17
+
10
18
  var _default = (0, _utils.createRule)({
11
19
  name: __filename,
12
20
  meta: {
@@ -41,7 +49,7 @@ var _default = (0, _utils.createRule)({
41
49
  const chain = jestFnCall.members.map(nod => (0, _utils.getAccessorValue)(nod)).join('.');
42
50
 
43
51
  for (const [restriction, message] of Object.entries(restrictedChains)) {
44
- if (chain.startsWith(restriction)) {
52
+ if (isChainRestricted(chain, restriction)) {
45
53
  context.report({
46
54
  messageId: message ? 'restrictedChainWithMessage' : 'restrictedChain',
47
55
  data: {
@@ -0,0 +1,98 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _utils = require("./utils");
9
+
10
+ var _default = (0, _utils.createRule)({
11
+ name: __filename,
12
+ meta: {
13
+ docs: {
14
+ category: 'Best Practices',
15
+ description: 'Prefer using `.each` rather than manual loops',
16
+ recommended: false
17
+ },
18
+ messages: {
19
+ preferEach: 'prefer using `{{ fn }}.each` rather than a manual loop'
20
+ },
21
+ type: 'suggestion',
22
+ schema: []
23
+ },
24
+ defaultOptions: [],
25
+
26
+ create(context) {
27
+ const jestFnCalls = [];
28
+ let inTestCaseCall = false;
29
+
30
+ const recommendFn = () => {
31
+ if (jestFnCalls.length === 1 && jestFnCalls[0] === 'test') {
32
+ return 'it';
33
+ }
34
+
35
+ return 'describe';
36
+ };
37
+
38
+ const enterForLoop = () => {
39
+ if (jestFnCalls.length === 0 || inTestCaseCall) {
40
+ return;
41
+ }
42
+
43
+ jestFnCalls.length = 0;
44
+ };
45
+
46
+ const exitForLoop = node => {
47
+ if (jestFnCalls.length === 0 || inTestCaseCall) {
48
+ return;
49
+ }
50
+
51
+ context.report({
52
+ node,
53
+ messageId: 'preferEach',
54
+ data: {
55
+ fn: recommendFn()
56
+ }
57
+ });
58
+ jestFnCalls.length = 0;
59
+ };
60
+
61
+ return {
62
+ ForStatement: enterForLoop,
63
+ 'ForStatement:exit': exitForLoop,
64
+ ForInStatement: enterForLoop,
65
+ 'ForInStatement:exit': exitForLoop,
66
+ ForOfStatement: enterForLoop,
67
+ 'ForOfStatement:exit': exitForLoop,
68
+
69
+ CallExpression(node) {
70
+ const {
71
+ type: jestFnCallType
72
+ } = (0, _utils.parseJestFnCall)(node, context) ?? {};
73
+
74
+ if (jestFnCallType === 'hook' || jestFnCallType === 'describe' || jestFnCallType === 'test') {
75
+ jestFnCalls.push(jestFnCallType);
76
+ }
77
+
78
+ if (jestFnCallType === 'test') {
79
+ inTestCaseCall = true;
80
+ }
81
+ },
82
+
83
+ 'CallExpression:exit'(node) {
84
+ const {
85
+ type: jestFnCallType
86
+ } = (0, _utils.parseJestFnCall)(node, context) ?? {};
87
+
88
+ if (jestFnCallType === 'test') {
89
+ inTestCaseCall = false;
90
+ }
91
+ }
92
+
93
+ };
94
+ }
95
+
96
+ });
97
+
98
+ exports.default = _default;
@@ -15,8 +15,7 @@ var _default = (0, _utils2.createRule)({
15
15
  docs: {
16
16
  category: 'Best Practices',
17
17
  description: 'Suggest using the built-in equality matchers',
18
- recommended: false,
19
- suggestion: true
18
+ recommended: false
20
19
  },
21
20
  messages: {
22
21
  useEqualityMatcher: 'Prefer using one of the equality matchers instead',
@@ -13,10 +13,16 @@ const isFirstStatement = node => {
13
13
  let parent = node;
14
14
 
15
15
  while (parent) {
16
- var _parent$parent;
16
+ var _parent$parent, _parent$parent2;
17
17
 
18
18
  if (((_parent$parent = parent.parent) === null || _parent$parent === void 0 ? void 0 : _parent$parent.type) === _utils.AST_NODE_TYPES.BlockStatement) {
19
19
  return parent.parent.body[0] === parent;
20
+ } // if we've hit an arrow function, then it must have a single expression
21
+ // as its body, as otherwise we would have hit the block statement already
22
+
23
+
24
+ if (((_parent$parent2 = parent.parent) === null || _parent$parent2 === void 0 ? void 0 : _parent$parent2.type) === _utils.AST_NODE_TYPES.ArrowFunctionExpression) {
25
+ return true;
20
26
  }
21
27
 
22
28
  parent = parent.parent;
@@ -32,18 +38,13 @@ const suggestRemovingExtraArguments = (args, extraArgsStartAt) => ({
32
38
  fix: fixer => fixer.removeRange([args[extraArgsStartAt].range[0] - Math.sign(extraArgsStartAt), args[args.length - 1].range[1]])
33
39
  });
34
40
 
35
- // const suggestions: Array<[MessageIds, string]> = [
36
- // ['suggestAddingHasAssertions', 'expect.hasAssertions();'],
37
- // ['suggestAddingAssertions', 'expect.assertions();'],
38
- // ];
39
41
  var _default = (0, _utils2.createRule)({
40
42
  name: __filename,
41
43
  meta: {
42
44
  docs: {
43
45
  category: 'Best Practices',
44
46
  description: 'Suggest using `expect.assertions()` OR `expect.hasAssertions()`',
45
- recommended: false,
46
- suggestion: true
47
+ recommended: false
47
48
  },
48
49
  messages: {
49
50
  hasAssertionsTakesNoArguments: '`expect.hasAssertions` expects no arguments',
@@ -13,8 +13,7 @@ var _default = (0, _utils.createRule)({
13
13
  docs: {
14
14
  category: 'Best Practices',
15
15
  description: 'Suggest using `toStrictEqual()`',
16
- recommended: false,
17
- suggestion: true
16
+ recommended: false
18
17
  },
19
18
  messages: {
20
19
  useToStrictEqual: 'Use `toStrictEqual()` instead',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-jest",
3
- "version": "27.0.0-next.2",
3
+ "version": "27.0.2",
4
4
  "description": "ESLint rules for Jest",
5
5
  "keywords": [
6
6
  "eslint",
@@ -109,7 +109,7 @@
109
109
  "@semantic-release/changelog": "^6.0.0",
110
110
  "@semantic-release/git": "^10.0.0",
111
111
  "@types/dedent": "^0.7.0",
112
- "@types/jest": "^28.0.0",
112
+ "@types/jest": "^29.0.0",
113
113
  "@types/node": "^14.18.26",
114
114
  "@types/prettier": "^2.0.0",
115
115
  "@typescript-eslint/eslint-plugin": "^5.0.0",
@@ -151,7 +151,7 @@
151
151
  "optional": true
152
152
  }
153
153
  },
154
- "packageManager": "yarn@3.2.2",
154
+ "packageManager": "yarn@3.2.3",
155
155
  "engines": {
156
156
  "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
157
157
  }