Skip to content

Commit

Permalink
test: add test case for transition memory leaks
Browse files Browse the repository at this point in the history
from #12190
  • Loading branch information
yyx990803 committed Nov 15, 2024
1 parent 1022eab commit 54812ea
Showing 1 changed file with 120 additions and 0 deletions.
120 changes: 120 additions & 0 deletions packages/vue/__tests__/e2e/Transition.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3121,4 +3121,124 @@ describe('e2e: Transition', () => {
},
E2E_TIMEOUT,
)

// https://github.com/vuejs/core/issues/12181#issuecomment-2414380955
describe('not leaking', async () => {
test('switching VNodes', async () => {
const client = await page().createCDPSession()
await page().evaluate(async () => {
const { createApp, ref, nextTick } = (window as any).Vue
const empty = ref(true)

createApp({
components: {
Child: {
setup: () => {
// Big arrays kick GC earlier
const test = ref([...Array(30_000_000)].map((_, i) => ({ i })))
// TODO: Use a diferent TypeScript env for testing
// @ts-expect-error - Custom property and same lib as runtime is used
window.__REF__ = new WeakRef(test)

return { test }
},
template: `
<p>{{ test.length }}</p>
`,
},
Empty: {
template: '<div></div>',
},
},
template: `
<transition>
<component :is="empty ? 'Empty' : 'Child'" />
</transition>
`,
setup() {
return { empty }
},
}).mount('#app')

await nextTick()
empty.value = false
await nextTick()
empty.value = true
await nextTick()
})

const isCollected = async () =>
// @ts-expect-error - Custom property
await page().evaluate(() => window.__REF__.deref() === undefined)

while ((await isCollected()) === false) {
await client.send('HeapProfiler.collectGarbage')
}

expect(await isCollected()).toBe(true)
})

// https://github.com/vuejs/core/issues/12181#issue-2588232334
test('switching deep vnodes edge case', async () => {
const client = await page().createCDPSession()
await page().evaluate(async () => {
const { createApp, ref, nextTick } = (window as any).Vue
const shown = ref(false)

createApp({
components: {
Child: {
setup: () => {
// Big arrays kick GC earlier
const test = ref([...Array(30_000_000)].map((_, i) => ({ i })))
// TODO: Use a diferent TypeScript env for testing
// @ts-expect-error - Custom property and same lib as runtime is used
window.__REF__ = new WeakRef(test)

return { test }
},
template: `
<p>{{ test.length }}</p>
`,
},
Wrapper: {
template: `
<transition>
<div v-if="true">
<slot />
</div>
</transition>
`,
},
},
template: `
<button id="toggleBtn" @click="shown = !shown">{{ shown ? 'Hide' : 'Show' }}</button>
<Wrapper>
<Child v-if="shown" />
<div v-else></div>
</Wrapper>
`,
setup() {
return { shown }
},
}).mount('#app')

await nextTick()
shown.value = true
await nextTick()
shown.value = false
await nextTick()
})

const isCollected = async () =>
// @ts-expect-error - Custom property
await page().evaluate(() => window.__REF__.deref() === undefined)

while ((await isCollected()) === false) {
await client.send('HeapProfiler.collectGarbage')
}

expect(await isCollected()).toBe(true)
})
})
})

0 comments on commit 54812ea

Please sign in to comment.