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