Skip to content

Commit

Permalink
Move visual_line_count and associated test to draw_target.rs
Browse files Browse the repository at this point in the history
  • Loading branch information
smoelius authored and chris-laplante committed Dec 23, 2023
1 parent 3bf0fe0 commit e06ce68
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 100 deletions.
99 changes: 99 additions & 0 deletions src/draw_target.rs
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,18 @@ impl DrawState {
}
}

/// Calculate the number of visual lines in the given lines, after
/// accounting for line wrapping and non-printable characters.
pub(crate) fn visual_line_count(lines: &[impl AsRef<str>], width: f64) -> usize {
let mut real_lines = 0;
for line in lines {
let effective_line_length = console::measure_text_width(line.as_ref()) as f64;
real_lines += usize::max((effective_line_length / width).ceil() as usize, 1);
}

real_lines
}

#[cfg(test)]
mod tests {
use crate::{MultiProgress, ProgressBar, ProgressDrawTarget};
Expand All @@ -559,4 +571,91 @@ mod tests {
assert!(mp.is_hidden());
assert!(pb.is_hidden());
}

#[test]
fn real_line_count_test() {
#[derive(Debug)]
struct Case {
lines: &'static [&'static str],
expectation: usize,
width: f64,
}

let lines_and_expectations = [
Case {
lines: &["1234567890"],
expectation: 1,
width: 10.0,
},
Case {
lines: &["1234567890"],
expectation: 2,
width: 5.0,
},
Case {
lines: &["1234567890"],
expectation: 3,
width: 4.0,
},
Case {
lines: &["1234567890"],
expectation: 4,
width: 3.0,
},
Case {
lines: &["1234567890", "", "1234567890"],
expectation: 3,
width: 10.0,
},
Case {
lines: &["1234567890", "", "1234567890"],
expectation: 5,
width: 5.0,
},
Case {
lines: &["1234567890", "", "1234567890"],
expectation: 7,
width: 4.0,
},
Case {
lines: &["aaaaaaaaaaaaa", "", "bbbbbbbbbbbbbbbbb", "", "ccccccc"],
expectation: 8,
width: 7.0,
},
Case {
lines: &["", "", "", "", ""],
expectation: 5,
width: 6.0,
},
Case {
// These lines contain only ANSI escape sequences, so they should only count as 1 line
lines: &["\u{1b}[1m\u{1b}[1m\u{1b}[1m", "\u{1b}[1m\u{1b}[1m\u{1b}[1m"],
expectation: 2,
width: 5.0,
},
Case {
// These lines contain ANSI escape sequences and two effective chars, so they should only count as 1 line still
lines: &[
"a\u{1b}[1m\u{1b}[1m\u{1b}[1ma",
"a\u{1b}[1m\u{1b}[1m\u{1b}[1ma",
],
expectation: 2,
width: 5.0,
},
Case {
// These lines contain ANSI escape sequences and six effective chars, so they should count as 2 lines each
lines: &[
"aa\u{1b}[1m\u{1b}[1m\u{1b}[1mabcd",
"aa\u{1b}[1m\u{1b}[1m\u{1b}[1mabcd",
],
expectation: 4,
width: 5.0,
},
];

for case in lines_and_expectations.iter() {
let result = super::visual_line_count(case.lines, case.width);
assert_eq!(result, case.expectation, "case: {:?}", case);
}
}
}
103 changes: 3 additions & 100 deletions src/multi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use std::thread::panicking;
#[cfg(not(target_arch = "wasm32"))]
use std::time::Instant;

use crate::draw_target::{DrawState, DrawStateWrapper, LineAdjust, ProgressDrawTarget};
use crate::draw_target::{
visual_line_count, DrawState, DrawStateWrapper, LineAdjust, ProgressDrawTarget,
};
use crate::progress_bar::ProgressBar;
#[cfg(target_arch = "wasm32")]
use instant::Instant;
Expand Down Expand Up @@ -519,18 +521,6 @@ enum InsertLocation {
Before(usize),
}

/// Calculate the number of visual lines in the given lines, after
/// accounting for line wrapping and non-printable characters.
fn visual_line_count(lines: &[impl AsRef<str>], width: f64) -> usize {
let mut real_lines = 0;
for line in lines {
let effective_line_length = console::measure_text_width(line.as_ref()) as f64;
real_lines += usize::max((effective_line_length / width).ceil() as usize, 1);
}

real_lines
}

#[cfg(test)]
mod tests {
use crate::{MultiProgress, ProgressBar, ProgressDrawTarget};
Expand Down Expand Up @@ -702,91 +692,4 @@ mod tests {
let pb = mp.add(ProgressBar::new(10));
mp.add(pb);
}

#[test]
fn real_line_count_test() {
#[derive(Debug)]
struct Case {
lines: &'static [&'static str],
expectation: usize,
width: f64,
}

let lines_and_expectations = [
Case {
lines: &["1234567890"],
expectation: 1,
width: 10.0,
},
Case {
lines: &["1234567890"],
expectation: 2,
width: 5.0,
},
Case {
lines: &["1234567890"],
expectation: 3,
width: 4.0,
},
Case {
lines: &["1234567890"],
expectation: 4,
width: 3.0,
},
Case {
lines: &["1234567890", "", "1234567890"],
expectation: 3,
width: 10.0,
},
Case {
lines: &["1234567890", "", "1234567890"],
expectation: 5,
width: 5.0,
},
Case {
lines: &["1234567890", "", "1234567890"],
expectation: 7,
width: 4.0,
},
Case {
lines: &["aaaaaaaaaaaaa", "", "bbbbbbbbbbbbbbbbb", "", "ccccccc"],
expectation: 8,
width: 7.0,
},
Case {
lines: &["", "", "", "", ""],
expectation: 5,
width: 6.0,
},
Case {
// These lines contain only ANSI escape sequences, so they should only count as 1 line
lines: &["\u{1b}[1m\u{1b}[1m\u{1b}[1m", "\u{1b}[1m\u{1b}[1m\u{1b}[1m"],
expectation: 2,
width: 5.0,
},
Case {
// These lines contain ANSI escape sequences and two effective chars, so they should only count as 1 line still
lines: &[
"a\u{1b}[1m\u{1b}[1m\u{1b}[1ma",
"a\u{1b}[1m\u{1b}[1m\u{1b}[1ma",
],
expectation: 2,
width: 5.0,
},
Case {
// These lines contain ANSI escape sequences and six effective chars, so they should count as 2 lines each
lines: &[
"aa\u{1b}[1m\u{1b}[1m\u{1b}[1mabcd",
"aa\u{1b}[1m\u{1b}[1m\u{1b}[1mabcd",
],
expectation: 4,
width: 5.0,
},
];

for case in lines_and_expectations.iter() {
let result = super::visual_line_count(case.lines, case.width);
assert_eq!(result, case.expectation, "case: {:?}", case);
}
}
}

0 comments on commit e06ce68

Please sign in to comment.