diff --git a/tests/render.rs b/tests/render.rs index 056f968d..6c561cba 100644 --- a/tests/render.rs +++ b/tests/render.rs @@ -650,3 +650,127 @@ fn progress_style_tab_width_unification() { spinner.tick(); assert_eq!(in_mem.contents(), "OK OK"); } + +#[test] +fn multi_progress_clear_println() { + let in_mem = InMemoryTerm::new(10, 80); + let mp = + MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone()))); + + mp.println("Test of println").unwrap(); + // Should have no effect + mp.clear().unwrap(); + assert_eq!(in_mem.contents(), "Test of println"); +} + +#[test] +fn multi_progress_clear_zombies_no_ticks() { + _multi_progress_clear_zombies(0); +} + +#[test] +fn multi_progress_clear_zombies_one_tick() { + _multi_progress_clear_zombies(1); +} + +#[test] +fn multi_progress_clear_zombies_two_ticks() { + _multi_progress_clear_zombies(2); +} + +// In the old (broken) implementation, zombie handling sometimes worked differently depending on +// how many draws were between certain operations. Let's make sure that doesn't happen again. +fn _multi_progress_clear_zombies(ticks: usize) { + let in_mem = InMemoryTerm::new(10, 80); + let mp = + MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone()))); + let style = ProgressStyle::with_template("{msg}").unwrap(); + + let pb1 = mp.add( + ProgressBar::new_spinner() + .with_style(style.clone()) + .with_message("pb1"), + ); + pb1.tick(); + + let pb2 = mp.add( + ProgressBar::new_spinner() + .with_style(style) + .with_message("pb2"), + ); + + pb2.tick(); + assert_eq!(in_mem.contents(), "pb1\npb2"); + + pb1.finish_with_message("pb1 done"); + drop(pb1); + assert_eq!(in_mem.contents(), "pb1 done\npb2"); + + for _ in 0..ticks { + pb2.tick(); + } + + mp.clear().unwrap(); + assert_eq!(in_mem.contents(), ""); +} + +// This test reproduces examples/multi.rs in a simpler form +#[test] +fn multi_zombie_handling() { + let in_mem = InMemoryTerm::new(10, 80); + let mp = + MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone()))); + let style = ProgressStyle::with_template("{msg}").unwrap(); + + let pb1 = mp.add( + ProgressBar::new_spinner() + .with_style(style.clone()) + .with_message("pb1"), + ); + pb1.tick(); + let pb2 = mp.add( + ProgressBar::new_spinner() + .with_style(style.clone()) + .with_message("pb2"), + ); + pb2.tick(); + let pb3 = mp.add( + ProgressBar::new_spinner() + .with_style(style) + .with_message("pb3"), + ); + pb3.tick(); + + mp.println("pb1 done!").unwrap(); + pb1.finish_with_message("done"); + assert_eq!(in_mem.contents(), "pb1 done!\ndone\npb2\npb3"); + drop(pb1); + + assert_eq!(in_mem.contents(), "pb1 done!\ndone\npb2\npb3"); + + pb2.tick(); + assert_eq!(in_mem.contents(), "pb1 done!\ndone\npb2\npb3"); + pb3.tick(); + assert_eq!(in_mem.contents(), "pb1 done!\ndone\npb2\npb3"); + + mp.println("pb3 done!").unwrap(); + assert_eq!(in_mem.contents(), "pb1 done!\npb3 done!\npb2\npb3"); + + pb3.finish_with_message("done"); + drop(pb3); + + pb2.tick(); + + mp.println("pb2 done!").unwrap(); + pb2.finish_with_message("done"); + drop(pb2); + + assert_eq!( + in_mem.contents(), + "pb1 done!\npb3 done!\npb2 done!\ndone\ndone" + ); + + mp.clear().unwrap(); + + assert_eq!(in_mem.contents(), "pb1 done!\npb3 done!\npb2 done!"); +}