Skip to content

Commit f9e7ae2

Browse files
authored
fix(prefer-hooks-on-top): improve message & docs (#999)
* test(prefer-hooks-on-top): add case for expressions before hooks * test(prefer-hooks-on-top): make cases a bit more readable * fix(prefer-hooks-on-top): improve working of lint message * docs(prefer-hooks-on-top): improve code example * docs(prefer-hooks-on-top): improve rule description
1 parent 5bea38f commit f9e7ae2

File tree

3 files changed

+108
-60
lines changed

3 files changed

+108
-60
lines changed

docs/rules/prefer-hooks-on-top.md

+72-48
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
# Suggest having hooks before any test cases (`prefer-hooks-on-top`)
22

3-
All hooks should be defined before the start of the tests
3+
While hooks can be setup anywhere in a test file, they are always called in a
4+
specific order which means it can be confusing if they're intermixed with test
5+
cases.
6+
7+
This rule helps to ensure that hooks are always defined before test cases.
48

59
## Rule Details
610

@@ -11,47 +15,51 @@ Examples of **incorrect** code for this rule
1115

1216
describe('foo', () => {
1317
beforeEach(() => {
14-
//some hook code
15-
});
16-
test('bar', () => {
17-
some_fn();
18+
seedMyDatabase();
1819
});
19-
beforeAll(() => {
20-
//some hook code
21-
});
22-
test('bar', () => {
23-
some_fn();
20+
21+
it('accepts this input', () => {
22+
// ...
2423
});
25-
});
2624

27-
// Nested describe scenario
28-
describe('foo', () => {
2925
beforeAll(() => {
30-
//some hook code
26+
createMyDatabase();
3127
});
32-
test('bar', () => {
33-
some_fn();
28+
29+
it('returns that value', () => {
30+
// ...
3431
});
35-
describe('inner_foo', () => {
32+
33+
describe('when the database has specific values', () => {
34+
const specificValue = '...';
35+
3636
beforeEach(() => {
37-
//some hook code
37+
seedMyDatabase(specificValue);
3838
});
39-
test('inner bar', () => {
40-
some_fn();
39+
40+
it('accepts that input', () => {
41+
// ...
4142
});
42-
test('inner bar', () => {
43-
some_fn();
43+
44+
it('throws an error', () => {
45+
// ...
4446
});
45-
beforeAll(() => {
46-
//some hook code
47+
48+
afterEach(() => {
49+
clearLogger();
4750
});
48-
afterAll(() => {
49-
//some hook code
51+
beforeEach(() => {
52+
mockLogger();
5053
});
51-
test('inner bar', () => {
52-
some_fn();
54+
55+
it('logs a message', () => {
56+
// ...
5357
});
5458
});
59+
60+
afterAll(() => {
61+
removeMyDatabase();
62+
});
5563
});
5664
```
5765

@@ -61,35 +69,51 @@ Examples of **correct** code for this rule
6169
/* eslint jest/prefer-hooks-on-top: "error" */
6270

6371
describe('foo', () => {
64-
beforeEach(() => {
65-
//some hook code
72+
beforeAll(() => {
73+
createMyDatabase();
6674
});
6775

68-
// Not affected by rule
69-
someSetup();
70-
71-
afterEach(() => {
72-
//some hook code
76+
beforeEach(() => {
77+
seedMyDatabase();
7378
});
74-
test('bar', () => {
75-
some_fn();
79+
80+
afterAll(() => {
81+
clearMyDatabase();
7682
});
77-
});
7883

79-
// Nested describe scenario
80-
describe('foo', () => {
81-
beforeEach(() => {
82-
//some hook code
84+
it('accepts this input', () => {
85+
// ...
8386
});
84-
test('bar', () => {
85-
some_fn();
87+
88+
it('returns that value', () => {
89+
// ...
8690
});
87-
describe('inner_foo', () => {
91+
92+
describe('when the database has specific values', () => {
93+
const specificValue = '...';
94+
8895
beforeEach(() => {
89-
//some hook code
96+
seedMyDatabase(specificValue);
9097
});
91-
test('inner bar', () => {
92-
some_fn();
98+
99+
beforeEach(() => {
100+
mockLogger();
101+
});
102+
103+
afterEach(() => {
104+
clearLogger();
105+
});
106+
107+
it('accepts that input', () => {
108+
// ...
109+
});
110+
111+
it('throws an error', () => {
112+
// ...
113+
});
114+
115+
it('logs a message', () => {
116+
// ...
93117
});
94118
});
95119
});

src/rules/__tests__/prefer-hooks-on-top.test.ts

+35-11
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,18 @@ ruleTester.run('basic describe block', rule, {
1717
beforeEach(() => {});
1818
someSetupFn();
1919
afterEach(() => {});
20+
21+
test('bar', () => {
22+
someFn();
23+
});
24+
});
25+
`,
26+
dedent`
27+
describe('foo', () => {
28+
someSetupFn();
29+
beforeEach(() => {});
30+
afterEach(() => {});
31+
2032
test('bar', () => {
2133
someFn();
2234
});
@@ -31,6 +43,7 @@ ruleTester.run('basic describe block', rule, {
3143
test('bar', () => {
3244
someFn();
3345
});
46+
3447
beforeAll(() => {});
3548
test('bar', () => {
3649
someFn();
@@ -41,7 +54,7 @@ ruleTester.run('basic describe block', rule, {
4154
{
4255
messageId: 'noHookOnTop',
4356
column: 3,
44-
line: 6,
57+
line: 7,
4558
},
4659
],
4760
},
@@ -52,6 +65,7 @@ ruleTester.run('basic describe block', rule, {
5265
test.each\`\`('bar', () => {
5366
someFn();
5467
});
68+
5569
beforeAll(() => {});
5670
test.only('bar', () => {
5771
someFn();
@@ -62,7 +76,7 @@ ruleTester.run('basic describe block', rule, {
6276
{
6377
messageId: 'noHookOnTop',
6478
column: 3,
65-
line: 6,
79+
line: 7,
6680
},
6781
],
6882
},
@@ -73,6 +87,7 @@ ruleTester.run('basic describe block', rule, {
7387
test.only.each\`\`('bar', () => {
7488
someFn();
7589
});
90+
7691
beforeAll(() => {});
7792
test.only('bar', () => {
7893
someFn();
@@ -83,7 +98,7 @@ ruleTester.run('basic describe block', rule, {
8398
{
8499
messageId: 'noHookOnTop',
85100
column: 3,
86-
line: 6,
101+
line: 7,
87102
},
88103
],
89104
},
@@ -96,19 +111,21 @@ ruleTester.run('multiple describe blocks', rule, {
96111
describe.skip('foo', () => {
97112
beforeEach(() => {});
98113
beforeAll(() => {});
114+
99115
test('bar', () => {
100116
someFn();
101117
});
102118
});
119+
103120
describe('foo', () => {
104121
beforeEach(() => {});
122+
105123
test('bar', () => {
106124
someFn();
107125
});
108126
});
109127
`,
110128
],
111-
112129
invalid: [
113130
{
114131
code: dedent`
@@ -117,6 +134,7 @@ ruleTester.run('multiple describe blocks', rule, {
117134
test('bar', () => {
118135
someFn();
119136
});
137+
120138
beforeAll(() => {});
121139
test('bar', () => {
122140
someFn();
@@ -126,14 +144,17 @@ ruleTester.run('multiple describe blocks', rule, {
126144
beforeEach(() => {});
127145
beforeEach(() => {});
128146
beforeAll(() => {});
147+
129148
test('bar', () => {
130149
someFn();
131150
});
132151
});
152+
133153
describe('foo', () => {
134154
test('bar', () => {
135155
someFn();
136156
});
157+
137158
beforeEach(() => {});
138159
beforeEach(() => {});
139160
beforeAll(() => {});
@@ -143,22 +164,22 @@ ruleTester.run('multiple describe blocks', rule, {
143164
{
144165
messageId: 'noHookOnTop',
145166
column: 3,
146-
line: 6,
167+
line: 7,
147168
},
148169
{
149170
messageId: 'noHookOnTop',
150171
column: 3,
151-
line: 23,
172+
line: 27,
152173
},
153174
{
154175
messageId: 'noHookOnTop',
155176
column: 3,
156-
line: 24,
177+
line: 28,
157178
},
158179
{
159180
messageId: 'noHookOnTop',
160181
column: 3,
161-
line: 25,
182+
line: 29,
162183
},
163184
],
164185
},
@@ -173,6 +194,7 @@ ruleTester.run('nested describe blocks', rule, {
173194
test('bar', () => {
174195
someFn();
175196
});
197+
176198
describe('inner_foo', () => {
177199
beforeEach(() => {});
178200
test('inner bar', () => {
@@ -182,7 +204,6 @@ ruleTester.run('nested describe blocks', rule, {
182204
});
183205
`,
184206
],
185-
186207
invalid: [
187208
{
188209
code: dedent`
@@ -191,14 +212,17 @@ ruleTester.run('nested describe blocks', rule, {
191212
test('bar', () => {
192213
someFn();
193214
});
215+
194216
describe('inner_foo', () => {
195217
beforeEach(() => {});
196218
test('inner bar', () => {
197219
someFn();
198220
});
221+
199222
test('inner bar', () => {
200223
someFn();
201224
});
225+
202226
beforeAll(() => {});
203227
afterAll(() => {});
204228
test('inner bar', () => {
@@ -211,12 +235,12 @@ ruleTester.run('nested describe blocks', rule, {
211235
{
212236
messageId: 'noHookOnTop',
213237
column: 5,
214-
line: 14,
238+
line: 17,
215239
},
216240
{
217241
messageId: 'noHookOnTop',
218242
column: 5,
219-
line: 15,
243+
line: 18,
220244
},
221245
],
222246
},

src/rules/prefer-hooks-on-top.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export default createRule({
99
recommended: false,
1010
},
1111
messages: {
12-
noHookOnTop: 'Move all hooks before test cases',
12+
noHookOnTop: 'Hooks should come before test cases',
1313
},
1414
schema: [],
1515
type: 'suggestion',

0 commit comments

Comments
 (0)