shallowReactive.spec.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import {
  2. isReactive,
  3. isRef,
  4. isShallow,
  5. reactive,
  6. Ref,
  7. ref,
  8. shallowReactive,
  9. shallowReadonly
  10. } from 'v3'
  11. describe('shallowReactive', () => {
  12. test('should not make non-reactive properties reactive', () => {
  13. const props = shallowReactive({ n: { foo: 1 } })
  14. expect(isReactive(props.n)).toBe(false)
  15. })
  16. test('should keep reactive properties reactive', () => {
  17. const props: any = shallowReactive({ n: reactive({ foo: 1 }) })
  18. props.n = reactive({ foo: 2 })
  19. expect(isReactive(props.n)).toBe(true)
  20. })
  21. test('isShallow', () => {
  22. expect(isShallow(shallowReactive({}))).toBe(true)
  23. expect(isShallow(shallowReadonly({}))).toBe(true)
  24. })
  25. // #5271
  26. test('should respect shallow reactive nested inside reactive on reset', () => {
  27. const r = reactive({ foo: shallowReactive({ bar: {} }) })
  28. expect(isShallow(r.foo)).toBe(true)
  29. expect(isReactive(r.foo.bar)).toBe(false)
  30. r.foo = shallowReactive({ bar: {} })
  31. expect(isShallow(r.foo)).toBe(true)
  32. expect(isReactive(r.foo.bar)).toBe(false)
  33. })
  34. // #12597
  35. test('should not unwrap refs', () => {
  36. const foo = shallowReactive({
  37. bar: ref(123)
  38. })
  39. expect(isRef(foo.bar)).toBe(true)
  40. expect(foo.bar.value).toBe(123)
  41. })
  42. // #12688
  43. test('should not mutate refs', () => {
  44. const original = ref(123)
  45. const foo = shallowReactive<{ bar: Ref<number> | number }>({
  46. bar: original
  47. })
  48. expect(foo.bar).toBe(original)
  49. foo.bar = 234
  50. expect(foo.bar).toBe(234)
  51. expect(original.value).toBe(123)
  52. })
  53. // @discrepancy no shallow/non-shallow versions from the same source -
  54. // cannot support this without real proxies
  55. // #2843
  56. // test('should allow shallow and normal reactive for same target', () => {
  57. // const original = { foo: {} }
  58. // const shallowProxy = shallowReactive(original)
  59. // const reactiveProxy = reactive(original)
  60. // expect(shallowProxy).not.toBe(reactiveProxy)
  61. // expect(isReactive(shallowProxy.foo)).toBe(false)
  62. // expect(isReactive(reactiveProxy.foo)).toBe(true)
  63. // })
  64. // test('should respect shallow/deep versions of same target on access', () => {
  65. // const original = {}
  66. // const shallow = shallowReactive(original)
  67. // const deep = reactive(original)
  68. // const r = reactive({ shallow, deep })
  69. // expect(r.shallow).toBe(shallow)
  70. // expect(r.deep).toBe(deep)
  71. // })
  72. // @discrepancy Vue 2 does not support collections
  73. // describe('collections', () => {
  74. // test('should be reactive', () => {
  75. // const shallowSet = shallowReactive(new Set())
  76. // const a = {}
  77. // let size
  78. // effect(() => {
  79. // size = shallowSet.size
  80. // })
  81. // expect(size).toBe(0)
  82. // shallowSet.add(a)
  83. // expect(size).toBe(1)
  84. // shallowSet.delete(a)
  85. // expect(size).toBe(0)
  86. // })
  87. // test('should not observe when iterating', () => {
  88. // const shallowSet = shallowReactive(new Set())
  89. // const a = {}
  90. // shallowSet.add(a)
  91. // const spreadA = [...shallowSet][0]
  92. // expect(isReactive(spreadA)).toBe(false)
  93. // })
  94. // test('should not get reactive entry', () => {
  95. // const shallowMap = shallowReactive(new Map())
  96. // const a = {}
  97. // const key = 'a'
  98. // shallowMap.set(key, a)
  99. // expect(isReactive(shallowMap.get(key))).toBe(false)
  100. // })
  101. // test('should not get reactive on foreach', () => {
  102. // const shallowSet = shallowReactive(new Set())
  103. // const a = {}
  104. // shallowSet.add(a)
  105. // shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
  106. // })
  107. // // #1210
  108. // test('onTrack on called on objectSpread', () => {
  109. // const onTrackFn = vi.fn()
  110. // const shallowSet = shallowReactive(new Set())
  111. // let a
  112. // effect(
  113. // () => {
  114. // a = Array.from(shallowSet)
  115. // },
  116. // {
  117. // onTrack: onTrackFn
  118. // }
  119. // )
  120. // expect(a).toMatchObject([])
  121. // expect(onTrackFn).toHaveBeenCalled()
  122. // })
  123. // })
  124. // @discrepancy Vue 2 does not track array without access
  125. // describe('array', () => {
  126. // test('should be reactive', () => {
  127. // const shallowArray = shallowReactive<unknown[]>([])
  128. // const a = {}
  129. // let size
  130. // effect(() => {
  131. // size = shallowArray.length
  132. // })
  133. // expect(size).toBe(0)
  134. // shallowArray.push(a)
  135. // expect(size).toBe(1)
  136. // shallowArray.pop()
  137. // expect(size).toBe(0)
  138. // })
  139. // test('should not observe when iterating', () => {
  140. // const shallowArray = shallowReactive<object[]>([])
  141. // const a = {}
  142. // shallowArray.push(a)
  143. // const spreadA = [...shallowArray][0]
  144. // expect(isReactive(spreadA)).toBe(false)
  145. // })
  146. // test('onTrack on called on objectSpread', () => {
  147. // const onTrackFn = vi.fn()
  148. // const shallowArray = shallowReactive([])
  149. // let a
  150. // effect(
  151. // () => {
  152. // a = Array.from(shallowArray)
  153. // },
  154. // {
  155. // onTrack: onTrackFn
  156. // }
  157. // )
  158. // expect(a).toMatchObject([])
  159. // expect(onTrackFn).toHaveBeenCalled()
  160. // })
  161. // })
  162. })