vue3-core/packages/reactivity/__tests__/gc.spec.ts

82 lines
1.7 KiB
TypeScript

import {
type ComputedRef,
computed,
effect,
reactive,
shallowRef as ref,
toRaw,
} from '../src/index'
import { getDepFromReactive } from '../src/dep'
describe.skipIf(!global.gc)('reactivity/gc', () => {
const gc = () => {
return new Promise<void>(resolve => {
setTimeout(() => {
global.gc!()
resolve()
})
})
}
// #9233
it('should release computed cache', async () => {
const src = ref<{} | undefined>({})
const srcRef = new WeakRef(src.value!)
let c: ComputedRef | undefined = computed(() => src.value)
c.value // cache src value
src.value = undefined // release value
c = undefined // release computed
await gc()
expect(srcRef.deref()).toBeUndefined()
})
it('should release reactive property dep', async () => {
const src = reactive({ foo: 1 })
let c: ComputedRef | undefined = computed(() => src.foo)
c.value
expect(getDepFromReactive(toRaw(src), 'foo')).not.toBeUndefined()
c = undefined
await gc()
await gc()
expect(getDepFromReactive(toRaw(src), 'foo')).toBeUndefined()
})
it('should not release effect for ref', async () => {
const spy = vi.fn()
const src = ref(0)
effect(() => {
spy()
src.value
})
expect(spy).toHaveBeenCalledTimes(1)
await gc()
src.value++
expect(spy).toHaveBeenCalledTimes(2)
})
it('should not release effect for reactive', async () => {
const spy = vi.fn()
const src = reactive({ foo: 1 })
effect(() => {
spy()
src.foo
})
expect(spy).toHaveBeenCalledTimes(1)
await gc()
src.foo++
expect(spy).toHaveBeenCalledTimes(2)
})
})