Skip to content

Commit 54812ea

Browse files
committed
test: add test case for transition memory leaks
from #12190
1 parent 1022eab commit 54812ea

File tree

1 file changed

+120
-0
lines changed

1 file changed

+120
-0
lines changed

packages/vue/__tests__/e2e/Transition.spec.ts

+120
Original file line numberDiff line numberDiff line change
@@ -3121,4 +3121,124 @@ describe('e2e: Transition', () => {
31213121
},
31223122
E2E_TIMEOUT,
31233123
)
3124+
3125+
// https://github.com/vuejs/core/issues/12181#issuecomment-2414380955
3126+
describe('not leaking', async () => {
3127+
test('switching VNodes', async () => {
3128+
const client = await page().createCDPSession()
3129+
await page().evaluate(async () => {
3130+
const { createApp, ref, nextTick } = (window as any).Vue
3131+
const empty = ref(true)
3132+
3133+
createApp({
3134+
components: {
3135+
Child: {
3136+
setup: () => {
3137+
// Big arrays kick GC earlier
3138+
const test = ref([...Array(30_000_000)].map((_, i) => ({ i })))
3139+
// TODO: Use a diferent TypeScript env for testing
3140+
// @ts-expect-error - Custom property and same lib as runtime is used
3141+
window.__REF__ = new WeakRef(test)
3142+
3143+
return { test }
3144+
},
3145+
template: `
3146+
<p>{{ test.length }}</p>
3147+
`,
3148+
},
3149+
Empty: {
3150+
template: '<div></div>',
3151+
},
3152+
},
3153+
template: `
3154+
<transition>
3155+
<component :is="empty ? 'Empty' : 'Child'" />
3156+
</transition>
3157+
`,
3158+
setup() {
3159+
return { empty }
3160+
},
3161+
}).mount('#app')
3162+
3163+
await nextTick()
3164+
empty.value = false
3165+
await nextTick()
3166+
empty.value = true
3167+
await nextTick()
3168+
})
3169+
3170+
const isCollected = async () =>
3171+
// @ts-expect-error - Custom property
3172+
await page().evaluate(() => window.__REF__.deref() === undefined)
3173+
3174+
while ((await isCollected()) === false) {
3175+
await client.send('HeapProfiler.collectGarbage')
3176+
}
3177+
3178+
expect(await isCollected()).toBe(true)
3179+
})
3180+
3181+
// https://github.com/vuejs/core/issues/12181#issue-2588232334
3182+
test('switching deep vnodes edge case', async () => {
3183+
const client = await page().createCDPSession()
3184+
await page().evaluate(async () => {
3185+
const { createApp, ref, nextTick } = (window as any).Vue
3186+
const shown = ref(false)
3187+
3188+
createApp({
3189+
components: {
3190+
Child: {
3191+
setup: () => {
3192+
// Big arrays kick GC earlier
3193+
const test = ref([...Array(30_000_000)].map((_, i) => ({ i })))
3194+
// TODO: Use a diferent TypeScript env for testing
3195+
// @ts-expect-error - Custom property and same lib as runtime is used
3196+
window.__REF__ = new WeakRef(test)
3197+
3198+
return { test }
3199+
},
3200+
template: `
3201+
<p>{{ test.length }}</p>
3202+
`,
3203+
},
3204+
Wrapper: {
3205+
template: `
3206+
<transition>
3207+
<div v-if="true">
3208+
<slot />
3209+
</div>
3210+
</transition>
3211+
`,
3212+
},
3213+
},
3214+
template: `
3215+
<button id="toggleBtn" @click="shown = !shown">{{ shown ? 'Hide' : 'Show' }}</button>
3216+
<Wrapper>
3217+
<Child v-if="shown" />
3218+
<div v-else></div>
3219+
</Wrapper>
3220+
`,
3221+
setup() {
3222+
return { shown }
3223+
},
3224+
}).mount('#app')
3225+
3226+
await nextTick()
3227+
shown.value = true
3228+
await nextTick()
3229+
shown.value = false
3230+
await nextTick()
3231+
})
3232+
3233+
const isCollected = async () =>
3234+
// @ts-expect-error - Custom property
3235+
await page().evaluate(() => window.__REF__.deref() === undefined)
3236+
3237+
while ((await isCollected()) === false) {
3238+
await client.send('HeapProfiler.collectGarbage')
3239+
}
3240+
3241+
expect(await isCollected()).toBe(true)
3242+
})
3243+
})
31243244
})

0 commit comments

Comments
 (0)