Skip to content

Commit 362d7e6

Browse files
committed
feat: create prefer-each rule
1 parent 5508c95 commit 362d7e6

File tree

7 files changed

+474
-14
lines changed

7 files changed

+474
-14
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,7 @@ installations requiring long-term consistency.
226226
| [no-test-return-statement](docs/rules/no-test-return-statement.md) | Disallow explicitly returning from tests | | |
227227
| [prefer-called-with](docs/rules/prefer-called-with.md) | Suggest using `toBeCalledWith()` or `toHaveBeenCalledWith()` | | |
228228
| [prefer-comparison-matcher](docs/rules/prefer-comparison-matcher.md) | Suggest using the built-in comparison matchers | | ![fixable][] |
229+
| [prefer-each](docs/rules/prefer-each.md) | Prefer using `.each` rather than manual loops | | |
229230
| [prefer-equality-matcher](docs/rules/prefer-equality-matcher.md) | Suggest using the built-in equality matchers | | ![suggest][] |
230231
| [prefer-expect-assertions](docs/rules/prefer-expect-assertions.md) | Suggest using `expect.assertions()` OR `expect.hasAssertions()` | | ![suggest][] |
231232
| [prefer-expect-resolves](docs/rules/prefer-expect-resolves.md) | Prefer `await expect(...).resolves` over `expect(await ...)` syntax | | ![fixable][] |

docs/rules/prefer-each.md

+54
Original file line numberDiff line numberDiff line change
@@ -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+
```

src/__tests__/__snapshots__/rules.test.ts.snap

+13-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

33
exports[`rules should export configs that refer to actual rules 1`] = `
4-
Object {
5-
"all": Object {
6-
"env": Object {
4+
{
5+
"all": {
6+
"env": {
77
"jest/globals": true,
88
},
9-
"plugins": Array [
9+
"plugins": [
1010
"jest",
1111
],
12-
"rules": Object {
12+
"rules": {
1313
"jest/consistent-test-it": "error",
1414
"jest/expect-expect": "error",
1515
"jest/max-expects": "error",
@@ -37,6 +37,7 @@ Object {
3737
"jest/no-test-return-statement": "error",
3838
"jest/prefer-called-with": "error",
3939
"jest/prefer-comparison-matcher": "error",
40+
"jest/prefer-each": "error",
4041
"jest/prefer-equality-matcher": "error",
4142
"jest/prefer-expect-assertions": "error",
4243
"jest/prefer-expect-resolves": "error",
@@ -61,14 +62,14 @@ Object {
6162
"jest/valid-title": "error",
6263
},
6364
},
64-
"recommended": Object {
65-
"env": Object {
65+
"recommended": {
66+
"env": {
6667
"jest/globals": true,
6768
},
68-
"plugins": Array [
69+
"plugins": [
6970
"jest",
7071
],
71-
"rules": Object {
72+
"rules": {
7273
"jest/expect-expect": "warn",
7374
"jest/no-commented-out-tests": "warn",
7475
"jest/no-conditional-expect": "error",
@@ -90,11 +91,11 @@ Object {
9091
"jest/valid-title": "error",
9192
},
9293
},
93-
"style": Object {
94-
"plugins": Array [
94+
"style": {
95+
"plugins": [
9596
"jest",
9697
],
97-
"rules": Object {
98+
"rules": {
9899
"jest/no-alias-methods": "warn",
99100
"jest/prefer-to-be": "error",
100101
"jest/prefer-to-contain": "error",

src/__tests__/rules.test.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { existsSync } from 'fs';
22
import { resolve } from 'path';
33
import plugin from '../';
44

5-
const numberOfRules = 50;
5+
const numberOfRules = 51;
66
const ruleNames = Object.keys(plugin.rules);
77
const deprecatedRules = Object.entries(plugin.rules)
88
.filter(([, rule]) => rule.meta.deprecated)

0 commit comments

Comments
 (0)