Skip to content

Commit bde855e

Browse files
committed
test: test for computed optimization
1 parent ebaac9a commit bde855e

File tree

2 files changed

+90
-2
lines changed

2 files changed

+90
-2
lines changed

packages/reactivity/__tests__/computed.spec.ts

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ import {
44
effect,
55
ref,
66
WritableComputedRef,
7-
isReadonly
7+
isReadonly,
8+
setComputedScheduler
89
} from '../src'
910

1011
describe('reactivity/computed', () => {
@@ -198,4 +199,58 @@ describe('reactivity/computed', () => {
198199
x.effect.stop()
199200
expect(x.value).toBe(1)
200201
})
202+
203+
describe('with scheduler', () => {
204+
const p = Promise.resolve()
205+
const defer = (fn?: any) => (fn ? p.then(fn) : p)
206+
beforeEach(() => {
207+
setComputedScheduler(defer)
208+
})
209+
210+
afterEach(() => {
211+
setComputedScheduler(undefined)
212+
})
213+
214+
test('should only trigger once on multiple mutations', async () => {
215+
const src = ref(0)
216+
const c = computed(() => src.value)
217+
const spy = jest.fn()
218+
effect(() => {
219+
spy(c.value)
220+
})
221+
expect(spy).toHaveBeenCalledTimes(1)
222+
src.value = 1
223+
src.value = 2
224+
src.value = 3
225+
// not called yet
226+
expect(spy).toHaveBeenCalledTimes(1)
227+
await defer()
228+
// should only trigger once
229+
expect(spy).toHaveBeenCalledTimes(2)
230+
expect(spy).toHaveBeenCalledWith(c.value)
231+
})
232+
233+
test('should not trigger if value did not change', async () => {
234+
const src = ref(0)
235+
const c = computed(() => src.value % 2)
236+
const spy = jest.fn()
237+
effect(() => {
238+
spy(c.value)
239+
})
240+
expect(spy).toHaveBeenCalledTimes(1)
241+
src.value = 1
242+
src.value = 2
243+
244+
await defer()
245+
// should not trigger
246+
expect(spy).toHaveBeenCalledTimes(1)
247+
248+
src.value = 3
249+
src.value = 4
250+
src.value = 5
251+
await defer()
252+
// should trigger because latest value changes
253+
expect(spy).toHaveBeenCalledTimes(2)
254+
})
255+
})
201256
})

packages/runtime-core/__tests__/rendererComponent.spec.ts

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ import {
1010
inject,
1111
Ref,
1212
watch,
13-
SetupContext
13+
SetupContext,
14+
computed
1415
} from '@vue/runtime-test'
1516

1617
describe('renderer: component', () => {
@@ -321,4 +322,36 @@ describe('renderer: component', () => {
321322
expect(serializeInner(root)).toBe(``)
322323
expect(ids).toEqual([ids[0], ids[0] + 1, ids[0] + 2])
323324
})
325+
326+
test('computed that did not change should not trigger re-render', async () => {
327+
const src = ref(0)
328+
const c = computed(() => src.value % 2)
329+
const spy = jest.fn()
330+
const App = {
331+
render() {
332+
spy()
333+
return c.value
334+
}
335+
}
336+
337+
const root = nodeOps.createElement('div')
338+
render(h(App), root)
339+
expect(serializeInner(root)).toBe(`0`)
340+
expect(spy).toHaveBeenCalledTimes(1)
341+
342+
// verify it updates
343+
src.value = 1
344+
src.value = 2
345+
src.value = 3
346+
await nextTick()
347+
expect(serializeInner(root)).toBe(`1`)
348+
expect(spy).toHaveBeenCalledTimes(2) // should only update once
349+
350+
// verify it updates
351+
src.value = 4
352+
src.value = 5
353+
await nextTick()
354+
expect(serializeInner(root)).toBe(`1`)
355+
expect(spy).toHaveBeenCalledTimes(2) // should not need to update
356+
})
324357
})

0 commit comments

Comments
 (0)