@@ -59,6 +59,7 @@ import {
59
59
docAddedRemoteEvent ,
60
60
docUpdateRemoteEvent ,
61
61
expectEqual ,
62
+ filter ,
62
63
key ,
63
64
localViewChanges ,
64
65
mapAsArray ,
@@ -72,14 +73,28 @@ import {
72
73
} from '../../util/helpers' ;
73
74
74
75
import { FieldValue , IntegerValue } from '../../../src/model/field_value' ;
76
+ import { CountingQueryEngine } from './forwarding_counting_query_engine' ;
75
77
import * as persistenceHelpers from './persistence_test_helpers' ;
76
78
77
79
class LocalStoreTester {
78
80
private promiseChain : Promise < void > = Promise . resolve ( ) ;
79
81
private lastChanges : MaybeDocumentMap | null = null ;
80
82
private lastTargetId : TargetId | null = null ;
81
83
private batches : MutationBatch [ ] = [ ] ;
82
- constructor ( public localStore : LocalStore , readonly gcIsEager : boolean ) { }
84
+
85
+ constructor (
86
+ public localStore : LocalStore ,
87
+ private readonly queryEngine : CountingQueryEngine ,
88
+ readonly gcIsEager : boolean
89
+ ) { }
90
+
91
+ private prepareNextStep ( ) : void {
92
+ this . promiseChain = this . promiseChain . then ( ( ) => {
93
+ this . lastChanges = null ;
94
+ this . lastTargetId = null ;
95
+ this . queryEngine . resetCounts ( ) ;
96
+ } ) ;
97
+ }
83
98
84
99
after (
85
100
op : Mutation | Mutation [ ] | RemoteEvent | LocalViewChanges
@@ -96,6 +111,8 @@ class LocalStoreTester {
96
111
}
97
112
98
113
afterMutations ( mutations : Mutation [ ] ) : LocalStoreTester {
114
+ this . prepareNextStep ( ) ;
115
+
99
116
this . promiseChain = this . promiseChain
100
117
. then ( ( ) => {
101
118
return this . localStore . localWrite ( mutations ) ;
@@ -110,6 +127,8 @@ class LocalStoreTester {
110
127
}
111
128
112
129
afterRemoteEvent ( remoteEvent : RemoteEvent ) : LocalStoreTester {
130
+ this . prepareNextStep ( ) ;
131
+
113
132
this . promiseChain = this . promiseChain
114
133
. then ( ( ) => {
115
134
return this . localStore . applyRemoteEvent ( remoteEvent ) ;
@@ -121,6 +140,8 @@ class LocalStoreTester {
121
140
}
122
141
123
142
afterViewChanges ( viewChanges : LocalViewChanges ) : LocalStoreTester {
143
+ this . prepareNextStep ( ) ;
144
+
124
145
this . promiseChain = this . promiseChain . then ( ( ) =>
125
146
this . localStore . notifyLocalViewChanges ( [ viewChanges ] )
126
147
) ;
@@ -131,6 +152,8 @@ class LocalStoreTester {
131
152
documentVersion : TestSnapshotVersion ;
132
153
transformResult ?: FieldValue ;
133
154
} ) : LocalStoreTester {
155
+ this . prepareNextStep ( ) ;
156
+
134
157
this . promiseChain = this . promiseChain
135
158
. then ( ( ) => {
136
159
const batch = this . batches . shift ( ) ! ;
@@ -161,6 +184,8 @@ class LocalStoreTester {
161
184
}
162
185
163
186
afterRejectingMutation ( ) : LocalStoreTester {
187
+ this . prepareNextStep ( ) ;
188
+
164
189
this . promiseChain = this . promiseChain
165
190
. then ( ( ) => {
166
191
return this . localStore . rejectBatch ( this . batches . shift ( ) ! . batchId ) ;
@@ -172,6 +197,8 @@ class LocalStoreTester {
172
197
}
173
198
174
199
afterAllocatingQuery ( query : Query ) : LocalStoreTester {
200
+ this . prepareNextStep ( ) ;
201
+
175
202
this . promiseChain = this . promiseChain . then ( ( ) => {
176
203
return this . localStore . allocateQuery ( query ) . then ( result => {
177
204
this . lastTargetId = result . targetId ;
@@ -181,6 +208,8 @@ class LocalStoreTester {
181
208
}
182
209
183
210
afterReleasingQuery ( query : Query ) : LocalStoreTester {
211
+ this . prepareNextStep ( ) ;
212
+
184
213
this . promiseChain = this . promiseChain . then ( ( ) => {
185
214
return this . localStore . releaseQuery (
186
215
query ,
@@ -190,6 +219,42 @@ class LocalStoreTester {
190
219
return this ;
191
220
}
192
221
222
+ afterExecutingQuery ( query : Query ) : LocalStoreTester {
223
+ this . prepareNextStep ( ) ;
224
+
225
+ this . promiseChain = this . promiseChain . then ( ( ) => {
226
+ return this . localStore . executeQuery ( query ) . then ( results => {
227
+ this . lastChanges = results ;
228
+ } ) ;
229
+ } ) ;
230
+ return this ;
231
+ }
232
+
233
+ /**
234
+ * Asserts the expected number of mutations and documents read by
235
+ * the MutationQueue and the RemoteDocumentCache.
236
+ */
237
+ toHaveRead ( expectedCount : {
238
+ mutations ?: number ;
239
+ remoteDocuments ?: number ;
240
+ } ) : LocalStoreTester {
241
+ this . promiseChain = this . promiseChain . then ( ( ) => {
242
+ if ( expectedCount . mutations !== undefined ) {
243
+ expect ( this . queryEngine . mutationsRead ) . to . be . eq (
244
+ expectedCount . mutations ,
245
+ 'Mutations read'
246
+ ) ;
247
+ }
248
+ if ( expectedCount . remoteDocuments !== undefined ) {
249
+ expect ( this . queryEngine . documentsRead ) . to . be . eq (
250
+ expectedCount . remoteDocuments ,
251
+ 'Remote documents read'
252
+ ) ;
253
+ }
254
+ } ) ;
255
+ return this ;
256
+ }
257
+
193
258
toReturnTargetId ( id : TargetId ) : LocalStoreTester {
194
259
this . promiseChain = this . promiseChain . then ( ( ) => {
195
260
expect ( this . lastTargetId ) . to . equal ( id ) ;
@@ -310,10 +375,16 @@ function genericLocalStoreTests(
310
375
) : void {
311
376
let persistence : Persistence ;
312
377
let localStore : LocalStore ;
378
+ let countingQueryEngine : CountingQueryEngine ;
313
379
314
380
beforeEach ( async ( ) => {
315
381
persistence = await getPersistence ( ) ;
316
- localStore = new LocalStore ( persistence , queryEngine , User . UNAUTHENTICATED ) ;
382
+ countingQueryEngine = new CountingQueryEngine ( queryEngine ) ;
383
+ localStore = new LocalStore (
384
+ persistence ,
385
+ countingQueryEngine ,
386
+ User . UNAUTHENTICATED
387
+ ) ;
317
388
} ) ;
318
389
319
390
afterEach ( async ( ) => {
@@ -322,7 +393,7 @@ function genericLocalStoreTests(
322
393
} ) ;
323
394
324
395
function expectLocalStore ( ) : LocalStoreTester {
325
- return new LocalStoreTester ( localStore , gcIsEager ) ;
396
+ return new LocalStoreTester ( localStore , countingQueryEngine , gcIsEager ) ;
326
397
}
327
398
328
399
it ( 'handles SetMutation' , ( ) => {
@@ -940,6 +1011,44 @@ function genericLocalStoreTests(
940
1011
] ) ;
941
1012
} ) ;
942
1013
1014
+ it ( 'reads all documents for initial collection queries' , ( ) => {
1015
+ const firstQuery = Query . atPath ( path ( 'foo' ) ) ;
1016
+ const secondQuery = Query . atPath ( path ( 'foo' ) ) . addFilter (
1017
+ filter ( 'matches' , '==' , true )
1018
+ ) ;
1019
+
1020
+ return expectLocalStore ( )
1021
+ . afterAllocatingQuery ( firstQuery )
1022
+ . toReturnTargetId ( 2 )
1023
+ . after (
1024
+ docAddedRemoteEvent (
1025
+ [
1026
+ doc ( 'foo/bar' , 10 , { matches : true } ) ,
1027
+ doc ( 'foo/baz' , 20 , { matches : true } )
1028
+ ] ,
1029
+ [ 2 ]
1030
+ )
1031
+ )
1032
+ . toReturnChanged (
1033
+ doc ( 'foo/bar' , 10 , { matches : true } ) ,
1034
+ doc ( 'foo/baz' , 20 , { matches : true } )
1035
+ )
1036
+ . after ( setMutation ( 'foo/bonk' , { matches : true } ) )
1037
+ . toReturnChanged (
1038
+ doc ( 'foo/bonk' , 0 , { matches : true } , { hasLocalMutations : true } )
1039
+ )
1040
+ . afterAllocatingQuery ( secondQuery )
1041
+ . toReturnTargetId ( 4 )
1042
+ . afterExecutingQuery ( secondQuery )
1043
+ . toReturnChanged (
1044
+ doc ( 'foo/bar' , 10 , { matches : true } ) ,
1045
+ doc ( 'foo/baz' , 20 , { matches : true } ) ,
1046
+ doc ( 'foo/bonk' , 0 , { matches : true } , { hasLocalMutations : true } )
1047
+ )
1048
+ . toHaveRead ( { remoteDocuments : 2 , mutations : 1 } )
1049
+ . finish ( ) ;
1050
+ } ) ;
1051
+
943
1052
it ( 'persists resume tokens' , async ( ) => {
944
1053
if ( gcIsEager ) {
945
1054
return ;
0 commit comments