1823 lines
53 KiB
Rust
1823 lines
53 KiB
Rust
#![cfg(feature = "in_memory")]
|
|
|
|
use std::time::Duration;
|
|
|
|
use indicatif::{
|
|
InMemoryTerm, MultiProgress, MultiProgressAlignment, ProgressBar, ProgressDrawTarget,
|
|
ProgressFinish, ProgressStyle, TermLike,
|
|
};
|
|
use pretty_assertions::assert_eq;
|
|
|
|
#[test]
|
|
fn basic_progress_bar() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let pb = ProgressBar::with_draw_target(
|
|
Some(10),
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
);
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"
|
|
);
|
|
|
|
pb.inc(1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/10"
|
|
);
|
|
|
|
pb.finish();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"██████████████████████████████████████████████████████████████████████████ 10/10"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn progress_bar_builder_method_order() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
// Test that `with_style` doesn't overwrite the message or prefix
|
|
let pb = ProgressBar::with_draw_target(
|
|
Some(10),
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
)
|
|
.with_message("crate")
|
|
.with_prefix("Downloading")
|
|
.with_style(
|
|
ProgressStyle::with_template("{prefix:>12.cyan.bold} {msg}: {wide_bar} {pos}/{len}")
|
|
.unwrap(),
|
|
);
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
" Downloading crate: ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn progress_bar_percent_with_no_length() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let pb = ProgressBar::with_draw_target(
|
|
None,
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
)
|
|
.with_style(ProgressStyle::with_template("{wide_bar} {percent}%").unwrap());
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb.tick();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0%"
|
|
);
|
|
|
|
pb.set_length(10);
|
|
|
|
pb.inc(1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 10%"
|
|
);
|
|
|
|
pb.finish();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"███████████████████████████████████████████████████████████████████████████ 100%"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_single_bar_and_leave() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave));
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
|
|
drop(pb1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"██████████████████████████████████████████████████████████████████████████ 10/10"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_single_bar_and_clear() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10));
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
|
|
drop(pb1);
|
|
assert_eq!(in_mem.contents(), "");
|
|
}
|
|
#[test]
|
|
fn multi_progress_two_bars() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave));
|
|
let pb2 = mp.add(ProgressBar::new(5));
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
|
|
pb2.tick();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
██████████████████████████████████████████████████████████████████████████ 10/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb2);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"██████████████████████████████████████████████████████████████████████████ 10/10"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave));
|
|
let pb2 = mp.add(ProgressBar::new(5));
|
|
let pb3 = mp.add(ProgressBar::new(100));
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
|
|
pb2.tick();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5"#
|
|
.trim_start()
|
|
);
|
|
|
|
pb3.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
██████████████████████████████████████████████████████████████████████████ 10/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb2);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
██████████████████████████████████████████████████████████████████████████ 10/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb3);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"██████████████████████████████████████████████████████████████████████████ 10/10"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_println() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10));
|
|
let pb2 = mp.add(ProgressBar::new(5));
|
|
let pb3 = mp.add(ProgressBar::new(100));
|
|
|
|
assert_eq!(in_mem.contents(), "");
|
|
|
|
pb1.inc(2);
|
|
mp.println("message printed :)").unwrap();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
mp.println("another great message!").unwrap();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
another great message!
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb2.inc(1);
|
|
pb3.tick();
|
|
mp.println("one last message").unwrap();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
another great message!
|
|
one last message
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/5
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
drop(pb1);
|
|
drop(pb2);
|
|
drop(pb3);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
another great message!
|
|
one last message"#
|
|
.trim()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_suspend() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10));
|
|
let pb2 = mp.add(ProgressBar::new(10));
|
|
|
|
assert_eq!(in_mem.contents(), "");
|
|
|
|
pb1.inc(2);
|
|
mp.println("message printed :)").unwrap();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
mp.suspend(|| {
|
|
in_mem.write_line("This is write_line output!").unwrap();
|
|
in_mem.write_line("And so is this").unwrap();
|
|
in_mem.move_cursor_down(1).unwrap();
|
|
});
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
This is write_line output!
|
|
And so is this
|
|
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb2.inc(1);
|
|
mp.println("Another line printed").unwrap();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
This is write_line output!
|
|
And so is this
|
|
|
|
Another line printed
|
|
███████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/10
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
drop(pb1);
|
|
drop(pb2);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
message printed :)
|
|
This is write_line output!
|
|
And so is this
|
|
|
|
Another line printed"#
|
|
.trim()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn ticker_drop() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let mut spinner: Option<ProgressBar> = None;
|
|
|
|
for i in 0..5 {
|
|
let new_spinner = mp.add(
|
|
ProgressBar::new_spinner()
|
|
.with_finish(ProgressFinish::AndLeave)
|
|
.with_message(format!("doing stuff {i}")),
|
|
);
|
|
new_spinner.enable_steady_tick(Duration::from_millis(100));
|
|
spinner.replace(new_spinner);
|
|
}
|
|
|
|
drop(spinner);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
" doing stuff 0\n doing stuff 1\n doing stuff 2\n doing stuff 3\n doing stuff 4"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn manually_inc_ticker() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let spinner = mp.add(ProgressBar::new_spinner().with_message("msg"));
|
|
|
|
assert_eq!(in_mem.contents(), "");
|
|
|
|
spinner.inc(1);
|
|
assert_eq!(in_mem.contents(), "⠁ msg");
|
|
|
|
spinner.inc(1);
|
|
assert_eq!(in_mem.contents(), "⠉ msg");
|
|
|
|
// set_message / set_prefix shouldn't increase tick
|
|
spinner.set_message("new message");
|
|
spinner.set_prefix("prefix");
|
|
assert_eq!(in_mem.contents(), "⠉ new message");
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_prune_zombies() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb0 = mp
|
|
.add(ProgressBar::new(10))
|
|
.with_finish(ProgressFinish::AndLeave);
|
|
let pb1 = mp.add(ProgressBar::new(15));
|
|
pb0.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"
|
|
);
|
|
|
|
pb0.inc(1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/10"
|
|
);
|
|
|
|
drop(pb0);
|
|
|
|
// Clear the screen
|
|
mp.clear().unwrap();
|
|
|
|
// Write a line that we expect to remain. This helps ensure the adjustment to last_line_count is
|
|
// working as expected, and `MultiState` isn't erasing lines when it shouldn't.
|
|
in_mem.write_line("don't erase me plz").unwrap();
|
|
|
|
// pb0 is dead, so only pb1 should be drawn from now on
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"don't erase me plz\n░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/15"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_prune_zombies_2() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave));
|
|
let pb2 = mp.add(ProgressBar::new(5));
|
|
let pb3 = mp
|
|
.add(ProgressBar::new(100))
|
|
.with_finish(ProgressFinish::Abandon);
|
|
let pb4 = mp
|
|
.add(ProgressBar::new(500))
|
|
.with_finish(ProgressFinish::AndLeave);
|
|
let pb5 = mp.add(ProgressBar::new(7));
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
|
|
pb2.tick();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5"#
|
|
.trim_start()
|
|
);
|
|
|
|
pb3.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/5
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb1);
|
|
drop(pb2);
|
|
drop(pb3);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
██████████████████████████████████████████████████████████████████████████ 10/10
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
|
|
.trim_start()
|
|
);
|
|
|
|
mp.clear().unwrap();
|
|
|
|
assert_eq!(in_mem.contents(), "");
|
|
|
|
// A sacrificial line we expect shouldn't be touched
|
|
in_mem.write_line("don't erase plz").unwrap();
|
|
|
|
mp.println("Test friend :)").unwrap();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)"#
|
|
.trim_start()
|
|
);
|
|
|
|
pb4.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/500"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb4);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
████████████████████████████████████████████████████████████████████████ 500/500"#
|
|
.trim_start()
|
|
);
|
|
|
|
mp.clear().unwrap();
|
|
assert_eq!(in_mem.contents(), "don't erase plz\nTest friend :)");
|
|
|
|
pb5.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/7"#
|
|
.trim_start()
|
|
);
|
|
|
|
mp.println("not your friend, buddy").unwrap();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
not your friend, buddy
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/7"#
|
|
.trim_start()
|
|
);
|
|
|
|
pb5.inc(1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
not your friend, buddy
|
|
██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/7"#
|
|
.trim_start()
|
|
);
|
|
|
|
mp.clear().unwrap();
|
|
in_mem.write_line("don't erase me either").unwrap();
|
|
|
|
pb5.inc(1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
not your friend, buddy
|
|
don't erase me either
|
|
█████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/7"#
|
|
.trim_start()
|
|
);
|
|
|
|
drop(pb5);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
don't erase plz
|
|
Test friend :)
|
|
not your friend, buddy
|
|
don't erase me either"#
|
|
.trim_start()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn basic_tab_expansion() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let mut spinner = mp.add(ProgressBar::new_spinner().with_message("Test\t:)"));
|
|
spinner.tick();
|
|
|
|
// 8 is the default number of spaces
|
|
assert_eq!(in_mem.contents(), "⠁ Test :)");
|
|
|
|
spinner.set_tab_width(4);
|
|
assert_eq!(in_mem.contents(), "⠁ Test :)");
|
|
}
|
|
|
|
#[test]
|
|
fn tab_expansion_in_template() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let mut spinner = mp.add(
|
|
ProgressBar::new_spinner()
|
|
.with_message("Test\t:)")
|
|
.with_prefix("Pre\tfix!")
|
|
.with_style(ProgressStyle::with_template("{spinner}{prefix}\t{msg}").unwrap()),
|
|
);
|
|
|
|
spinner.tick();
|
|
assert_eq!(in_mem.contents(), "⠁Pre fix! Test :)");
|
|
|
|
spinner.set_tab_width(4);
|
|
assert_eq!(in_mem.contents(), "⠁Pre fix! Test :)");
|
|
|
|
spinner.set_tab_width(2);
|
|
assert_eq!(in_mem.contents(), "⠁Pre fix! Test :)");
|
|
}
|
|
|
|
#[test]
|
|
fn progress_style_tab_width_unification() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
// Style will have default of 8 spaces for tabs
|
|
let style = ProgressStyle::with_template("{msg}\t{msg}").unwrap();
|
|
|
|
let spinner = mp.add(
|
|
ProgressBar::new_spinner()
|
|
.with_message("OK")
|
|
.with_tab_width(4),
|
|
);
|
|
|
|
// Setting the spinner's style to |style| should override the style's tab width with that of bar
|
|
spinner.set_style(style);
|
|
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!");
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_multiline_msg() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new_spinner().with_message("test1"));
|
|
let pb2 = mp.add(ProgressBar::new_spinner().with_message("test2"));
|
|
|
|
assert_eq!(in_mem.contents(), "");
|
|
|
|
pb1.inc(1);
|
|
pb2.inc(1);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
⠁ test1
|
|
⠁ test2
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb1.set_message("test1\n test1 line2\n test1 line3");
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
⠁ test1
|
|
test1 line2
|
|
test1 line3
|
|
⠁ test2
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb1.inc(1);
|
|
pb2.inc(1);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
⠉ test1
|
|
test1 line2
|
|
test1 line3
|
|
⠉ test2
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb2.set_message("test2\n test2 line2");
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
⠉ test1
|
|
test1 line2
|
|
test1 line3
|
|
⠉ test2
|
|
test2 line2
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb1.set_message("single line again");
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
⠉ single line again
|
|
⠉ test2
|
|
test2 line2
|
|
"#
|
|
.trim()
|
|
);
|
|
|
|
pb1.finish_with_message("test1 done!");
|
|
pb2.finish_with_message("test2 done!");
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#" test1 done!
|
|
test2 done!"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_bottom_alignment() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
mp.set_alignment(MultiProgressAlignment::Bottom);
|
|
|
|
let pb1 = mp.add(ProgressBar::new_spinner().with_message("test1"));
|
|
let pb2 = mp.add(ProgressBar::new_spinner().with_message("test2"));
|
|
|
|
pb1.tick();
|
|
pb2.tick();
|
|
pb1.finish_and_clear();
|
|
|
|
assert_eq!(in_mem.contents(), "\n⠁ test2");
|
|
|
|
pb2.finish_and_clear();
|
|
// `InMemoryTerm::contents` normally gets rid of trailing newlines, so write some text to ensure
|
|
// the newlines are seen.
|
|
in_mem.write_line("anchor").unwrap();
|
|
assert_eq!(in_mem.contents(), "\n\nanchor");
|
|
}
|
|
|
|
#[test]
|
|
fn progress_bar_terminal_wrap() {
|
|
use std::cmp::min;
|
|
let in_mem = InMemoryTerm::new(10, 20);
|
|
|
|
let mut downloaded = 0;
|
|
let total_size = 231231231;
|
|
|
|
let pb = ProgressBar::with_draw_target(
|
|
None,
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
);
|
|
pb.set_style(ProgressStyle::default_bar()
|
|
.template("{msg:>12.cyan.bold} {spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {bytes}/{total_bytes}").unwrap()
|
|
.progress_chars("#>-"));
|
|
|
|
pb.set_message("Downloading");
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#" Downloading ⠁ [00:0
|
|
0:00] [-------------
|
|
--------------------
|
|
-------] 0 B/0 B"#
|
|
);
|
|
|
|
let new = min(downloaded + 223211, total_size);
|
|
downloaded = new;
|
|
pb.set_position(new);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#" Downloading ⠁ [00:0
|
|
0:00] [-------------
|
|
--------------------
|
|
-------] 217.98 KiB/
|
|
217.98 KiB"#
|
|
);
|
|
|
|
let new = min(downloaded + 223211, total_size);
|
|
pb.set_position(new);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#" Downloading ⠉ [00:0
|
|
0:00] [-------------
|
|
--------------------
|
|
-------] 435.96 KiB/
|
|
435.96 KiB"#
|
|
);
|
|
|
|
pb.set_style(
|
|
ProgressStyle::default_bar()
|
|
.template("{msg:>12.green.bold} downloading {total_bytes:.green} in {elapsed:.green}")
|
|
.unwrap(),
|
|
);
|
|
pb.finish_with_message("Finished");
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#" Finished downloa
|
|
ding 435.96 KiB in 0
|
|
s"#
|
|
);
|
|
|
|
println!("{:?}", in_mem.contents())
|
|
}
|
|
|
|
#[test]
|
|
fn spinner_terminal_cleared_log_line_with_ansi_codes() {
|
|
let in_mem = InMemoryTerm::new(10, 100);
|
|
|
|
let pb = ProgressBar::with_draw_target(
|
|
Some(10),
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
);
|
|
pb.set_style(ProgressStyle::default_spinner());
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb.finish_and_clear();
|
|
// Visually empty, but consists of an ANSII code
|
|
pb.println("\u{1b}[1m");
|
|
|
|
pb.println("text\u{1b}[0m");
|
|
assert_eq!(in_mem.contents(), "\ntext");
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_println_terminal_wrap() {
|
|
let in_mem = InMemoryTerm::new(10, 48);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10));
|
|
let pb2 = mp.add(ProgressBar::new(5));
|
|
let pb3 = mp.add(ProgressBar::new(100));
|
|
|
|
assert_eq!(in_mem.contents(), "");
|
|
|
|
pb1.inc(2);
|
|
mp.println("message printed that is longer than terminal width :)")
|
|
.unwrap();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"message printed that is longer than terminal wid
|
|
th :)
|
|
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10"#
|
|
);
|
|
|
|
mp.println("another great message!").unwrap();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"message printed that is longer than terminal wid
|
|
th :)
|
|
another great message!
|
|
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10"#
|
|
);
|
|
|
|
pb2.inc(1);
|
|
pb3.tick();
|
|
mp.println("one last message but this one is also longer than terminal width")
|
|
.unwrap();
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"message printed that is longer than terminal wid
|
|
th :)
|
|
another great message!
|
|
one last message but this one is also longer tha
|
|
n terminal width
|
|
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 2/10
|
|
████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/5
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/100"#
|
|
.trim()
|
|
);
|
|
|
|
drop(pb1);
|
|
drop(pb2);
|
|
drop(pb3);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"message printed that is longer than terminal wid
|
|
th :)
|
|
another great message!
|
|
one last message but this one is also longer tha
|
|
n terminal width"#
|
|
.trim()
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn basic_progress_bar_newline() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
let pb = ProgressBar::with_draw_target(
|
|
Some(10),
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
);
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb.println("\nhello");
|
|
pb.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
hello
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
|
|
pb.inc(1);
|
|
pb.println("");
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
hello
|
|
|
|
███████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 1/10"#
|
|
);
|
|
|
|
pb.finish();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
"
|
|
hello
|
|
|
|
██████████████████████████████████████████████████████████████████████████ 10/10"
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_many_bars() {
|
|
let in_mem = InMemoryTerm::new(4, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave));
|
|
let mut spinners = vec![];
|
|
for i in 0..7 {
|
|
let spinner = ProgressBar::new_spinner().with_message(i.to_string());
|
|
mp.add(spinner.clone());
|
|
spinners.push(spinner);
|
|
}
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
for spinner in &spinners {
|
|
spinner.tick()
|
|
}
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
⠁ 0
|
|
⠁ 1
|
|
⠁ 2"#
|
|
.trim_start()
|
|
);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Clear
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str(" ")
|
|
Flush
|
|
Up(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(1)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str(" ")
|
|
Flush
|
|
Up(2)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(2)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str(" ")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
drop(pb1);
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
██████████████████████████████████████████████████████████████████████████ 10/10
|
|
⠁ 0
|
|
⠁ 1
|
|
⠁ 2"#
|
|
.trim_start()
|
|
);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("██████████████████████████████████████████████████████████████████████████ 10/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
drop(spinners);
|
|
|
|
assert_eq!(in_mem.contents(), r#""#);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Up(2)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(2)
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 3")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 4")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("⠁ 2")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 3")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 4")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 5")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("⠁ 3")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 4")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 5")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("⠁ 4")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 5")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Up(2)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(2)
|
|
Str("⠁ 5")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Up(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(1)
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Clear
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn multi_progress_many_spinners() {
|
|
let in_mem = InMemoryTerm::new(4, 80);
|
|
let mp =
|
|
MultiProgress::with_draw_target(ProgressDrawTarget::term_like(Box::new(in_mem.clone())));
|
|
|
|
let pb1 = mp.add(ProgressBar::new(10).with_finish(ProgressFinish::AndLeave));
|
|
let mut spinners = vec![];
|
|
for i in 0..7 {
|
|
let spinner = ProgressBar::new_spinner().with_message(i.to_string());
|
|
mp.add(spinner.clone());
|
|
spinners.push(spinner);
|
|
}
|
|
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
pb1.tick();
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
for spinner in &spinners {
|
|
spinner.tick()
|
|
}
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
⠁ 0
|
|
⠁ 1
|
|
⠁ 2"#
|
|
.trim_start()
|
|
);
|
|
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Clear
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str(" ")
|
|
Flush
|
|
Up(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(1)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str(" ")
|
|
Flush
|
|
Up(2)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(2)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str(" ")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
spinners.remove(3);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
⠁ 0
|
|
⠁ 1
|
|
⠁ 2"#
|
|
.trim_start()
|
|
);
|
|
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
spinners.remove(4);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"
|
|
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10
|
|
⠁ 0
|
|
⠁ 1
|
|
⠁ 2"#
|
|
.trim_start()
|
|
);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 0")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
|
|
drop(spinners);
|
|
|
|
assert_eq!(
|
|
in_mem.contents(),
|
|
r#"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10"#
|
|
);
|
|
assert_eq!(
|
|
in_mem.moves_since_last_check(),
|
|
r#"Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 1")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 4")
|
|
Str("")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 2")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 4")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Up(3)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(3)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 4")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Up(2)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(2)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
NewLine
|
|
Str("⠁ 6")
|
|
Str(" ")
|
|
Flush
|
|
Up(1)
|
|
Clear
|
|
Down(1)
|
|
Clear
|
|
Up(1)
|
|
Str("░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 0/10")
|
|
Str("")
|
|
Flush
|
|
"#
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn orphan_lines() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
|
|
let pb = ProgressBar::with_draw_target(
|
|
Some(10),
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
);
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
for i in 0..=10 {
|
|
if i != 0 {
|
|
pb.inc(1);
|
|
}
|
|
|
|
let n = 5 + i;
|
|
|
|
pb.println("\n".repeat(n));
|
|
}
|
|
|
|
pb.finish();
|
|
}
|
|
|
|
#[test]
|
|
fn orphan_lines_message_above_progress_bar() {
|
|
let in_mem = InMemoryTerm::new(10, 80);
|
|
|
|
let pb = ProgressBar::with_draw_target(
|
|
Some(10),
|
|
ProgressDrawTarget::term_like(Box::new(in_mem.clone())),
|
|
);
|
|
assert_eq!(in_mem.contents(), String::new());
|
|
|
|
for i in 0..=10 {
|
|
if i != 0 {
|
|
pb.inc(1);
|
|
}
|
|
|
|
let n = 5 + i;
|
|
|
|
// Test with messages of differing numbers of lines. The messages have the form:
|
|
// n - 1 newlines followed by n * 11 dashes (`-`). The value of n ranges from 5
|
|
// (less than the terminal height) to 15 (greater than the terminal height). The
|
|
// number 11 is intentionally not a factor of the terminal width (80), but large
|
|
// enough that the strings of dashes eventually wrap.
|
|
pb.println(format!("{}{}", "\n".repeat(n - 1), "-".repeat(n * 11)));
|
|
|
|
// Check that the line above the progress bar is a string of dashes of length
|
|
// n * 11 mod the terminal width.
|
|
assert_eq!(
|
|
format!("{}", "-".repeat(n * 11 % 80)),
|
|
in_mem.contents().lines().rev().nth(1).unwrap(),
|
|
);
|
|
}
|
|
|
|
pb.finish();
|
|
}
|