@@ -89,6 +89,80 @@ describe('reactivity/reactive/Array', () => {
8989 expect ( index ) . toBe ( 1 )
9090 } )
9191
92+ // only non-existent reactive will try to search by using its raw value
93+ describe ( 'Array identity methods have been called times' , ( ) => {
94+ const identityMethods = [ 'includes' , 'indexOf' , 'lastIndexOf' ] as const
95+ function instrumentArr ( rawTarget : any [ ] ) {
96+ identityMethods . forEach ( key => {
97+ const spy = vi . fn ( rawTarget [ key ] as any )
98+ rawTarget [ key ] = spy
99+ } )
100+ }
101+ function searchValue ( target : any [ ] , ...args : unknown [ ] ) {
102+ return identityMethods . map ( key => ( target [ key ] as any ) ( ...args ) )
103+ }
104+ function unInstrumentArr ( rawTarget : any [ ] ) {
105+ identityMethods . forEach ( key => {
106+ ; ( rawTarget [ key ] as any ) . mockClear ( )
107+ // relink to prototype method
108+ rawTarget [ key ] = Array . prototype [ key ] as any
109+ } )
110+ }
111+ function expectHaveBeenCalledTimes ( rawTarget : any [ ] , times : number ) {
112+ identityMethods . forEach ( key => {
113+ expect ( rawTarget [ key ] ) . toHaveBeenCalledTimes ( times )
114+ } )
115+ }
116+
117+ test ( 'should be called once with a non-existent raw value' , ( ) => {
118+ const reactiveArr = reactive ( [ ] )
119+ instrumentArr ( toRaw ( reactiveArr ) )
120+ const searchResult = searchValue ( reactiveArr , { } )
121+
122+ expectHaveBeenCalledTimes ( toRaw ( reactiveArr ) , 1 )
123+ expect ( searchResult ) . toStrictEqual ( [ false , - 1 , - 1 ] )
124+
125+ unInstrumentArr ( toRaw ( reactiveArr ) )
126+ } )
127+
128+ test ( 'should be called once with an existent reactive value' , ( ) => {
129+ const existReactiveValue = reactive ( { } )
130+ const reactiveArr = reactive ( [ existReactiveValue , existReactiveValue ] )
131+
132+ instrumentArr ( toRaw ( reactiveArr ) )
133+ const searchResult = searchValue ( reactiveArr , existReactiveValue )
134+
135+ expectHaveBeenCalledTimes ( toRaw ( reactiveArr ) , 1 )
136+ expect ( searchResult ) . toStrictEqual ( [ true , 0 , 1 ] )
137+
138+ unInstrumentArr ( toRaw ( reactiveArr ) )
139+ } )
140+
141+ test ( 'should be called twice with a non-existent reactive value' , ( ) => {
142+ const reactiveArr = reactive ( [ ] )
143+ instrumentArr ( toRaw ( reactiveArr ) )
144+ const searchResult = searchValue ( reactiveArr , reactive ( { } ) )
145+
146+ expectHaveBeenCalledTimes ( toRaw ( reactiveArr ) , 2 )
147+ expect ( searchResult ) . toStrictEqual ( [ false , - 1 , - 1 ] )
148+
149+ unInstrumentArr ( toRaw ( reactiveArr ) )
150+ } )
151+
152+ test ( 'should be called twice with a non-existent reactive value, but the raw value exists' , ( ) => {
153+ const existRaw = { }
154+ const reactiveArr = reactive ( [ existRaw , existRaw ] )
155+
156+ instrumentArr ( toRaw ( reactiveArr ) )
157+ const searchResult = searchValue ( reactiveArr , reactive ( existRaw ) )
158+
159+ expectHaveBeenCalledTimes ( toRaw ( reactiveArr ) , 2 )
160+ expect ( searchResult ) . toStrictEqual ( [ true , 0 , 1 ] )
161+
162+ unInstrumentArr ( toRaw ( reactiveArr ) )
163+ } )
164+ } )
165+
92166 test ( 'delete on Array should not trigger length dependency' , ( ) => {
93167 const arr = reactive ( [ 1 , 2 , 3 ] )
94168 const fn = vi . fn ( )
0 commit comments