1
- import { rule } from "../src/no-derived-state.js" ;
2
- import { MyRuleTester , js } from "./rule-tester.js" ;
3
-
4
- // Uses taken from the real world, as opposed to contrived examples
5
- // TODO: Refactor to use entire plugin?
6
- new MyRuleTester ( ) . run ( "real-world" , rule , {
7
- valid : [
8
- {
9
- name : "Managing a timer" ,
10
- code : js `
1
+ import { ESLint } from "eslint" ;
2
+ import plugin from "../src/index.js" ;
3
+ import { js } from "./rule-tester.js" ;
4
+ import assert from "assert" ;
5
+
6
+ // Sanity check that runs the recommended config
7
+ // on common + valid real-world code, as opposed to contrived test cases.
8
+ describe ( "recommended rules on real-world code" , ( ) => {
9
+ const eslint = new ESLint ( {
10
+ overrideConfigFile : true ,
11
+ overrideConfig : [ plugin . configs . recommended ] ,
12
+ } ) ;
13
+
14
+ describe ( "should not flag" , ( ) => {
15
+ [
16
+ {
17
+ name : "Managing a timer" ,
18
+ code : js `
11
19
function Timer() {
12
20
const [seconds, setSeconds] = useState(0);
13
21
@@ -24,11 +32,10 @@ new MyRuleTester().run("real-world", rule, {
24
32
return <div>{seconds}</div>;
25
33
}
26
34
` ,
27
- } ,
28
- {
29
- // https://github.com/NickvanDyke/eslint-plugin-react-you-might-not-need-an-effect/issues/11
30
- name : "Debouncing" ,
31
- code : js `
35
+ } ,
36
+ {
37
+ name : "Debouncing" ,
38
+ code : js `
32
39
function useDebouncedState(value, delay) {
33
40
const [state, setState] = useState(value);
34
41
const [debouncedState, setDebouncedState] = useState(value);
@@ -46,10 +53,10 @@ new MyRuleTester().run("real-world", rule, {
46
53
return [state, debouncedState, setState];
47
54
}
48
55
` ,
49
- } ,
50
- {
51
- name : "Listening for window events" ,
52
- code : js `
56
+ } ,
57
+ {
58
+ name : "Listening for window events" ,
59
+ code : js `
53
60
function WindowSize() {
54
61
const [size, setSize] = useState({ width: window.innerWidth, height: window.innerHeight });
55
62
@@ -68,12 +75,10 @@ new MyRuleTester().run("real-world", rule, {
68
75
return <div>{size.width} x {size.height}</div>;
69
76
}
70
77
` ,
71
- } ,
72
- {
73
- name : "Play/pausing DOM video" ,
74
- // Could technically play/pause the video in the `onClick` handler,
75
- // but the use of an effect to sync state is arguably more readable and a valid use.
76
- code : js `
78
+ } ,
79
+ {
80
+ name : "Play/pausing DOM video" ,
81
+ code : js `
77
82
function VideoPlayer() {
78
83
const [isPlaying, setIsPlaying] = useState(false);
79
84
const videoRef = useRef();
@@ -92,10 +97,10 @@ new MyRuleTester().run("real-world", rule, {
92
97
</div>
93
98
}
94
99
` ,
95
- } ,
96
- {
97
- name : "Saving to LocalStorage" ,
98
- code : js `
100
+ } ,
101
+ {
102
+ name : "Saving to LocalStorage" ,
103
+ code : js `
99
104
function Notes() {
100
105
const [notes, setNotes] = useState(() => {
101
106
const savedNotes = localStorage.getItem('notes');
@@ -113,10 +118,10 @@ new MyRuleTester().run("real-world", rule, {
113
118
/>
114
119
}
115
120
` ,
116
- } ,
117
- {
118
- name : "Logging/Analytics" ,
119
- code : js `
121
+ } ,
122
+ {
123
+ name : "Logging/Analytics" ,
124
+ code : js `
120
125
function Nav() {
121
126
const [page, setPage] = useState('home');
122
127
@@ -133,27 +138,23 @@ new MyRuleTester().run("real-world", rule, {
133
138
)
134
139
}
135
140
` ,
136
- } ,
137
- {
138
- // This might be a code smell, but people do it
139
- name : "JSON.stringifying in deps" ,
140
- code : js `
141
+ } ,
142
+ {
143
+ name : "JSON.stringifying in deps" ,
144
+ code : js `
141
145
function Feed() {
142
146
const [posts, setPosts] = useState([]);
143
147
const [scrollPosition, setScrollPosition] = useState(0);
144
148
145
149
useEffect(() => {
146
150
setScrollPosition(0);
147
- // We can't be sure JSON.stringify is pure, so we can't warn about this.
148
- // TODO: Technically we could check against known pure functions.
149
151
}, [JSON.stringify(posts)]);
150
152
}
151
153
` ,
152
- } ,
153
- {
154
- // Taken from https://github.com/linhnguyen-gt/react-native-phone-number-input/blob/b5e6dc652fa8a03609efb72607dc6866f5556ca3/src/countryPickerModal/CountryPicker.tsx
155
- name : "CountryPicker" ,
156
- code : js `
154
+ } ,
155
+ {
156
+ name : "CountryPicker" ,
157
+ code : js `
157
158
function CountryPicker({ withEmoji }) {
158
159
const { translation, getCountries } = useContext();
159
160
@@ -172,17 +173,13 @@ new MyRuleTester().run("real-world", rule, {
172
173
return () => {
173
174
cancel = true;
174
175
};
175
- },
176
- // Important to the test: Leads us to find useStates to check their initializers
177
- [translation, withEmoji]
178
- );
176
+ }, [translation, withEmoji]);
179
177
}
180
178
` ,
181
- } ,
182
- {
183
- // https://github.com/NickvanDyke/eslint-plugin-react-you-might-not-need-an-effect/issues/10
184
- name : "navigation.setOptions" ,
185
- code : js `
179
+ } ,
180
+ {
181
+ name : "navigation.setOptions" ,
182
+ code : js `
186
183
import { useNavigation } from '@react-navigation/native';
187
184
import { useState, useLayoutEffect } from 'react';
188
185
@@ -197,11 +194,10 @@ new MyRuleTester().run("real-world", rule, {
197
194
}, [navigation, route]);
198
195
}
199
196
` ,
200
- } ,
201
- {
202
- // https://github.com/NickvanDyke/eslint-plugin-react-you-might-not-need-an-effect/issues/9#issuecomment-2913950378
203
- name : "Keyboard state listener" ,
204
- code : js `
197
+ } ,
198
+ {
199
+ name : "Keyboard state listener" ,
200
+ code : js `
205
201
import { useEffect, useState } from 'react';
206
202
import keyboardReducer from './reducers';
207
203
@@ -232,6 +228,17 @@ new MyRuleTester().run("real-world", rule, {
232
228
233
229
useKeyboardStore.setKeyboardState = setKeyboardState;
234
230
` ,
235
- } ,
236
- ] ,
231
+ } ,
232
+ ] . forEach ( ( { name, code } ) => {
233
+ it ( name , async ( ) => {
234
+ const results = await eslint . lintText ( code ) ;
235
+ const messages = results [ 0 ] . messages ;
236
+ assert . strictEqual (
237
+ messages . length ,
238
+ 0 ,
239
+ `Expected no lint errors for: ${ name } , but got: ${ JSON . stringify ( messages ) } ` ,
240
+ ) ;
241
+ } ) ;
242
+ } ) ;
243
+ } ) ;
237
244
} ) ;
0 commit comments