]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
fix(reactivity): shallowReactive collection to not-readonly (#1212)
authorCarlos Rodrigues <carlos@hypermob.co.uk>
Tue, 9 Jun 2020 21:20:30 +0000 (22:20 +0100)
committerGitHub <noreply@github.com>
Tue, 9 Jun 2020 21:20:30 +0000 (17:20 -0400)
packages/reactivity/__tests__/reactive.spec.ts
packages/reactivity/__tests__/shallowReactive.spec.ts [new file with mode: 0644]
packages/reactivity/src/collectionHandlers.ts

index 6d2c68962d465fa06ee233e75ecafd3d1f69bb26..46ce75b6acb449755d09e62f2158194c7f446805 100644 (file)
@@ -1,11 +1,5 @@
 import { ref, isRef } from '../src/ref'
-import {
-  reactive,
-  isReactive,
-  toRaw,
-  markRaw,
-  shallowReactive
-} from '../src/reactive'
+import { reactive, isReactive, toRaw, markRaw } from '../src/reactive'
 import { mockWarn } from '@vue/shared'
 import { computed } from '../src/computed'
 
@@ -175,44 +169,4 @@ describe('reactivity/reactive', () => {
     })
     expect(isReactive(obj.foo)).toBe(false)
   })
-
-  describe('shallowReactive', () => {
-    test('should not make non-reactive properties reactive', () => {
-      const props = shallowReactive({ n: { foo: 1 } })
-      expect(isReactive(props.n)).toBe(false)
-    })
-
-    test('should keep reactive properties reactive', () => {
-      const props: any = shallowReactive({ n: reactive({ foo: 1 }) })
-      props.n = reactive({ foo: 2 })
-      expect(isReactive(props.n)).toBe(true)
-    })
-
-    test('should not observe when iterating', () => {
-      const shallowSet = shallowReactive(new Set())
-      const a = {}
-      shallowSet.add(a)
-
-      const spreadA = [...shallowSet][0]
-      expect(isReactive(spreadA)).toBe(false)
-    })
-
-    test('should not get reactive entry', () => {
-      const shallowMap = shallowReactive(new Map())
-      const a = {}
-      const key = 'a'
-
-      shallowMap.set(key, a)
-
-      expect(isReactive(shallowMap.get(key))).toBe(false)
-    })
-
-    test('should not get reactive on foreach', () => {
-      const shallowSet = shallowReactive(new Set())
-      const a = {}
-      shallowSet.add(a)
-
-      shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
-    })
-  })
 })
diff --git a/packages/reactivity/__tests__/shallowReactive.spec.ts b/packages/reactivity/__tests__/shallowReactive.spec.ts
new file mode 100644 (file)
index 0000000..5997d04
--- /dev/null
@@ -0,0 +1,125 @@
+import { shallowReactive, isReactive, reactive } from '../src/reactive'
+import { effect } from '../src/effect'
+
+describe('shallowReactive', () => {
+  test('should not make non-reactive properties reactive', () => {
+    const props = shallowReactive({ n: { foo: 1 } })
+    expect(isReactive(props.n)).toBe(false)
+  })
+
+  test('should keep reactive properties reactive', () => {
+    const props: any = shallowReactive({ n: reactive({ foo: 1 }) })
+    props.n = reactive({ foo: 2 })
+    expect(isReactive(props.n)).toBe(true)
+  })
+
+  describe('collections', () => {
+    test('should be reactive', () => {
+      const shallowSet = shallowReactive(new Set())
+      const a = {}
+      let size
+
+      effect(() => {
+        size = shallowSet.size
+      })
+
+      expect(size).toBe(0)
+
+      shallowSet.add(a)
+      expect(size).toBe(1)
+
+      shallowSet.delete(a)
+      expect(size).toBe(0)
+    })
+
+    test('should not observe when iterating', () => {
+      const shallowSet = shallowReactive(new Set())
+      const a = {}
+      shallowSet.add(a)
+
+      const spreadA = [...shallowSet][0]
+      expect(isReactive(spreadA)).toBe(false)
+    })
+
+    test('should not get reactive entry', () => {
+      const shallowMap = shallowReactive(new Map())
+      const a = {}
+      const key = 'a'
+
+      shallowMap.set(key, a)
+
+      expect(isReactive(shallowMap.get(key))).toBe(false)
+    })
+
+    test('should not get reactive on foreach', () => {
+      const shallowSet = shallowReactive(new Set())
+      const a = {}
+      shallowSet.add(a)
+
+      shallowSet.forEach(x => expect(isReactive(x)).toBe(false))
+    })
+
+    // #1210
+    test('onTrack on called on objectSpread', () => {
+      const onTrackFn = jest.fn()
+      const shallowSet = shallowReactive(new Set())
+      let a
+      effect(
+        () => {
+          a = Array.from(shallowSet)
+        },
+        {
+          onTrack: onTrackFn
+        }
+      )
+
+      expect(a).toMatchObject([])
+      expect(onTrackFn).toHaveBeenCalled()
+    })
+  })
+
+  describe('array', () => {
+    test('should be reactive', () => {
+      const shallowArray = shallowReactive<unknown[]>([])
+      const a = {}
+      let size
+
+      effect(() => {
+        size = shallowArray.length
+      })
+
+      expect(size).toBe(0)
+
+      shallowArray.push(a)
+      expect(size).toBe(1)
+
+      shallowArray.pop()
+      expect(size).toBe(0)
+    })
+    test('should not observe when iterating', () => {
+      const shallowArray = shallowReactive<object[]>([])
+      const a = {}
+      shallowArray.push(a)
+
+      const spreadA = [...shallowArray][0]
+      expect(isReactive(spreadA)).toBe(false)
+    })
+
+    test('onTrack on called on objectSpread', () => {
+      const onTrackFn = jest.fn()
+      const shallowArray = shallowReactive([])
+      let a
+      effect(
+        () => {
+          a = Array.from(shallowArray)
+        },
+        {
+          onTrack: onTrackFn
+        }
+      )
+
+      expect(a).toMatchObject([])
+      expect(onTrackFn).toHaveBeenCalled()
+    })
+  })
+})
index 181a6e2152cebe8e698bbe37fc6e247d410d55f4..b9b45c78db8736064a83b1c62939b18db7424375 100644 (file)
@@ -265,7 +265,7 @@ iteratorMethods.forEach(method => {
   )
   shallowInstrumentations[method as string] = createIterableMethod(
     method,
-    true,
+    false,
     true
   )
 })