|
@@ -2,6 +2,7 @@ import { h, nextTick, nodeOps, render, serializeInner } from '@vue/runtime-test'
|
|
|
import {
|
|
import {
|
|
|
type DebuggerEvent,
|
|
type DebuggerEvent,
|
|
|
ITERATE_KEY,
|
|
ITERATE_KEY,
|
|
|
|
|
+ ReactiveEffect,
|
|
|
TrackOpTypes,
|
|
TrackOpTypes,
|
|
|
TriggerOpTypes,
|
|
TriggerOpTypes,
|
|
|
type WritableComputedRef,
|
|
type WritableComputedRef,
|
|
@@ -454,14 +455,10 @@ describe('reactivity/computed', () => {
|
|
|
expect(fnSpy).toBeCalledTimes(2)
|
|
expect(fnSpy).toBeCalledTimes(2)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
- it('...', () => {
|
|
|
|
|
- const fnSpy = vi.fn()
|
|
|
|
|
|
|
+ it('should chained recurse effects clear dirty after trigger', () => {
|
|
|
const v = ref(1)
|
|
const v = ref(1)
|
|
|
const c1 = computed(() => v.value)
|
|
const c1 = computed(() => v.value)
|
|
|
- const c2 = computed(() => {
|
|
|
|
|
- fnSpy()
|
|
|
|
|
- return c1.value
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ const c2 = computed(() => c1.value)
|
|
|
|
|
|
|
|
c1.effect.allowRecurse = true
|
|
c1.effect.allowRecurse = true
|
|
|
c2.effect.allowRecurse = true
|
|
c2.effect.allowRecurse = true
|
|
@@ -471,6 +468,60 @@ describe('reactivity/computed', () => {
|
|
|
expect(c2.effect._dirtyLevel).toBe(DirtyLevels.NotDirty)
|
|
expect(c2.effect._dirtyLevel).toBe(DirtyLevels.NotDirty)
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
|
|
+ it('should chained computeds dirtyLevel update with first computed effect', () => {
|
|
|
|
|
+ const v = ref(0)
|
|
|
|
|
+ const c1 = computed(() => {
|
|
|
|
|
+ if (v.value === 0) {
|
|
|
|
|
+ v.value = 1
|
|
|
|
|
+ }
|
|
|
|
|
+ return v.value
|
|
|
|
|
+ })
|
|
|
|
|
+ const c2 = computed(() => c1.value)
|
|
|
|
|
+ const c3 = computed(() => c2.value)
|
|
|
|
|
+
|
|
|
|
|
+ c3.value
|
|
|
|
|
+
|
|
|
|
|
+ expect(c1.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
|
|
|
|
|
+ expect(c2.effect._dirtyLevel).toBe(DirtyLevels.MaybeDirty)
|
|
|
|
|
+ expect(c3.effect._dirtyLevel).toBe(DirtyLevels.MaybeDirty)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ it('should work when chained(ref+computed)', () => {
|
|
|
|
|
+ const v = ref(0)
|
|
|
|
|
+ const c1 = computed(() => {
|
|
|
|
|
+ if (v.value === 0) {
|
|
|
|
|
+ v.value = 1
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'foo'
|
|
|
|
|
+ })
|
|
|
|
|
+ const c2 = computed(() => v.value + c1.value)
|
|
|
|
|
+ expect(c2.value).toBe('0foo')
|
|
|
|
|
+ expect(c2.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
|
|
|
|
|
+ expect(c2.value).toBe('1foo')
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ it('should trigger effect even computed already dirty', () => {
|
|
|
|
|
+ const fnSpy = vi.fn()
|
|
|
|
|
+ const v = ref(0)
|
|
|
|
|
+ const c1 = computed(() => {
|
|
|
|
|
+ if (v.value === 0) {
|
|
|
|
|
+ v.value = 1
|
|
|
|
|
+ }
|
|
|
|
|
+ return 'foo'
|
|
|
|
|
+ })
|
|
|
|
|
+ const c2 = computed(() => v.value + c1.value)
|
|
|
|
|
+
|
|
|
|
|
+ effect(() => {
|
|
|
|
|
+ fnSpy()
|
|
|
|
|
+ c2.value
|
|
|
|
|
+ })
|
|
|
|
|
+ expect(fnSpy).toBeCalledTimes(1)
|
|
|
|
|
+ expect(c1.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
|
|
|
|
|
+ expect(c2.effect._dirtyLevel).toBe(DirtyLevels.Dirty)
|
|
|
|
|
+ v.value = 2
|
|
|
|
|
+ expect(fnSpy).toBeCalledTimes(2)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
it('should be not dirty after deps mutate (mutate deps in computed)', async () => {
|
|
it('should be not dirty after deps mutate (mutate deps in computed)', async () => {
|
|
|
const state = reactive<any>({})
|
|
const state = reactive<any>({})
|
|
|
const consumer = computed(() => {
|
|
const consumer = computed(() => {
|