Skip to content

Commit c46f8bf

Browse files
committed
Add tests for lruMemoize 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. - `lruMemoize` with `resultEqualityCheck` set to `referenceEqualityCheck` works the same as `lruMemoize` without `resultEqualityCheck`.
1 parent acbf08b commit c46f8bf

File tree

1 file changed

+144
-7
lines changed

1 file changed

+144
-7
lines changed

test/lruMemoize.test.ts

Lines changed: 144 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
11
// TODO: Add test for React Redux connect function
22

3-
import { createSelectorCreator, lruMemoize } from 'reselect'
4-
import { vi } from 'vitest'
5-
6-
const createSelector = createSelectorCreator({
3+
import { shallowEqual } from 'react-redux'
4+
import {
5+
createSelectorCreator,
6+
lruMemoize,
7+
referenceEqualityCheck
8+
} from 'reselect'
9+
import type { RootState } from './testUtils'
10+
import { localTest, toggleCompleted } from './testUtils'
11+
12+
const createSelectorLru = createSelectorCreator({
713
memoize: lruMemoize,
814
argsMemoize: lruMemoize
915
})
@@ -268,7 +274,7 @@ describe(lruMemoize, () => {
268274

269275
const fooChangeSpy = vi.fn()
270276

271-
const fooChangeHandler = createSelector(
277+
const fooChangeHandler = createSelectorLru(
272278
(state: any) => state.foo,
273279
fooChangeSpy
274280
)
@@ -284,7 +290,7 @@ describe(lruMemoize, () => {
284290
const state2 = { a: 1 }
285291
let count = 0
286292

287-
const selector = createSelector([(state: any) => state.a], () => {
293+
const selector = createSelectorLru([(state: any) => state.a], () => {
288294
count++
289295
return undefined
290296
})
@@ -361,7 +367,7 @@ describe(lruMemoize, () => {
361367
funcCalls = 0
362368

363369
// Test out maxSize of 3 + exposure via createSelector
364-
const selector = createSelector(
370+
const selector = createSelectorLru(
365371
(state: string) => state,
366372
state => {
367373
funcCalls++
@@ -415,3 +421,134 @@ describe(lruMemoize, () => {
415421
expect(selector.resultFunc.clearCache).toBeUndefined()
416422
})
417423
})
424+
425+
describe('lruMemoize integration with resultEqualityCheck', () => {
426+
const createAppSelector = createSelectorLru.withTypes<RootState>()
427+
428+
const resultEqualityCheck = vi
429+
.fn(shallowEqual)
430+
.mockName('resultEqualityCheck')
431+
432+
afterEach(() => {
433+
resultEqualityCheck.mockClear()
434+
})
435+
436+
localTest(
437+
'resultEqualityCheck works when set to shallowEqual',
438+
({ store }) => {
439+
const selectTodoIds = lruMemoize(
440+
(state: RootState) => state.todos.map(({ id }) => id),
441+
{ resultEqualityCheck }
442+
)
443+
444+
const firstResult = selectTodoIds(store.getState())
445+
446+
store.dispatch(toggleCompleted(0))
447+
448+
const secondResult = selectTodoIds(store.getState())
449+
450+
expect(firstResult).toBe(secondResult)
451+
452+
expect(selectTodoIds.resultsCount()).toBe(1)
453+
}
454+
)
455+
456+
localTest(
457+
'resultEqualityCheck should not be called on the first output selector call',
458+
({ store }) => {
459+
const selectTodoIds = createAppSelector(
460+
[state => state.todos],
461+
todos => todos.map(({ id }) => id),
462+
{
463+
memoizeOptions: { resultEqualityCheck },
464+
devModeChecks: { inputStabilityCheck: 'once' }
465+
}
466+
)
467+
468+
expect(selectTodoIds(store.getState())).to.be.an('array').that.is.not
469+
.empty
470+
471+
expect(resultEqualityCheck).not.toHaveBeenCalled()
472+
473+
store.dispatch(toggleCompleted(0))
474+
475+
expect(selectTodoIds.lastResult()).toBe(selectTodoIds(store.getState()))
476+
477+
expect(resultEqualityCheck).toHaveBeenCalledOnce()
478+
479+
expect(selectTodoIds.memoizedResultFunc.resultsCount()).toBe(1)
480+
481+
expect(selectTodoIds.recomputations()).toBe(2)
482+
483+
expect(selectTodoIds.resultsCount()).toBe(2)
484+
485+
expect(selectTodoIds.dependencyRecomputations()).toBe(2)
486+
487+
store.dispatch(toggleCompleted(0))
488+
489+
expect(selectTodoIds.lastResult()).toBe(selectTodoIds(store.getState()))
490+
491+
expect(resultEqualityCheck).toHaveBeenCalledTimes(2)
492+
493+
expect(selectTodoIds.memoizedResultFunc.resultsCount()).toBe(1)
494+
495+
expect(selectTodoIds.recomputations()).toBe(3)
496+
497+
expect(selectTodoIds.resultsCount()).toBe(3)
498+
499+
expect(selectTodoIds.dependencyRecomputations()).toBe(3)
500+
}
501+
)
502+
503+
localTest(
504+
'lruMemoize with resultEqualityCheck set to referenceEqualityCheck works the same as lruMemoize without resultEqualityCheck',
505+
({ store }) => {
506+
const resultEqualityCheck = vi
507+
.fn(referenceEqualityCheck)
508+
.mockName('resultEqualityCheck')
509+
510+
const selectTodoIdsWithResultEqualityCheck = lruMemoize(
511+
(state: RootState) => state.todos.map(({ id }) => id),
512+
{ resultEqualityCheck }
513+
)
514+
515+
const firstResultWithResultEqualityCheck =
516+
selectTodoIdsWithResultEqualityCheck(store.getState())
517+
518+
expect(resultEqualityCheck).not.toHaveBeenCalled()
519+
520+
store.dispatch(toggleCompleted(0))
521+
522+
const secondResultWithResultEqualityCheck =
523+
selectTodoIdsWithResultEqualityCheck(store.getState())
524+
525+
expect(firstResultWithResultEqualityCheck).not.toBe(
526+
secondResultWithResultEqualityCheck
527+
)
528+
529+
expect(firstResultWithResultEqualityCheck).toStrictEqual(
530+
secondResultWithResultEqualityCheck
531+
)
532+
533+
expect(selectTodoIdsWithResultEqualityCheck.resultsCount()).toBe(2)
534+
535+
const selectTodoIds = lruMemoize((state: RootState) =>
536+
state.todos.map(({ id }) => id)
537+
)
538+
539+
const firstResult = selectTodoIds(store.getState())
540+
541+
store.dispatch(toggleCompleted(0))
542+
543+
const secondResult = selectTodoIds(store.getState())
544+
545+
expect(firstResult).not.toBe(secondResult)
546+
547+
expect(firstResult).toStrictEqual(secondResult)
548+
549+
expect(selectTodoIds.resultsCount()).toBe(2)
550+
551+
resultEqualityCheck.mockClear()
552+
}
553+
)
554+
})

0 commit comments

Comments
 (0)