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