Skip to content

Commit a15de48

Browse files
committed
Add tests for inputStabilityCheck and resultEqualityCheck dynamics
1 parent 5a2d74b commit a15de48

File tree

1 file changed

+110
-1
lines changed

1 file changed

+110
-1
lines changed

test/inputStabilityCheck.spec.ts

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
import { shallowEqual } from 'react-redux'
2-
import { createSelector, lruMemoize, setGlobalDevModeChecks } from 'reselect'
2+
import {
3+
createSelector,
4+
lruMemoize,
5+
referenceEqualityCheck,
6+
setGlobalDevModeChecks
7+
} from 'reselect'
8+
import type { RootState } from './testUtils'
9+
import { localTest } from './testUtils'
310

411
describe('inputStabilityCheck', () => {
512
const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {})
@@ -164,3 +171,105 @@ describe('inputStabilityCheck', () => {
164171
expect(consoleSpy).not.toHaveBeenCalled()
165172
})
166173
})
174+
175+
describe('the effects of inputStabilityCheck with resultEqualityCheck', () => {
176+
const createAppSelector = createSelector.withTypes<RootState>()
177+
178+
const resultEqualityCheck = vi
179+
.fn(referenceEqualityCheck)
180+
.mockName('resultEqualityCheck')
181+
182+
afterEach(() => {
183+
resultEqualityCheck.mockClear()
184+
})
185+
186+
localTest(
187+
'resultEqualityCheck should not be called with empty objects when inputStabilityCheck is set to once and input selectors are stable',
188+
({ store }) => {
189+
const selectTodoIds = createAppSelector(
190+
[state => state.todos],
191+
todos => todos.map(({ id }) => id),
192+
{
193+
memoizeOptions: { resultEqualityCheck },
194+
devModeChecks: { inputStabilityCheck: 'once' }
195+
}
196+
)
197+
198+
const firstResult = selectTodoIds(store.getState())
199+
200+
expect(resultEqualityCheck).not.toHaveBeenCalled()
201+
202+
const secondResult = selectTodoIds(store.getState())
203+
204+
expect(firstResult).toBe(secondResult)
205+
206+
expect(resultEqualityCheck).not.toHaveBeenCalled()
207+
208+
const thirdResult = selectTodoIds(store.getState())
209+
210+
expect(secondResult).toBe(thirdResult)
211+
212+
expect(resultEqualityCheck).not.toHaveBeenCalled()
213+
}
214+
)
215+
216+
localTest(
217+
'resultEqualityCheck should not be called with empty objects when inputStabilityCheck is set to always and input selectors are stable',
218+
({ store }) => {
219+
const selectTodoIds = createAppSelector(
220+
[state => state.todos],
221+
todos => todos.map(({ id }) => id),
222+
{
223+
memoizeOptions: { resultEqualityCheck },
224+
devModeChecks: { inputStabilityCheck: 'always' }
225+
}
226+
)
227+
228+
const firstResult = selectTodoIds(store.getState())
229+
230+
expect(resultEqualityCheck).not.toHaveBeenCalled()
231+
232+
const secondResult = selectTodoIds(store.getState())
233+
234+
expect(firstResult).toBe(secondResult)
235+
236+
expect(resultEqualityCheck).not.toHaveBeenCalled()
237+
238+
const thirdResult = selectTodoIds(store.getState())
239+
240+
expect(secondResult).toBe(thirdResult)
241+
242+
expect(resultEqualityCheck).not.toHaveBeenCalled()
243+
}
244+
)
245+
246+
localTest(
247+
'resultEqualityCheck should not be called with empty objects when inputStabilityCheck is set to never and input selectors are unstable',
248+
({ store }) => {
249+
const selectTodoIds = createAppSelector(
250+
[state => [...state.todos]],
251+
todos => todos.map(({ id }) => id),
252+
{
253+
memoizeOptions: { resultEqualityCheck },
254+
devModeChecks: { inputStabilityCheck: 'never' }
255+
}
256+
)
257+
258+
const firstResult = selectTodoIds(store.getState())
259+
260+
expect(resultEqualityCheck).not.toHaveBeenCalled()
261+
262+
const secondResult = selectTodoIds(store.getState())
263+
264+
expect(firstResult).toBe(secondResult)
265+
266+
expect(resultEqualityCheck).not.toHaveBeenCalled()
267+
268+
const thirdResult = selectTodoIds(store.getState())
269+
270+
expect(secondResult).toBe(thirdResult)
271+
272+
expect(resultEqualityCheck).not.toHaveBeenCalled()
273+
}
274+
)
275+
})

0 commit comments

Comments
 (0)