use super::*;
use std::path::Path;
fn width_reporting_renderer(log: Option<&Path>) -> Vec<String> {
let file_header = r#"label,suffix;header=0}"#;
let with_width = r#"label,suffix " @" ENVIRON["COLUMNS"];header=0}"#;
super::pager::annotating_renderer()
.into_iter()
.map(|arg| {
if !arg.contains(file_header) {
return arg;
}
let arg = arg.replace(file_header, with_width);
match log {
Some(log) => arg.replacen(
"BEGIN{",
&format!(
r#"BEGIN{{print ENVIRON["COLUMNS"] >> "{}";"#,
super::pager::awk_path(log)
),
1,
),
None => arg,
}
})
.collect()
}
fn with_a_change(mut ctx: TestContext, log: Option<&Path>) -> TestContext {
ctx.config().general.diff_renderer.command = width_reporting_renderer(log);
commit(&ctx.dir, "firstfile", "testing\ntesttest\n");
fs::write(ctx.dir.join("firstfile"), "changed\ntesttest\n").unwrap();
ctx
}
#[test]
fn a_resize_renders_the_pager_view_again_at_the_new_width() {
let mut ctx = with_a_change(setup_clone!(), None);
let mut app = ctx.init_app_as_pager_of(&["git", "diff"]);
let before = ctx.redact_buffer();
assert!(before.contains("firstfile @78"), "{before}");
ctx.resize(&mut app, &[(120, 20)]);
let after = ctx.redact_buffer();
assert!(after.contains("firstfile @118"), "{after}");
}
#[test]
fn a_resize_renders_the_status_view_again_at_the_new_width() {
let mut ctx = with_a_change(setup_clone!(), None);
let mut app = ctx.init_app();
let before = ctx.redact_buffer();
assert!(before.contains("firstfile @78"), "{before}");
ctx.resize(&mut app, &[(120, 20)]);
let after = ctx.redact_buffer();
assert!(after.contains("firstfile @118"), "{after}");
}
#[test]
fn many_resizes_in_a_row_render_once_at_the_last_width() {
let ctx = setup_clone!();
let log = ctx.dir.join(".git").join("render-widths");
let mut ctx = with_a_change(ctx, Some(&log));
let mut app = ctx.init_app_as_pager_of(&["git", "diff"]);
let widths = || fs::read_to_string(&log).unwrap_or_default();
assert_eq!(widths(), "78\n");
ctx.resize(&mut app, &[(90, 20), (100, 20), (110, 20), (120, 20)]);
assert_eq!(widths(), "78\n118\n");
let screen = ctx.redact_buffer();
assert!(screen.contains("firstfile @118"), "{screen}");
}
#[test]
fn a_resize_of_the_height_alone_does_not_render_again() {
let ctx = setup_clone!();
let log = ctx.dir.join(".git").join("render-widths");
let mut ctx = with_a_change(ctx, Some(&log));
let mut app = ctx.init_app_as_pager_of(&["git", "diff"]);
ctx.resize(&mut app, &[(80, 30)]);
assert_eq!(fs::read_to_string(&log).unwrap(), "78\n");
}
#[test]
fn a_resize_renders_at_the_terminals_width_when_its_events_lag_behind() {
let mut ctx = with_a_change(setup_clone!(), None);
let mut app = ctx.init_app_as_pager_of(&["git", "diff"]);
ctx.resize_with_events(&mut app, (120, 20), &[(100, 20)]);
let screen = ctx.redact_buffer();
assert!(screen.contains("firstfile @118"), "{screen}");
}
#[test]
fn the_event_loop_wakes_when_a_render_at_the_new_width_is_due() {
let mut ctx = with_a_change(setup_clone!(), None);
let mut app = ctx.init_app_as_pager_of(&["git", "diff"]);
let tick = std::time::Duration::from_millis(100);
let now = std::time::Instant::now();
app.state.terminal_width = Some((80, now));
assert_eq!(app.poll_timeout(tick, now), tick);
app.state.terminal_width = Some((120, now));
assert!(app.poll_timeout(tick, now) < tick);
}