@@ -2,6 +2,7 @@ import { h, nextTick, nodeOps, render, serializeInner } from '@vue/runtime-test'
22import {
33 type DebuggerEvent ,
44 ITERATE_KEY ,
5+ ReactiveEffect ,
56 TrackOpTypes ,
67 TriggerOpTypes ,
78 type WritableComputedRef ,
@@ -454,14 +455,10 @@ describe('reactivity/computed', () => {
454455 expect ( fnSpy ) . toBeCalledTimes ( 2 )
455456 } )
456457
457- it ( '...' , ( ) => {
458- const fnSpy = vi . fn ( )
458+ it ( 'should chained recurse effects clear dirty after trigger' , ( ) => {
459459 const v = ref ( 1 )
460460 const c1 = computed ( ( ) => v . value )
461- const c2 = computed ( ( ) => {
462- fnSpy ( )
463- return c1 . value
464- } )
461+ const c2 = computed ( ( ) => c1 . value )
465462
466463 c1 . effect . allowRecurse = true
467464 c2 . effect . allowRecurse = true
@@ -471,6 +468,60 @@ describe('reactivity/computed', () => {
471468 expect ( c2 . effect . _dirtyLevel ) . toBe ( DirtyLevels . NotDirty )
472469 } )
473470
471+ it ( 'should chained computeds dirtyLevel update with first computed effect' , ( ) => {
472+ const v = ref ( 0 )
473+ const c1 = computed ( ( ) => {
474+ if ( v . value === 0 ) {
475+ v . value = 1
476+ }
477+ return v . value
478+ } )
479+ const c2 = computed ( ( ) => c1 . value )
480+ const c3 = computed ( ( ) => c2 . value )
481+
482+ c3 . value
483+
484+ expect ( c1 . effect . _dirtyLevel ) . toBe ( DirtyLevels . Dirty )
485+ expect ( c2 . effect . _dirtyLevel ) . toBe ( DirtyLevels . MaybeDirty )
486+ expect ( c3 . effect . _dirtyLevel ) . toBe ( DirtyLevels . MaybeDirty )
487+ } )
488+
489+ it ( 'should work when chained(ref+computed)' , ( ) => {
490+ const v = ref ( 0 )
491+ const c1 = computed ( ( ) => {
492+ if ( v . value === 0 ) {
493+ v . value = 1
494+ }
495+ return 'foo'
496+ } )
497+ const c2 = computed ( ( ) => v . value + c1 . value )
498+ expect ( c2 . value ) . toBe ( '0foo' )
499+ expect ( c2 . effect . _dirtyLevel ) . toBe ( DirtyLevels . Dirty )
500+ expect ( c2 . value ) . toBe ( '1foo' )
501+ } )
502+
503+ it ( 'should trigger effect even computed already dirty' , ( ) => {
504+ const fnSpy = vi . fn ( )
505+ const v = ref ( 0 )
506+ const c1 = computed ( ( ) => {
507+ if ( v . value === 0 ) {
508+ v . value = 1
509+ }
510+ return 'foo'
511+ } )
512+ const c2 = computed ( ( ) => v . value + c1 . value )
513+
514+ effect ( ( ) => {
515+ fnSpy ( )
516+ c2 . value
517+ } )
518+ expect ( fnSpy ) . toBeCalledTimes ( 1 )
519+ expect ( c1 . effect . _dirtyLevel ) . toBe ( DirtyLevels . Dirty )
520+ expect ( c2 . effect . _dirtyLevel ) . toBe ( DirtyLevels . Dirty )
521+ v . value = 2
522+ expect ( fnSpy ) . toBeCalledTimes ( 2 )
523+ } )
524+
474525 it ( 'should be not dirty after deps mutate (mutate deps in computed)' , async ( ) => {
475526 const state = reactive < any > ( { } )
476527 const consumer = computed ( ( ) => {
0 commit comments