@@ -76,12 +76,19 @@ export interface ActiveTargetSpec {
7676 queries : SpecQuery [ ] ;
7777 resumeToken ?: string ;
7878 readTime ?: TestSnapshotVersion ;
79+ expectedCount ?: number ;
7980}
8081
8182export interface ActiveTargetMap {
8283 [ targetId : string ] : ActiveTargetSpec ;
8384}
8485
86+ export interface ResumeSpec {
87+ resumeToken ?: string ;
88+ readTime ?: TestSnapshotVersion ;
89+ expectedCount ?: number ;
90+ }
91+
8592/**
8693 * Tracks the expected memory state of a client (e.g. the expected active watch
8794 * targets based on userListens(), userUnlistens(), and watchRemoves()
@@ -256,10 +263,7 @@ export class SpecBuilder {
256263 return this ;
257264 }
258265
259- userListens (
260- query : Query ,
261- resume ?: { resumeToken ?: string ; readTime ?: TestSnapshotVersion }
262- ) : this {
266+ userListens ( query : Query , resume ?: ResumeSpec ) : this {
263267 this . nextStep ( ) ;
264268
265269 const target = queryToTarget ( query ) ;
@@ -278,12 +282,7 @@ export class SpecBuilder {
278282 }
279283
280284 this . queryMapping . set ( target , targetId ) ;
281- this . addQueryToActiveTargets (
282- targetId ,
283- query ,
284- resume ?. resumeToken ,
285- resume ?. readTime
286- ) ;
285+ this . addQueryToActiveTargets ( targetId , query , resume ) ;
287286 this . currentStep = {
288287 userListen : { targetId, query : SpecBuilder . queryToSpec ( query ) } ,
289288 expectedState : { activeTargets : { ...this . activeTargets } }
@@ -296,14 +295,21 @@ export class SpecBuilder {
296295 * Registers a previously active target with the test expectations after a
297296 * stream disconnect.
298297 */
299- restoreListen ( query : Query , resumeToken : string ) : this {
298+ restoreListen (
299+ query : Query ,
300+ resumeToken : string ,
301+ expectedCount ?: number
302+ ) : this {
300303 const targetId = this . queryMapping . get ( queryToTarget ( query ) ) ;
301304
302305 if ( isNullOrUndefined ( targetId ) ) {
303306 throw new Error ( "Can't restore an unknown query: " + query ) ;
304307 }
305308
306- this . addQueryToActiveTargets ( targetId ! , query , resumeToken ) ;
309+ this . addQueryToActiveTargets ( targetId ! , query , {
310+ resumeToken,
311+ expectedCount
312+ } ) ;
307313
308314 const currentStep = this . currentStep ! ;
309315 currentStep . expectedState = currentStep . expectedState || { } ;
@@ -531,18 +537,18 @@ export class SpecBuilder {
531537 query : Query ;
532538 resumeToken ?: string ;
533539 readTime ?: TestSnapshotVersion ;
540+ expectedCount ?: number ;
534541 } >
535542 ) : this {
536543 this . assertStep ( 'Active target expectation requires previous step' ) ;
537544 const currentStep = this . currentStep ! ;
538545 this . clientState . activeTargets = { } ;
539- targets . forEach ( ( { query, resumeToken, readTime } ) => {
540- this . addQueryToActiveTargets (
541- this . getTargetId ( query ) ,
542- query ,
546+ targets . forEach ( ( { query, resumeToken, readTime, expectedCount } ) => {
547+ this . addQueryToActiveTargets ( this . getTargetId ( query ) , query , {
543548 resumeToken,
544- readTime
545- ) ;
549+ readTime,
550+ expectedCount
551+ } ) ;
546552 } ) ;
547553 currentStep . expectedState = currentStep . expectedState || { } ;
548554 currentStep . expectedState . activeTargets = { ...this . activeTargets } ;
@@ -573,7 +579,7 @@ export class SpecBuilder {
573579 this . addQueryToActiveTargets (
574580 this . limboMapping [ path ] ,
575581 newQueryForPath ( key . path ) ,
576- ''
582+ { resumeToken : '' }
577583 ) ;
578584 } ) ;
579585
@@ -912,22 +918,14 @@ export class SpecBuilder {
912918 }
913919
914920 /** Registers a query that is active in another tab. */
915- expectListen (
916- query : Query ,
917- resume ?: { resumeToken ?: string ; readTime ?: TestSnapshotVersion }
918- ) : this {
921+ expectListen ( query : Query , resume ?: ResumeSpec ) : this {
919922 this . assertStep ( 'Expectations require previous step' ) ;
920923
921924 const target = queryToTarget ( query ) ;
922925 const targetId = this . queryIdGenerator . cachedId ( target ) ;
923926 this . queryMapping . set ( target , targetId ) ;
924927
925- this . addQueryToActiveTargets (
926- targetId ,
927- query ,
928- resume ?. resumeToken ,
929- resume ?. readTime
930- ) ;
928+ this . addQueryToActiveTargets ( targetId , query , resume ) ;
931929
932930 const currentStep = this . currentStep ! ;
933931 currentStep . expectedState = currentStep . expectedState || { } ;
@@ -1095,9 +1093,12 @@ export class SpecBuilder {
10951093 private addQueryToActiveTargets (
10961094 targetId : number ,
10971095 query : Query ,
1098- resumeToken ?: string ,
1099- readTime ?: TestSnapshotVersion
1096+ resume ?: ResumeSpec
11001097 ) : void {
1098+ if ( ! ( resume ?. resumeToken || resume ?. readTime ) && resume ?. expectedCount ) {
1099+ fail ( 'Expected count is present without a resume token or read time.' ) ;
1100+ }
1101+
11011102 if ( this . activeTargets [ targetId ] ) {
11021103 const activeQueries = this . activeTargets [ targetId ] . queries ;
11031104 if (
@@ -1108,21 +1109,24 @@ export class SpecBuilder {
11081109 // `query` is not added yet.
11091110 this . activeTargets [ targetId ] = {
11101111 queries : [ SpecBuilder . queryToSpec ( query ) , ...activeQueries ] ,
1111- resumeToken : resumeToken || '' ,
1112- readTime
1112+ resumeToken : resume ?. resumeToken || '' ,
1113+ readTime : resume ?. readTime ,
1114+ expectedCount : resume ?. expectedCount
11131115 } ;
11141116 } else {
11151117 this . activeTargets [ targetId ] = {
11161118 queries : activeQueries ,
1117- resumeToken : resumeToken || '' ,
1118- readTime
1119+ resumeToken : resume ?. resumeToken || '' ,
1120+ readTime : resume ?. readTime ,
1121+ expectedCount : resume ?. expectedCount
11191122 } ;
11201123 }
11211124 } else {
11221125 this . activeTargets [ targetId ] = {
11231126 queries : [ SpecBuilder . queryToSpec ( query ) ] ,
1124- resumeToken : resumeToken || '' ,
1125- readTime
1127+ resumeToken : resume ?. resumeToken || '' ,
1128+ readTime : resume ?. readTime ,
1129+ expectedCount : resume ?. expectedCount
11261130 } ;
11271131 }
11281132 }
@@ -1134,7 +1138,8 @@ export class SpecBuilder {
11341138 if ( queriesAfterRemoval . length > 0 ) {
11351139 this . activeTargets [ targetId ] = {
11361140 queries : queriesAfterRemoval ,
1137- resumeToken : this . activeTargets [ targetId ] . resumeToken
1141+ resumeToken : this . activeTargets [ targetId ] . resumeToken ,
1142+ expectedCount : this . activeTargets [ targetId ] . expectedCount
11381143 } ;
11391144 } else {
11401145 delete this . activeTargets [ targetId ] ;
0 commit comments