gc.spec.ts 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081
  1. import {
  2. type ComputedRef,
  3. computed,
  4. effect,
  5. reactive,
  6. shallowRef as ref,
  7. toRaw,
  8. } from '../src/index'
  9. import { getDepFromReactive } from '../src/reactiveEffect'
  10. describe.skipIf(!global.gc)('reactivity/gc', () => {
  11. const gc = () => {
  12. return new Promise<void>(resolve => {
  13. setTimeout(() => {
  14. global.gc!()
  15. resolve()
  16. })
  17. })
  18. }
  19. // #9233
  20. it('should release computed cache', async () => {
  21. const src = ref<{} | undefined>({})
  22. const srcRef = new WeakRef(src.value!)
  23. let c: ComputedRef | undefined = computed(() => src.value)
  24. c.value // cache src value
  25. src.value = undefined // release value
  26. c = undefined // release computed
  27. await gc()
  28. expect(srcRef.deref()).toBeUndefined()
  29. })
  30. it('should release reactive property dep', async () => {
  31. const src = reactive({ foo: 1 })
  32. let c: ComputedRef | undefined = computed(() => src.foo)
  33. c.value
  34. expect(getDepFromReactive(toRaw(src), 'foo')).not.toBeUndefined()
  35. c = undefined
  36. await gc()
  37. await gc()
  38. expect(getDepFromReactive(toRaw(src), 'foo')).toBeUndefined()
  39. })
  40. it('should not release effect for ref', async () => {
  41. const spy = vi.fn()
  42. const src = ref(0)
  43. effect(() => {
  44. spy()
  45. src.value
  46. })
  47. expect(spy).toHaveBeenCalledTimes(1)
  48. await gc()
  49. src.value++
  50. expect(spy).toHaveBeenCalledTimes(2)
  51. })
  52. it('should not release effect for reactive', async () => {
  53. const spy = vi.fn()
  54. const src = reactive({ foo: 1 })
  55. effect(() => {
  56. spy()
  57. src.foo
  58. })
  59. expect(spy).toHaveBeenCalledTimes(1)
  60. await gc()
  61. src.foo++
  62. expect(spy).toHaveBeenCalledTimes(2)
  63. })
  64. })