@@ -418,6 +418,68 @@ describe('Controller', () => {
418
418
expect ( loop ) . toBeCalledTimes ( 0 )
419
419
} )
420
420
} )
421
+
422
+ describe ( 'when "finish" is called while paused' , ( ) => {
423
+ async function getPausedLoop ( ) {
424
+ const ctrl = new Controller < { t : number } > ( {
425
+ from : { t : 0 } , // FIXME: replace this line with `t: 0,` for a stack overflow
426
+ loop : {
427
+ async to ( start ) {
428
+ await start ( {
429
+ t : 1 ,
430
+ reset : true ,
431
+ } )
432
+ } ,
433
+ } ,
434
+ } )
435
+
436
+ // Ensure `loop.to` has been called.
437
+ await flushMicroTasks ( )
438
+
439
+ // Apply the first frame.
440
+ mockRaf . step ( )
441
+
442
+ ctrl . pause ( )
443
+ return ctrl
444
+ }
445
+
446
+ it ( 'finishes immediately' , async ( ) => {
447
+ const ctrl = await getPausedLoop ( )
448
+ const { t } = ctrl . springs
449
+
450
+ expect ( t . get ( ) ) . toBeLessThan ( 1 )
451
+ t . finish ( )
452
+ expect ( t . get ( ) ) . toBe ( 1 )
453
+ } )
454
+
455
+ it ( 'does not loop until resumed' , async ( ) => {
456
+ const ctrl = await getPausedLoop ( )
457
+ const { t } = ctrl . springs
458
+
459
+ t . finish ( )
460
+ expect ( t . idle ) . toBeTruthy ( )
461
+ expect ( t . get ( ) ) . toBe ( 1 )
462
+
463
+ // HACK: The internal promise is undefined once resolved.
464
+ const expectResolved = ( isResolved : boolean ) =>
465
+ ! ctrl [ '_state' ] . promise == isResolved
466
+
467
+ // Resume the paused loop.
468
+ ctrl . resume ( )
469
+
470
+ // Its promise is not resolved yet..
471
+ expectResolved ( false )
472
+ expect ( t . idle ) . toBeTruthy ( )
473
+ expect ( t . get ( ) ) . toBe ( 1 )
474
+
475
+ // ..but in the next microtask, it will be..
476
+ await flushMicroTasks ( )
477
+ expectResolved ( true )
478
+ // ..which means the loop restarts!
479
+ expect ( t . idle ) . toBeFalsy ( )
480
+ expect ( t . get ( ) ) . toBe ( 0 )
481
+ } )
482
+ } )
421
483
} )
422
484
423
485
describe ( 'the "stop" method' , ( ) => {
0 commit comments