@@ -177,6 +177,59 @@ test('an authoritative newer push acknowledges its matching choice before the ol
177177 f . client . close ( ) ;
178178} ) ;
179179
180+ test ( 'a validated generation change settles a readiness-waiting read before it is sent' , async ( t ) => {
181+ const f = fixture ( ) ;
182+ t . after ( ( ) => f . client . close ( ) ) ;
183+ const initial = await nextRequest ( ( ) => f . client . read ( ) ) ;
184+ f . reply ( accepted ) ;
185+ await initial . promise ;
186+ const oldFrame = f . frame ;
187+ const sentBeforeRead = f . sent . length ;
188+
189+ const waitingRead = f . client . read ( ) ;
190+ f . message ( { ...envelope , type : 'changed' , state : rejected } ) ;
191+
192+ assert . deepEqual ( await waitingRead , rejected ) ;
193+ await new Promise ( resolve => setImmediate ( resolve ) ) ;
194+ assert . equal ( f . sent . length , sentBeforeRead ) ;
195+ assert . equal ( oldFrame . removed , true ) ;
196+ assert . deepEqual ( f . client . state , rejected ) ;
197+ assert . equal ( f . failures . length , 0 ) ;
198+ } ) ;
199+
200+ test ( 'a validated generation change settles only its matching readiness-waiting choice' , async ( t ) => {
201+ const matching = fixture ( ) ;
202+ t . after ( ( ) => matching . client . close ( ) ) ;
203+ const initial = await nextRequest ( ( ) => matching . client . read ( ) ) ;
204+ matching . reply ( accepted ) ;
205+ await initial . promise ;
206+
207+ const matchingSentBeforeChoice = matching . sent . length ;
208+ const refusal = matching . client . choose ( 'rejected' ) ;
209+ matching . message ( { ...envelope , type : 'changed' , state : rejected } ) ;
210+ assert . deepEqual ( await refusal , rejected ) ;
211+ await new Promise ( resolve => setImmediate ( resolve ) ) ;
212+ assert . equal ( matching . sent . length , matchingSentBeforeChoice ) ;
213+ assert . equal ( matching . values . has ( localRefusalKey ) , false ) ;
214+ assert . equal ( matching . failures . length , 0 ) ;
215+ } ) ;
216+
217+ test ( 'a readiness-waiting acceptance cannot override a validated rejection' , async ( t ) => {
218+ const conflicting = fixture ( ) ;
219+ t . after ( ( ) => conflicting . client . close ( ) ) ;
220+ const initial = await nextRequest ( ( ) => conflicting . client . read ( ) ) ;
221+ conflicting . reply ( accepted ) ;
222+ await initial . promise ;
223+ const conflictingSentBeforeChoice = conflicting . sent . length ;
224+ const acceptance = conflicting . client . choose ( 'accepted' ) ;
225+ conflicting . message ( { ...envelope , type : 'changed' , state : rejected } ) ;
226+ await assert . rejects ( acceptance , / t r a c k i n g / i) ;
227+ await new Promise ( resolve => setImmediate ( resolve ) ) ;
228+ assert . equal ( conflicting . sent . length , conflictingSentBeforeChoice ) ;
229+ assert . deepEqual ( conflicting . client . state , rejected ) ;
230+ assert . equal ( conflicting . failures . length , 0 ) ;
231+ } ) ;
232+
180233test ( 'a visible rejected tab recreates its essential bridge and observes another tab reaccepting' , async ( ) => {
181234 const f = fixture ( ) ;
182235 const initial = await nextRequest ( ( ) => f . client . read ( ) ) ;
0 commit comments