@@ -12,7 +12,7 @@ import {
12
12
readonly ,
13
13
ReactiveEffectRunner
14
14
} from '../src/index'
15
- import { ITERATE_KEY } from '../src/effect'
15
+ import { getDepFromReactive , ITERATE_KEY } from '../src/effect'
16
16
17
17
describe ( 'reactivity/effect' , ( ) => {
18
18
it ( 'should run the passed function once (wrapped by a effect)' , ( ) => {
@@ -999,4 +999,68 @@ describe('reactivity/effect', () => {
999
999
expect ( has ) . toBe ( false )
1000
1000
} )
1001
1001
} )
1002
+
1003
+ describe ( 'empty dep cleanup' , ( ) => {
1004
+ it ( 'should remove the dep when the effect is stopped' , ( ) => {
1005
+ const obj = reactive ( { prop : 1 } )
1006
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1007
+ const runner = effect ( ( ) => obj . prop )
1008
+ const dep = getDepFromReactive ( toRaw ( obj ) , 'prop' )
1009
+ expect ( dep ) . toHaveLength ( 1 )
1010
+ obj . prop = 2
1011
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBe ( dep )
1012
+ expect ( dep ) . toHaveLength ( 1 )
1013
+ stop ( runner )
1014
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1015
+ obj . prop = 3
1016
+ runner ( )
1017
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1018
+ } )
1019
+
1020
+ it ( 'should only remove the dep when the last effect is stopped' , ( ) => {
1021
+ const obj = reactive ( { prop : 1 } )
1022
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1023
+ const runner1 = effect ( ( ) => obj . prop )
1024
+ const dep = getDepFromReactive ( toRaw ( obj ) , 'prop' )
1025
+ expect ( dep ) . toHaveLength ( 1 )
1026
+ const runner2 = effect ( ( ) => obj . prop )
1027
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBe ( dep )
1028
+ expect ( dep ) . toHaveLength ( 2 )
1029
+ obj . prop = 2
1030
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBe ( dep )
1031
+ expect ( dep ) . toHaveLength ( 2 )
1032
+ stop ( runner1 )
1033
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBe ( dep )
1034
+ expect ( dep ) . toHaveLength ( 1 )
1035
+ obj . prop = 3
1036
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBe ( dep )
1037
+ expect ( dep ) . toHaveLength ( 1 )
1038
+ stop ( runner2 )
1039
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1040
+ obj . prop = 4
1041
+ runner1 ( )
1042
+ runner2 ( )
1043
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1044
+ } )
1045
+
1046
+ it ( 'should remove the dep when it is no longer used by the effect' , ( ) => {
1047
+ const obj = reactive < { a : number ; b : number ; c : 'a' | 'b' } > ( {
1048
+ a : 1 ,
1049
+ b : 2 ,
1050
+ c : 'a'
1051
+ } )
1052
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'prop' ) ) . toBeUndefined ( )
1053
+ effect ( ( ) => obj [ obj . c ] )
1054
+ const depC = getDepFromReactive ( toRaw ( obj ) , 'c' )
1055
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'a' ) ) . toHaveLength ( 1 )
1056
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'b' ) ) . toBeUndefined ( )
1057
+ expect ( depC ) . toHaveLength ( 1 )
1058
+ obj . c = 'b'
1059
+ obj . a = 4
1060
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'a' ) ) . toBeUndefined ( )
1061
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'b' ) ) . toHaveLength ( 1 )
1062
+ expect ( getDepFromReactive ( toRaw ( obj ) , 'c' ) ) . toBe ( depC )
1063
+ expect ( depC ) . toHaveLength ( 1 )
1064
+ } )
1065
+ } )
1002
1066
} )
0 commit comments