Skip to content

Commit

Permalink
Merge pull request #4701 from ensconced/master
Browse files Browse the repository at this point in the history
Fix issue #4693
  • Loading branch information
markerikson authored Nov 23, 2024
2 parents 5c66933 + 3907062 commit dbe7f06
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 8 deletions.
12 changes: 4 additions & 8 deletions packages/toolkit/src/autoBatchEnhancer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ const createQueueWithTimer = (timeout: number) => {
}
}

// requestAnimationFrame won't exist in SSR environments.
// Fall back to a vague approximation just to keep from erroring.
const rAF =
typeof window !== 'undefined' && window.requestAnimationFrame
? window.requestAnimationFrame
: createQueueWithTimer(10)

export type AutoBatchOptions =
| { type: 'tick' }
| { type: 'timer'; timeout: number }
Expand Down Expand Up @@ -66,7 +59,10 @@ export const autoBatchEnhancer =
options.type === 'tick'
? queueMicrotask
: options.type === 'raf'
? rAF
? // requestAnimationFrame won't exist in SSR environments. Fall back to a vague approximation just to keep from erroring.
typeof window !== 'undefined' && window.requestAnimationFrame
? window.requestAnimationFrame
: createQueueWithTimer(10)
: options.type === 'callback'
? options.queueNotification
: createQueueWithTimer(options.timeout)
Expand Down
81 changes: 81 additions & 0 deletions packages/toolkit/src/tests/autoBatchEnhancer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,84 @@ describe.each(cases)('autoBatchEnhancer: %j', (autoBatchOptions) => {
expect(subscriptionNotifications).toBe(3)
})
})

describe.each(cases)(
'autoBatchEnhancer with fake timers: %j',
(autoBatchOptions) => {
beforeAll(() => {
vitest.useFakeTimers({
toFake: ['setTimeout', 'queueMicrotask', 'requestAnimationFrame'],
})
})
afterAll(() => {
vitest.useRealTimers()
})
beforeEach(() => {
subscriptionNotifications = 0
store = makeStore(autoBatchOptions)

store.subscribe(() => {
subscriptionNotifications++
})
})
test('Does not alter normal subscription notification behavior', () => {
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(1)
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(2)
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(3)
store.dispatch(decrementUnbatched())

vitest.runAllTimers()

expect(subscriptionNotifications).toBe(4)
})

test('Only notifies once if several batched actions are dispatched in a row', () => {
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(incrementBatched())

vitest.runAllTimers()

expect(subscriptionNotifications).toBe(1)
})

test('Notifies immediately if a non-batched action is dispatched', () => {
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(1)
store.dispatch(incrementBatched())

vitest.runAllTimers()

expect(subscriptionNotifications).toBe(2)
})

test('Does not notify at end of tick if last action was normal priority', () => {
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(incrementBatched())
expect(subscriptionNotifications).toBe(0)
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(1)
store.dispatch(incrementBatched())
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(2)
store.dispatch(decrementUnbatched())
expect(subscriptionNotifications).toBe(3)

vitest.runAllTimers()

expect(subscriptionNotifications).toBe(3)
})
},
)

0 comments on commit dbe7f06

Please sign in to comment.