Skip to content

Commit acbf08b

Browse files
committed
Add tests for weakMapMemoize and resultEqualityCheck integration
- Added runtime unit tests to verify that: - `resultEqualityCheck` works correctly when set to `shallowEqual`. - `resultEqualityCheck` is not called on the first output selector call. - `weakMapMemoize` with `resultEqualityCheck` set to `referenceEqualityCheck` works the same as `weakMapMemoize` without `resultEqualityCheck`.
1 parent 4228bc1 commit acbf08b

File tree

1 file changed

+140
-2
lines changed

1 file changed

+140
-2
lines changed

test/weakmapMemoize.spec.ts

Lines changed: 140 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
1-
import { createSelector, createSelectorCreator, weakMapMemoize } from 'reselect'
2-
import { setEnvToProd } from './testUtils'
1+
import { shallowEqual } from 'react-redux'
2+
import {
3+
createSelector,
4+
createSelectorCreator,
5+
referenceEqualityCheck,
6+
weakMapMemoize
7+
} from 'reselect'
8+
import type { RootState } from './testUtils'
9+
import { localTest, setEnvToProd, toggleCompleted } from './testUtils'
310

411
// Construct 1E6 states for perf test outside of the perf test so as to not change the execute time of the test function
512
const numOfStates = 1_000_000
@@ -224,3 +231,134 @@ describe.skipIf(isCoverage)('weakmapMemoize performance tests', () => {
224231
expect(totalTime).toBeLessThan(2000)
225232
})
226233
})
234+
235+
describe('weakMapMemoize integration with resultEqualityCheck', () => {
236+
const createAppSelector = createSelector.withTypes<RootState>()
237+
238+
const resultEqualityCheck = vi
239+
.fn(shallowEqual)
240+
.mockName('resultEqualityCheck')
241+
242+
afterEach(() => {
243+
resultEqualityCheck.mockClear()
244+
})
245+
246+
localTest(
247+
'resultEqualityCheck works correctly when set to shallowEqual',
248+
({ store }) => {
249+
const selectTodoIds = weakMapMemoize(
250+
(state: RootState) => state.todos.map(({ id }) => id),
251+
{ resultEqualityCheck }
252+
)
253+
254+
const firstResult = selectTodoIds(store.getState())
255+
256+
store.dispatch(toggleCompleted(0))
257+
258+
const secondResult = selectTodoIds(store.getState())
259+
260+
expect(firstResult).toBe(secondResult)
261+
262+
expect(selectTodoIds.resultsCount()).toBe(1)
263+
}
264+
)
265+
266+
localTest(
267+
'resultEqualityCheck is not called on the first output selector call',
268+
({ store }) => {
269+
const selectTodoIds = createAppSelector(
270+
[state => state.todos],
271+
todos => todos.map(({ id }) => id),
272+
{
273+
memoizeOptions: { resultEqualityCheck },
274+
devModeChecks: { inputStabilityCheck: 'once' }
275+
}
276+
)
277+
278+
expect(selectTodoIds(store.getState())).to.be.an('array').that.is.not
279+
.empty
280+
281+
expect(resultEqualityCheck).not.toHaveBeenCalled()
282+
283+
store.dispatch(toggleCompleted(0))
284+
285+
expect(selectTodoIds.lastResult()).toBe(selectTodoIds(store.getState()))
286+
287+
expect(resultEqualityCheck).toHaveBeenCalledOnce()
288+
289+
expect(selectTodoIds.memoizedResultFunc.resultsCount()).toBe(1)
290+
291+
expect(selectTodoIds.recomputations()).toBe(2)
292+
293+
expect(selectTodoIds.resultsCount()).toBe(2)
294+
295+
expect(selectTodoIds.dependencyRecomputations()).toBe(2)
296+
297+
store.dispatch(toggleCompleted(0))
298+
299+
expect(selectTodoIds.lastResult()).toBe(selectTodoIds(store.getState()))
300+
301+
expect(resultEqualityCheck).toHaveBeenCalledTimes(2)
302+
303+
expect(selectTodoIds.memoizedResultFunc.resultsCount()).toBe(1)
304+
305+
expect(selectTodoIds.recomputations()).toBe(3)
306+
307+
expect(selectTodoIds.resultsCount()).toBe(3)
308+
309+
expect(selectTodoIds.dependencyRecomputations()).toBe(3)
310+
}
311+
)
312+
313+
localTest(
314+
'weakMapMemoize with resultEqualityCheck set to referenceEqualityCheck works the same as weakMapMemoize without resultEqualityCheck',
315+
({ store }) => {
316+
const resultEqualityCheck = vi
317+
.fn(referenceEqualityCheck)
318+
.mockName('resultEqualityCheck')
319+
320+
const selectTodoIdsWithResultEqualityCheck = weakMapMemoize(
321+
(state: RootState) => state.todos.map(({ id }) => id),
322+
{ resultEqualityCheck }
323+
)
324+
325+
const firstResultWithResultEqualityCheck =
326+
selectTodoIdsWithResultEqualityCheck(store.getState())
327+
328+
expect(resultEqualityCheck).not.toHaveBeenCalled()
329+
330+
store.dispatch(toggleCompleted(0))
331+
332+
const secondResultWithResultEqualityCheck =
333+
selectTodoIdsWithResultEqualityCheck(store.getState())
334+
335+
expect(firstResultWithResultEqualityCheck).not.toBe(
336+
secondResultWithResultEqualityCheck
337+
)
338+
339+
expect(firstResultWithResultEqualityCheck).toStrictEqual(
340+
secondResultWithResultEqualityCheck
341+
)
342+
343+
expect(selectTodoIdsWithResultEqualityCheck.resultsCount()).toBe(2)
344+
345+
const selectTodoIds = weakMapMemoize((state: RootState) =>
346+
state.todos.map(({ id }) => id)
347+
)
348+
349+
const firstResult = selectTodoIds(store.getState())
350+
351+
store.dispatch(toggleCompleted(0))
352+
353+
const secondResult = selectTodoIds(store.getState())
354+
355+
expect(firstResult).not.toBe(secondResult)
356+
357+
expect(firstResult).toStrictEqual(secondResult)
358+
359+
expect(selectTodoIds.resultsCount()).toBe(2)
360+
361+
resultEqualityCheck.mockClear()
362+
}
363+
)
364+
})

0 commit comments

Comments
 (0)