shallowReadonly.spec.ts 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import { isReactive, isReadonly, readonly, shallowReadonly } from '../src'
  2. describe('reactivity/shallowReadonly', () => {
  3. test('should not make non-reactive properties reactive', () => {
  4. const props = shallowReadonly({ n: { foo: 1 } })
  5. expect(isReactive(props.n)).toBe(false)
  6. })
  7. test('should make root level properties readonly', () => {
  8. const props = shallowReadonly({ n: 1 })
  9. // @ts-expect-error
  10. props.n = 2
  11. expect(props.n).toBe(1)
  12. expect(
  13. `Set operation on key "n" failed: target is readonly.`
  14. ).toHaveBeenWarned()
  15. })
  16. // to retain 2.x behavior.
  17. test('should NOT make nested properties readonly', () => {
  18. const props = shallowReadonly({ n: { foo: 1 } })
  19. props.n.foo = 2
  20. expect(props.n.foo).toBe(2)
  21. expect(
  22. `Set operation on key "foo" failed: target is readonly.`
  23. ).not.toHaveBeenWarned()
  24. })
  25. // #2843
  26. test('should differentiate from normal readonly calls', () => {
  27. const original = { foo: {} }
  28. const shallowProxy = shallowReadonly(original)
  29. const reactiveProxy = readonly(original)
  30. expect(shallowProxy).not.toBe(reactiveProxy)
  31. expect(isReadonly(shallowProxy.foo)).toBe(false)
  32. expect(isReadonly(reactiveProxy.foo)).toBe(true)
  33. })
  34. describe('collection/Map', () => {
  35. ;[Map, WeakMap].forEach(Collection => {
  36. test('should make the map/weak-map readonly', () => {
  37. const key = {}
  38. const val = { foo: 1 }
  39. const original = new Collection([[key, val]])
  40. const sroMap = shallowReadonly(original)
  41. expect(isReadonly(sroMap)).toBe(true)
  42. expect(isReactive(sroMap)).toBe(false)
  43. expect(sroMap.get(key)).toBe(val)
  44. sroMap.set(key, {} as any)
  45. expect(
  46. `Set operation on key "[object Object]" failed: target is readonly.`
  47. ).toHaveBeenWarned()
  48. })
  49. test('should not make nested values readonly', () => {
  50. const key = {}
  51. const val = { foo: 1 }
  52. const original = new Collection([[key, val]])
  53. const sroMap = shallowReadonly(original)
  54. expect(isReadonly(sroMap.get(key))).toBe(false)
  55. expect(isReactive(sroMap.get(key))).toBe(false)
  56. sroMap.get(key)!.foo = 2
  57. expect(
  58. `Set operation on key "foo" failed: target is readonly.`
  59. ).not.toHaveBeenWarned()
  60. })
  61. })
  62. test('should not make the value generated by the iterable method readonly', () => {
  63. const key = {}
  64. const val = { foo: 1 }
  65. const original = new Map([[key, val]])
  66. const sroMap = shallowReadonly(original)
  67. const values1 = [...sroMap.values()]
  68. const values2 = [...sroMap.entries()]
  69. expect(isReadonly(values1[0])).toBe(false)
  70. expect(isReactive(values1[0])).toBe(false)
  71. expect(values1[0]).toBe(val)
  72. values1[0].foo = 2
  73. expect(
  74. `Set operation on key "foo" failed: target is readonly.`
  75. ).not.toHaveBeenWarned()
  76. expect(isReadonly(values2[0][1])).toBe(false)
  77. expect(isReactive(values2[0][1])).toBe(false)
  78. expect(values2[0][1]).toBe(val)
  79. values2[0][1].foo = 2
  80. expect(
  81. `Set operation on key "foo" failed: target is readonly.`
  82. ).not.toHaveBeenWarned()
  83. })
  84. test('should not make the value generated by the forEach method readonly', () => {
  85. const val = { foo: 1 }
  86. const original = new Map([['key', val]])
  87. const sroMap = shallowReadonly(original)
  88. sroMap.forEach(val => {
  89. expect(isReadonly(val)).toBe(false)
  90. expect(isReactive(val)).toBe(false)
  91. expect(val).toBe(val)
  92. val.foo = 2
  93. expect(
  94. `Set operation on key "foo" failed: target is readonly.`
  95. ).not.toHaveBeenWarned()
  96. })
  97. })
  98. })
  99. describe('collection/Set', () => {
  100. test('should make the set/weak-set readonly', () => {
  101. ;[Set, WeakSet].forEach(Collection => {
  102. const obj = { foo: 1 }
  103. const original = new Collection([obj])
  104. const sroSet = shallowReadonly(original)
  105. expect(isReadonly(sroSet)).toBe(true)
  106. expect(isReactive(sroSet)).toBe(false)
  107. expect(sroSet.has(obj)).toBe(true)
  108. sroSet.add({} as any)
  109. expect(
  110. `Add operation on key "[object Object]" failed: target is readonly.`
  111. ).toHaveBeenWarned()
  112. })
  113. })
  114. test('should not make nested values readonly', () => {
  115. const obj = { foo: 1 }
  116. const original = new Set([obj])
  117. const sroSet = shallowReadonly(original)
  118. const values = [...sroSet.values()]
  119. expect(values[0]).toBe(obj)
  120. expect(isReadonly(values[0])).toBe(false)
  121. expect(isReactive(values[0])).toBe(false)
  122. sroSet.add({} as any)
  123. expect(
  124. `Add operation on key "[object Object]" failed: target is readonly.`
  125. ).toHaveBeenWarned()
  126. values[0].foo = 2
  127. expect(
  128. `Set operation on key "foo" failed: target is readonly.`
  129. ).not.toHaveBeenWarned()
  130. })
  131. test('should not make the value generated by the iterable method readonly', () => {
  132. const val = { foo: 1 }
  133. const original = new Set([val])
  134. const sroSet = shallowReadonly(original)
  135. const values1 = [...sroSet.values()]
  136. const values2 = [...sroSet.entries()]
  137. expect(isReadonly(values1[0])).toBe(false)
  138. expect(isReactive(values1[0])).toBe(false)
  139. expect(values1[0]).toBe(val)
  140. values1[0].foo = 2
  141. expect(
  142. `Set operation on key "foo" failed: target is readonly.`
  143. ).not.toHaveBeenWarned()
  144. expect(isReadonly(values2[0][1])).toBe(false)
  145. expect(isReactive(values2[0][1])).toBe(false)
  146. expect(values2[0][1]).toBe(val)
  147. values2[0][1].foo = 2
  148. expect(
  149. `Set operation on key "foo" failed: target is readonly.`
  150. ).not.toHaveBeenWarned()
  151. })
  152. test('should not make the value generated by the forEach method readonly', () => {
  153. const val = { foo: 1 }
  154. const original = new Set([val])
  155. const sroSet = shallowReadonly(original)
  156. sroSet.forEach(val => {
  157. expect(isReadonly(val)).toBe(false)
  158. expect(isReactive(val)).toBe(false)
  159. expect(val).toBe(val)
  160. val.foo = 2
  161. expect(
  162. `Set operation on key "foo" failed: target is readonly.`
  163. ).not.toHaveBeenWarned()
  164. })
  165. })
  166. })
  167. })