@@ -60,6 +60,84 @@ fn progress_bar_builder_method_order() {
60
60
) ;
61
61
}
62
62
63
+ #[ test]
64
+ fn multi_progress_single_bar_and_leave ( ) {
65
+ let in_mem = InMemoryTerm :: new ( 10 , 80 ) ;
66
+ let mp =
67
+ MultiProgress :: with_draw_target ( ProgressDrawTarget :: term_like ( Box :: new ( in_mem. clone ( ) ) ) ) ;
68
+
69
+ let pb1 = mp. add ( ProgressBar :: new ( 10 ) . with_finish ( ProgressFinish :: AndLeave ) ) ;
70
+
71
+ assert_eq ! ( in_mem. contents( ) , String :: new( ) ) ;
72
+
73
+ pb1. tick ( ) ;
74
+ assert_eq ! (
75
+ in_mem. contents( ) ,
76
+ r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
77
+ ) ;
78
+
79
+ drop ( pb1) ;
80
+ assert_eq ! (
81
+ in_mem. contents( ) ,
82
+ r#"██████████████████████████████████████████████████████████████████████████ 10/10"#
83
+ ) ;
84
+ }
85
+
86
+ #[ test]
87
+ fn multi_progress_single_bar_and_clear ( ) {
88
+ let in_mem = InMemoryTerm :: new ( 10 , 80 ) ;
89
+ let mp =
90
+ MultiProgress :: with_draw_target ( ProgressDrawTarget :: term_like ( Box :: new ( in_mem. clone ( ) ) ) ) ;
91
+
92
+ let pb1 = mp. add ( ProgressBar :: new ( 10 ) ) ;
93
+
94
+ assert_eq ! ( in_mem. contents( ) , String :: new( ) ) ;
95
+
96
+ pb1. tick ( ) ;
97
+ assert_eq ! (
98
+ in_mem. contents( ) ,
99
+ r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
100
+ ) ;
101
+
102
+ drop ( pb1) ;
103
+ assert_eq ! ( in_mem. contents( ) , "" ) ;
104
+ }
105
+ #[ test]
106
+ fn multi_progress_two_bars ( ) {
107
+ let in_mem = InMemoryTerm :: new ( 10 , 80 ) ;
108
+ let mp =
109
+ MultiProgress :: with_draw_target ( ProgressDrawTarget :: term_like ( Box :: new ( in_mem. clone ( ) ) ) ) ;
110
+
111
+ let pb1 = mp. add ( ProgressBar :: new ( 10 ) . with_finish ( ProgressFinish :: AndLeave ) ) ;
112
+ let pb2 = mp. add ( ProgressBar :: new ( 5 ) ) ;
113
+
114
+ assert_eq ! ( in_mem. contents( ) , String :: new( ) ) ;
115
+
116
+ pb1. tick ( ) ;
117
+ assert_eq ! (
118
+ in_mem. contents( ) ,
119
+ r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
120
+ ) ;
121
+
122
+ pb2. tick ( ) ;
123
+
124
+ assert_eq ! (
125
+ in_mem. contents( ) ,
126
+ r#"
127
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
128
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5"#
129
+ . trim_start( )
130
+ ) ;
131
+
132
+ drop ( pb1) ;
133
+ drop ( pb2) ;
134
+
135
+ assert_eq ! (
136
+ in_mem. contents( ) ,
137
+ r#"██████████████████████████████████████████████████████████████████████████ 10/10"#
138
+ ) ;
139
+ }
140
+
63
141
#[ test]
64
142
fn multi_progress ( ) {
65
143
let in_mem = InMemoryTerm :: new ( 10 , 80 ) ;
@@ -293,3 +371,166 @@ fn manually_inc_ticker() {
293
371
spinner. set_prefix ( "prefix" ) ;
294
372
assert_eq ! ( in_mem. contents( ) , "⠉ new message" ) ;
295
373
}
374
+
375
+ #[ test]
376
+ fn multi_progress_prune_zombies ( ) {
377
+ let in_mem = InMemoryTerm :: new ( 10 , 80 ) ;
378
+ let mp =
379
+ MultiProgress :: with_draw_target ( ProgressDrawTarget :: term_like ( Box :: new ( in_mem. clone ( ) ) ) ) ;
380
+
381
+ let pb0 = mp
382
+ . add ( ProgressBar :: new ( 10 ) )
383
+ . with_finish ( ProgressFinish :: AndLeave ) ;
384
+ let pb1 = mp. add ( ProgressBar :: new ( 15 ) ) ;
385
+ pb0. tick ( ) ;
386
+ assert_eq ! (
387
+ in_mem. contents( ) ,
388
+ "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"
389
+ ) ;
390
+
391
+ pb0. inc ( 1 ) ;
392
+ assert_eq ! (
393
+ in_mem. contents( ) ,
394
+ "███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/10"
395
+ ) ;
396
+
397
+ drop ( pb0) ;
398
+
399
+ // Clear the screen
400
+ in_mem. reset ( ) ;
401
+
402
+ // Write a line that we expect to remain. This helps ensure the adjustment to last_line_count is
403
+ // working as expected, and `MultiState` isn't erasing lines when it shouldn't.
404
+ in_mem. write_line ( "don't erase me plz" ) . unwrap ( ) ;
405
+
406
+ // pb0 is dead, so only pb1 should be drawn from now on
407
+ pb1. tick ( ) ;
408
+ assert_eq ! (
409
+ in_mem. contents( ) ,
410
+ "don't erase me plz\n ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/15"
411
+ ) ;
412
+ }
413
+
414
+ #[ test]
415
+ fn multi_progress_prune_zombies_2 ( ) {
416
+ let in_mem = InMemoryTerm :: new ( 10 , 80 ) ;
417
+ let mp =
418
+ MultiProgress :: with_draw_target ( ProgressDrawTarget :: term_like ( Box :: new ( in_mem. clone ( ) ) ) ) ;
419
+
420
+ let pb1 = mp. add ( ProgressBar :: new ( 10 ) . with_finish ( ProgressFinish :: AndLeave ) ) ;
421
+ let pb2 = mp. add ( ProgressBar :: new ( 5 ) ) ;
422
+ let pb3 = mp
423
+ . add ( ProgressBar :: new ( 100 ) )
424
+ . with_finish ( ProgressFinish :: Abandon ) ;
425
+ let pb4 = mp
426
+ . add ( ProgressBar :: new ( 500 ) )
427
+ . with_finish ( ProgressFinish :: AndLeave ) ;
428
+ let pb5 = mp. add ( ProgressBar :: new ( 7 ) ) ;
429
+
430
+ assert_eq ! ( in_mem. contents( ) , String :: new( ) ) ;
431
+
432
+ pb1. tick ( ) ;
433
+ assert_eq ! (
434
+ in_mem. contents( ) ,
435
+ r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
436
+ ) ;
437
+
438
+ pb2. tick ( ) ;
439
+
440
+ assert_eq ! (
441
+ in_mem. contents( ) ,
442
+ r#"
443
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
444
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5"#
445
+ . trim_start( )
446
+ ) ;
447
+
448
+ pb3. tick ( ) ;
449
+ assert_eq ! (
450
+ in_mem. contents( ) ,
451
+ r#"
452
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
453
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5
454
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
455
+ . trim_start( )
456
+ ) ;
457
+
458
+ drop ( pb1) ;
459
+ drop ( pb2) ;
460
+ drop ( pb3) ;
461
+
462
+ assert_eq ! (
463
+ in_mem. contents( ) ,
464
+ r#"
465
+ ██████████████████████████████████████████████████████████████████████████ 10/10
466
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
467
+ . trim_start( )
468
+ ) ;
469
+
470
+ in_mem. reset ( ) ;
471
+
472
+ // Another sacrificial line we expect shouldn't be touched
473
+ in_mem. write_line ( "don't erase plz" ) . unwrap ( ) ;
474
+
475
+ mp. println ( "Test friend :)" ) . unwrap ( ) ;
476
+ assert_eq ! (
477
+ in_mem. contents( ) ,
478
+ r#"
479
+ don't erase plz
480
+ Test friend :)"#
481
+ . trim_start( )
482
+ ) ;
483
+
484
+ pb4. tick ( ) ;
485
+ assert_eq ! (
486
+ in_mem. contents( ) ,
487
+ r#"
488
+ don't erase plz
489
+ Test friend :)
490
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/500"#
491
+ . trim_start( )
492
+ ) ;
493
+
494
+ drop ( pb4) ;
495
+
496
+ in_mem. reset ( ) ;
497
+ pb5. tick ( ) ;
498
+ assert_eq ! (
499
+ in_mem. contents( ) ,
500
+ "░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/7"
501
+ ) ;
502
+
503
+ mp. println ( "not your friend, buddy" ) . unwrap ( ) ;
504
+ assert_eq ! (
505
+ in_mem. contents( ) ,
506
+ r#"
507
+ not your friend, buddy
508
+ ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/7"#
509
+ . trim_start( )
510
+ ) ;
511
+
512
+ pb5. inc ( 1 ) ;
513
+ assert_eq ! (
514
+ in_mem. contents( ) ,
515
+ r#"
516
+ not your friend, buddy
517
+ ██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/7"#
518
+ . trim_start( )
519
+ ) ;
520
+
521
+ in_mem. reset ( ) ;
522
+ in_mem. write_line ( "don't erase me either" ) . unwrap ( ) ;
523
+
524
+ pb5. inc ( 1 ) ;
525
+ assert_eq ! (
526
+ in_mem. contents( ) ,
527
+ r#"
528
+ don't erase me either
529
+ █████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/7"#
530
+ . trim_start( )
531
+ ) ;
532
+
533
+ drop ( pb5) ;
534
+
535
+ assert_eq ! ( in_mem. contents( ) , "don't erase me either" ) ;
536
+ }
0 commit comments