Skip to content

Commit 27e3190

Browse files
committed
[nextest-runner] use Unicode characters if available
Nextest has rigorously followed Cargo's theming so far -- but I think it's time to start breaking from that a bit. An easy change is to use Unicode hbar and progress characters.
1 parent 177bdba commit 27e3190

File tree

4 files changed

+61
-12
lines changed

4 files changed

+61
-12
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

integration-tests/tests/integration/fixtures.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -322,11 +322,11 @@ impl CheckResult {
322322
vec![
323323
(
324324
"stdout",
325-
Regex::new(&format!("---- STDOUT: +{name}")).unwrap(),
325+
Regex::new(&format!("──── STDOUT: +{name}")).unwrap(),
326326
),
327327
(
328328
"stderr",
329-
Regex::new(&format!("---- STDERR: +{name}")).unwrap(),
329+
Regex::new(&format!("──── STDERR: +{name}")).unwrap(),
330330
),
331331
]
332332
}

nextest-runner/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ shell-words.workspace = true
6060
smallvec.workspace = true
6161
smol_str = { workspace = true, features = ["serde"] }
6262
strip-ansi-escapes.workspace = true
63+
supports-unicode.workspace = true
6364
swrite.workspace = true
6465
tar.workspace = true
6566
# For cfg expression evaluation for [target.'cfg()'] expressions

nextest-runner/src/reporter/displayer.rs

Lines changed: 57 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,19 @@ impl TestReporterBuilder {
254254
false => self.failure_output,
255255
};
256256

257+
let mut theme_characters = ThemeCharacters::default();
258+
match output {
259+
ReporterStderr::Terminal => {
260+
if supports_unicode::on(supports_unicode::Stream::Stderr) {
261+
theme_characters.use_unicode();
262+
}
263+
}
264+
ReporterStderr::Buffer(_) => {
265+
// Always use Unicode for internal buffers.
266+
theme_characters.use_unicode();
267+
}
268+
}
269+
257270
let stderr = match output {
258271
ReporterStderr::Terminal if self.no_capture => {
259272
// Do not use a progress bar if --no-capture is passed in. This is required since we
@@ -286,12 +299,12 @@ impl TestReporterBuilder {
286299
// but that isn't possible due to https://github.com/console-rs/indicatif/issues/440. Use
287300
// {{elapsed_precise}} as an OK tradeoff here.
288301
let template = format!(
289-
"{{prefix:>12}} [{{elapsed_precise:>9}}] [{{wide_bar}}] \
302+
"{{prefix:>12}} [{{elapsed_precise:>9}}] {{wide_bar}} \
290303
{{pos:>{test_count_width}}}/{{len:{test_count_width}}}: {{msg}} "
291304
);
292305
bar.set_style(
293306
ProgressStyle::default_bar()
294-
.progress_chars("=> ")
307+
.progress_chars(theme_characters.progress_chars)
295308
.template(&template)
296309
.expect("template is known to be valid"),
297310
);
@@ -328,6 +341,7 @@ impl TestReporterBuilder {
328341
force_failure_output,
329342
no_capture: self.no_capture,
330343
styles,
344+
theme_characters,
331345
cancel_status: None,
332346
final_outputs: DebugIgnore(vec![]),
333347
display_empty_outputs,
@@ -641,6 +655,7 @@ struct TestReporterImpl<'a> {
641655
force_failure_output: Option<TestOutputDisplay>,
642656
no_capture: bool,
643657
styles: Box<Styles>,
658+
theme_characters: ThemeCharacters,
644659
cancel_status: Option<CancelReason>,
645660
final_outputs: DebugIgnore<Vec<(TestInstance<'a>, FinalOutput)>>,
646661
display_empty_outputs: bool,
@@ -659,7 +674,7 @@ impl<'a> TestReporterImpl<'a> {
659674
profile_name,
660675
cli_args: _,
661676
} => {
662-
writeln!(writer, "------------")?;
677+
writeln!(writer, "{}", self.theme_characters.hbar(12))?;
663678
write!(writer, "{:>12} ", "Nextest run".style(self.styles.pass))?;
664679
writeln!(
665680
writer,
@@ -1025,7 +1040,8 @@ impl<'a> TestReporterImpl<'a> {
10251040
};
10261041
write!(
10271042
writer,
1028-
"------------\n{:>12} ",
1043+
"{}\n{:>12} ",
1044+
self.theme_characters.hbar(12),
10291045
"Summary".style(summary_style)
10301046
)?;
10311047

@@ -1363,10 +1379,12 @@ impl<'a> TestReporterImpl<'a> {
13631379
(self.styles.fail, self.styles.fail_output)
13641380
};
13651381

1382+
let hbar = self.theme_characters.hbar(4);
1383+
13661384
let stdout_header = {
13671385
format!(
13681386
"{} {:19} {}",
1369-
"---- ".style(header_style),
1387+
hbar.style(header_style),
13701388
"STDOUT:".style(header_style),
13711389
self.display_script_instance(script_id.clone(), command, args),
13721390
)
@@ -1375,7 +1393,7 @@ impl<'a> TestReporterImpl<'a> {
13751393
let stderr_header = {
13761394
format!(
13771395
"{} {:19} {}",
1378-
"---- ".style(header_style),
1396+
hbar.style(header_style),
13791397
"STDERR:".style(header_style),
13801398
self.display_script_instance(script_id.clone(), command, args),
13811399
)
@@ -1425,6 +1443,8 @@ impl<'a> TestReporterImpl<'a> {
14251443
(self.styles.fail, self.styles.fail_output)
14261444
};
14271445

1446+
let hbar = self.theme_characters.hbar(4);
1447+
14281448
match &run_status.output {
14291449
TestExecutionOutput::Output(output) => {
14301450
let description = if self.styles.is_colorized {
@@ -1435,7 +1455,7 @@ impl<'a> TestReporterImpl<'a> {
14351455

14361456
let stdout_header = {
14371457
let mut header = String::new();
1438-
swrite!(header, "{}", "---- ".style(header_style));
1458+
swrite!(header, "{} ", hbar.style(header_style));
14391459
let out_len = self.write_attempt(run_status, header_style, &mut header);
14401460
// The width is to align test instances.
14411461
swrite!(
@@ -1450,7 +1470,7 @@ impl<'a> TestReporterImpl<'a> {
14501470

14511471
let stderr_header = {
14521472
let mut header = String::new();
1453-
swrite!(header, "{}", "---- ".style(header_style));
1473+
swrite!(header, "{} ", hbar.style(header_style));
14541474
let out_len = self.write_attempt(run_status, header_style, &mut header);
14551475
// The width is to align test instances.
14561476
swrite!(
@@ -1465,7 +1485,7 @@ impl<'a> TestReporterImpl<'a> {
14651485

14661486
let combined_header = {
14671487
let mut header = String::new();
1468-
swrite!(header, "{}", "---- ".style(header_style));
1488+
swrite!(header, "{} ", hbar.style(header_style));
14691489
let out_len = self.write_attempt(run_status, header_style, &mut header);
14701490
// The width is to align test instances.
14711491
swrite!(
@@ -1491,7 +1511,7 @@ impl<'a> TestReporterImpl<'a> {
14911511
TestExecutionOutput::ExecFail { description, .. } => {
14921512
let exec_fail_header = {
14931513
let mut header = String::new();
1494-
swrite!(header, "{}", "---- ".style(header_style));
1514+
swrite!(header, "{} ", hbar.style(header_style));
14951515
let out_len = self.write_attempt(run_status, header_style, &mut header);
14961516
// The width is to align test instances.
14971517
swrite!(
@@ -2027,6 +2047,33 @@ impl Styles {
20272047
}
20282048
}
20292049

2050+
#[derive(Debug)]
2051+
struct ThemeCharacters {
2052+
hbar: char,
2053+
progress_chars: &'static str,
2054+
}
2055+
2056+
impl Default for ThemeCharacters {
2057+
fn default() -> Self {
2058+
Self {
2059+
hbar: '-',
2060+
progress_chars: "=> ",
2061+
}
2062+
}
2063+
}
2064+
2065+
impl ThemeCharacters {
2066+
fn use_unicode(&mut self) {
2067+
self.hbar = '─';
2068+
// https://mike42.me/blog/2018-06-make-better-cli-progress-bars-with-unicode-block-characters
2069+
self.progress_chars = "█▉▊▋▌▍▎▏ ";
2070+
}
2071+
2072+
fn hbar(&self, width: usize) -> String {
2073+
std::iter::repeat(self.hbar).take(width).collect()
2074+
}
2075+
}
2076+
20302077
#[cfg(test)]
20312078
mod tests {
20322079
use super::*;

0 commit comments

Comments
 (0)