@@ -50,16 +50,16 @@ const assertTransmission = async (t, publishKit, value, method = 'publish') => {
50
50
}
51
51
} ;
52
52
53
- const assertCells = ( t , label , cells , publishCount , result , options = { } ) => {
54
- const { strict = true } = options ;
53
+ const assertCells = ( t , label , cells , publishCount , expected , options = { } ) => {
54
+ const { strict = true , iterationResults = { } } = options ;
55
55
const firstCell = cells [ 0 ] ;
56
56
t . deepEqual (
57
57
Reflect . ownKeys ( firstCell ) . sort ( ) ,
58
58
[ 'head' , 'publishCount' , 'tail' ] ,
59
59
`${ label } cell property keys` ,
60
60
) ;
61
- t . deepEqual ( firstCell . head , result , `${ label } cell result` ) ;
62
- t . is ( firstCell . head . value , result . value , `${ label } cell value` ) ;
61
+ t . deepEqual ( firstCell . head , expected , `${ label } cell result` ) ;
62
+ t . is ( firstCell . head . value , expected . value , `${ label } cell value` ) ;
63
63
// `publishCount` values *should* be considered opaque,
64
64
// but de facto they are a gap-free sequence of bigints
65
65
// that starts at 1.
@@ -78,6 +78,10 @@ const assertCells = (t, label, cells, publishCount, result, options = {}) => {
78
78
t . like ( cell , props , `${ label } cell ${ i + 1 } must match cell 0` ) ;
79
79
} ) ;
80
80
}
81
+
82
+ for ( const [ resultLabel , result ] of Object . entries ( iterationResults ) ) {
83
+ t . deepEqual ( result , expected , `${ label } ${ resultLabel } result` ) ;
84
+ }
81
85
} ;
82
86
83
87
// eslint-disable-next-line no-shadow
@@ -270,13 +274,31 @@ test('durable publish kit upgrade trauma (full-vat integration)', async t => {
270
274
vatParameters : { version : 'v1' } ,
271
275
} ,
272
276
] ) ;
277
+ await run ( 'createVat' , [
278
+ {
279
+ name : 'pubsub2' ,
280
+ bundleCapName : 'pubsub' ,
281
+ } ,
282
+ ] ) ;
273
283
t . is (
274
284
await run ( 'messageVat' , [ { name : 'pubsub' , methodName : 'getVersion' } ] ) ,
275
285
'v1' ,
276
286
) ;
277
287
const sub1 = await run ( 'messageVat' , [
278
288
{ name : 'pubsub' , methodName : 'getSubscriber' } ,
279
289
] ) ;
290
+ const eachIterable = await run ( 'messageVat' , [
291
+ { name : 'pubsub2' , methodName : 'subscribeEach' , args : [ sub1 ] } ,
292
+ ] ) ;
293
+ const eachIterator1 = await run ( 'messageVatObject' , [
294
+ { presence : eachIterable , methodName : Symbol . asyncIterator } ,
295
+ ] ) ;
296
+ const latestIterable = await run ( 'messageVat' , [
297
+ { name : 'pubsub2' , methodName : 'subscribeLatest' , args : [ sub1 ] } ,
298
+ ] ) ;
299
+ const latestIterator1 = await run ( 'messageVatObject' , [
300
+ { presence : latestIterable , methodName : Symbol . asyncIterator } ,
301
+ ] ) ;
280
302
281
303
/**
282
304
* Advances the publisher.
@@ -290,17 +312,39 @@ test('durable publish kit upgrade trauma (full-vat integration)', async t => {
290
312
] ) ;
291
313
} ;
292
314
293
- // Verify receipt of a published value.
315
+ // Verify receipt of a published value via subscribeAfter
316
+ // and async iterators.
294
317
const value1 = Symbol . for ( 'value1' ) ;
295
318
await publish ( value1 ) ;
319
+ const expectedV1FirstResult = { value : value1 , done : false } ;
296
320
const v1FirstCell = await run ( 'messageVatObject' , [
297
321
{ presence : sub1 , methodName : 'subscribeAfter' } ,
298
322
] ) ;
299
- assertCells ( t , 'v1 first' , [ v1FirstCell ] , 1n , { value : value1 , done : false } ) ;
300
-
301
- // Verify receipt of a second published value via tail and subscribeAfter.
323
+ assertCells ( t , 'v1 first' , [ v1FirstCell ] , 1n , expectedV1FirstResult ) ;
324
+ const eachIteratorFirstResult = await run ( 'messageVatObject' , [
325
+ { presence : eachIterator1 , methodName : 'next' } ,
326
+ ] ) ;
327
+ t . deepEqual (
328
+ eachIteratorFirstResult ,
329
+ expectedV1FirstResult ,
330
+ 'v1 eachIterator first result' ,
331
+ ) ;
332
+ // Don't ask the latest iterator for its first result so we can observe
333
+ // that it skips intermediate results.
334
+ // const latestIteratorFirstResult = await run('messageVatObject', [
335
+ // { presence: latestIterator1, methodName: 'next' },
336
+ // ]);
337
+ // t.deepEqual(
338
+ // latestIteratorFirstResult,
339
+ // expectedV1FirstResult,
340
+ // 'v1 latestIterator first result',
341
+ // );
342
+
343
+ // Verify receipt of a second published value via tail and subscribeAfter
344
+ // and async iterators.
302
345
const value2 = Symbol . for ( 'value2' ) ;
303
346
await publish ( value2 ) ;
347
+ const expectedV1SecondResult = { value : value2 , done : false } ;
304
348
await run ( 'messageVatObject' , [
305
349
{ presence : sub1 , methodName : 'subscribeAfter' } ,
306
350
] ) ;
@@ -313,14 +357,18 @@ test('durable publish kit upgrade trauma (full-vat integration)', async t => {
313
357
{ presence : sub1 , methodName : 'subscribeAfter' } ,
314
358
] ) ,
315
359
] ;
316
- assertCells (
317
- t ,
318
- 'v1 second' ,
319
- v1SecondCells ,
320
- 2n ,
321
- { value : value2 , done : false } ,
322
- { strict : false } ,
323
- ) ;
360
+ const v1SecondIterationResults = {
361
+ eachIterator : await run ( 'messageVatObject' , [
362
+ { presence : eachIterator1 , methodName : 'next' } ,
363
+ ] ) ,
364
+ latestIterator : await run ( 'messageVatObject' , [
365
+ { presence : latestIterator1 , methodName : 'next' } ,
366
+ ] ) ,
367
+ } ;
368
+ assertCells ( t , 'v1 second' , v1SecondCells , 2n , expectedV1SecondResult , {
369
+ strict : false ,
370
+ iterationResults : v1SecondIterationResults ,
371
+ } ) ;
324
372
325
373
// Upgrade the vat, breaking promises from v1.
326
374
await run ( 'upgradeVat' , [
@@ -337,26 +385,47 @@ test('durable publish kit upgrade trauma (full-vat integration)', async t => {
337
385
const sub2 = await run ( 'messageVat' , [
338
386
{ name : 'pubsub' , methodName : 'getSubscriber' } ,
339
387
] ) ;
340
- await run ( 'awaitVatObject' , [ { presence : v1SecondCells [ 0 ] . tail } ] ) . then (
341
- ( ...args ) =>
342
- t . deepEqual ( args , undefined , 'tail promise of old vat must be rejected' ) ,
343
- failure =>
344
- t . deepEqual ( failure , {
345
- incarnationNumber : 1 ,
346
- name : 'vatUpgraded' ,
347
- upgradeMessage : 'vat upgraded' ,
348
- } ) ,
388
+ const eachIterator2 = await run ( 'messageVatObject' , [
389
+ { presence : eachIterable , methodName : Symbol . asyncIterator } ,
390
+ ] ) ;
391
+ const assertDisconnection = ( p , label ) => {
392
+ const expected = {
393
+ incarnationNumber : 1 ,
394
+ name : 'vatUpgraded' ,
395
+ upgradeMessage : 'vat upgraded' ,
396
+ } ;
397
+ return p . then (
398
+ ( ...args ) => t . deepEqual ( args , undefined , `${ label } must be rejected` ) ,
399
+ failure =>
400
+ t . deepEqual ( failure , expected , `${ label } must indicate disconnection` ) ,
401
+ ) ;
402
+ } ;
403
+ await assertDisconnection (
404
+ run ( 'awaitVatObject' , [ { presence : v1SecondCells [ 0 ] . tail } ] ) ,
405
+ 'tail promise of old vat' ,
406
+ ) ;
407
+ await assertDisconnection (
408
+ run ( 'messageVatObject' , [ { presence : eachIterator1 , methodName : 'next' } ] ) ,
409
+ 'eachIterator following old vat subscriber' ,
349
410
) ;
350
411
351
412
// Verify receipt of the last published value from v1.
352
413
const v2FirstCell = await run ( 'messageVatObject' , [
353
414
{ presence : sub2 , methodName : 'subscribeAfter' } ,
354
415
] ) ;
355
- assertCells ( t , 'v2 first' , [ v2FirstCell ] , 2n , { value : value2 , done : false } ) ;
416
+ const v2FirstIterationResults = {
417
+ eachIterator : await run ( 'messageVatObject' , [
418
+ { presence : eachIterator2 , methodName : 'next' } ,
419
+ ] ) ,
420
+ } ;
421
+ assertCells ( t , 'v2 first' , [ v2FirstCell ] , 2n , expectedV1SecondResult , {
422
+ iterationResults : v2FirstIterationResults ,
423
+ } ) ;
356
424
357
425
// Verify receipt of a published value from v2.
358
426
const value3 = Symbol . for ( 'value3' ) ;
359
427
await publish ( value3 ) ;
428
+ const expectedV2SecondResult = { value : value3 , done : false } ;
360
429
const v2SecondCells = [
361
430
await run ( 'awaitVatObject' , [ { presence : v2FirstCell . tail } ] ) ,
362
431
await run ( 'messageVatObject' , [
@@ -366,14 +435,18 @@ test('durable publish kit upgrade trauma (full-vat integration)', async t => {
366
435
{ presence : sub2 , methodName : 'subscribeAfter' } ,
367
436
] ) ,
368
437
] ;
369
- assertCells (
370
- t ,
371
- 'v2 second' ,
372
- v2SecondCells ,
373
- 3n ,
374
- { value : value3 , done : false } ,
375
- { strict : false } ,
376
- ) ;
438
+ const v2SecondIterationResults = {
439
+ eachIterator : await run ( 'messageVatObject' , [
440
+ { presence : eachIterator2 , methodName : 'next' } ,
441
+ ] ) ,
442
+ latestIterator : await run ( 'messageVatObject' , [
443
+ { presence : latestIterator1 , methodName : 'next' } ,
444
+ ] ) ,
445
+ } ;
446
+ assertCells ( t , 'v2 second' , v2SecondCells , 3n , expectedV2SecondResult , {
447
+ strict : false ,
448
+ iterationResults : v2SecondIterationResults ,
449
+ } ) ;
377
450
} ) ;
378
451
379
452
// TODO: Find a way to test virtual object rehydration
0 commit comments