use super::*;
use crate::item_data::ItemData;
fn setup(ctx: TestContext) -> TestContext {
commit(&ctx.dir, "third commit", "");
commit(&ctx.dir, "second commit", "");
commit(&ctx.dir, "first commit", "");
ctx
}
#[test]
fn limit_prompt() {
snapshot!(setup(setup_clone!()), "l-n-n");
}
#[test]
fn limit_set_10() {
snapshot!(setup(setup_clone!()), "l-n-n10<enter>");
}
#[test]
fn limit_invalid() {
snapshot!(setup(setup_clone!()), "l-n-nfff<enter>");
}
#[test]
fn limit_2_commits() {
snapshot!(setup(setup_clone!()), "l-n-n2<enter>l");
}
#[test]
fn limit_2_commits_other() {
snapshot!(setup(setup_clone!()), "l-n-n2<enter>l");
}
#[test]
fn grep_prompt() {
snapshot!(setup(setup_clone!()), "l-F");
}
#[test]
fn grep_set_example() {
snapshot!(setup(setup_clone!()), "l-Fexample<enter>");
}
#[test]
fn grep_second() {
snapshot!(setup(setup_clone!()), "l-Fsecond<enter>l");
}
#[test]
fn grep_no_match() {
snapshot!(setup(setup_clone!()), "l-Fdoesntexist<enter>l");
}
#[test]
fn grep_second_other() {
snapshot!(setup(setup_clone!()), "l-Fsecond<enter>omain<enter>");
}
#[test]
fn log_other_prompt() {
snapshot!(setup(setup_clone!()), "lljlo");
}
#[test]
fn log_other() {
snapshot!(setup(setup_clone!()), "lljlo<enter>");
}
#[test]
fn log_other_input() {
snapshot!(setup(setup_clone!()), "lomain~1<enter>");
}
#[test]
fn log_other_invalid() {
snapshot!(setup(setup_clone!()), "lo <enter>");
}
#[test]
fn log_empty_branch() {
let mut ctx = setup_clone!();
run(&ctx.dir, &["rm", "-rf", ".git"]);
run(&ctx.dir, &["rm", "initial-file"]);
run(&ctx.dir, &["git", "init", "--initial-branch=main"]);
let mut app = ctx.init_app();
ctx.update(&mut app, keys("ll"));
insta::assert_snapshot!(ctx.redact_buffer());
}
pub(super) fn with_log_renderer(mut ctx: TestContext, args: &[&str], format: &str) -> TestContext {
let config = ctx.config();
config.general.log_renderer.enabled = true;
config.general.log_renderer.command = [&["git", "log", "--color=always", "--date=short"], args]
.concat()
.iter()
.map(|arg| arg.to_string())
.chain([format!("--format={format}")])
.collect();
ctx
}
pub(super) const MULTI_ROW_FORMAT: &str =
"{commit}%n\u{25b8} %h %an %ad%C(auto)%d%C(reset)%n %s";
#[test]
fn rendered_log() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"ll"
);
}
#[test]
fn rendered_log_move_down_steps_a_whole_commit() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"lljj"
);
}
#[test]
fn rendered_log_move_next_section_steps_a_whole_commit() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"ll<alt+j><alt+j>"
);
}
#[test]
fn rendered_log_move_prev_section_steps_a_whole_commit() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"lljj<alt+k>"
);
}
#[test]
fn rendered_log_fold_hides_the_commit_rows() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"ll<tab>"
);
}
#[test]
fn rendered_log_show_acts_on_the_selected_commit() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"llj<enter>"
);
}
#[test]
fn rendered_log_copy_hash_of_the_selected_commit() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"lljy"
);
}
#[test]
fn rendered_log_with_stat() {
snapshot!(
with_log_renderer(
setup(setup_clone!()),
&["--stat"],
"{commit}%n\u{25b8} %h %s"
),
"llj"
);
}
#[test]
fn rendered_log_limit() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"l-n-n2<enter>l"
);
}
#[test]
fn rendered_log_grep() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"l-Fsecond<enter>l"
);
}
#[test]
fn rendered_log_other_rev() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], MULTI_ROW_FORMAT),
"lomain~1<enter>"
);
}
#[test]
fn rendered_log_without_commit_marker_falls_back() {
snapshot!(with_log_renderer(setup(setup_clone!()), &[], "%h %s"), "ll");
}
#[test]
fn rendered_log_empty_branch_falls_back() {
let ctx = setup_clone!();
run(&ctx.dir, &["rm", "-rf", ".git"]);
run(&ctx.dir, &["rm", "initial-file"]);
run(&ctx.dir, &["git", "init", "--initial-branch=main"]);
let mut ctx = with_log_renderer(ctx, &[], MULTI_ROW_FORMAT);
let mut app = ctx.init_app();
ctx.update(&mut app, keys("ll"));
insta::assert_snapshot!(ctx.redact_buffer());
}
const DECORATED_FORMAT: &str = "{commit}%n\u{2500}\u{2500}\u{2500}\u{2500}\u{2500}%n\u{25b8} %h %s";
#[test]
fn rendered_log_divider_is_not_the_cursor_line() {
snapshot!(
with_log_renderer(setup(setup_clone!()), &[], DECORATED_FORMAT),
"llj"
);
}
#[test]
fn rendered_log_keeps_the_first_commit_when_the_renderer_greets_on_its_line() {
let mut ctx = setup(setup_clone!());
ctx.config().general.log_renderer.enabled = true;
ctx.config().general.log_renderer.command = [
"sh",
"-c",
r#"printf '\033]1717;1\033\\'; git log --format="{commit}%nâââ%n⸠%h %s" "$@""#,
"gitu",
]
.map(String::from)
.to_vec();
let mut app = ctx.init_app();
ctx.update(&mut app, keys("ll"));
insta::assert_snapshot!(ctx.redact_buffer());
}
#[test]
fn paging_lands_on_a_commit_of_the_new_page() {
let mut ctx = setup_clone!();
for i in 1..=40 {
commit(&ctx.dir, &format!("file-{i:02}"), "");
}
let mut app = ctx.init_app();
ctx.update(&mut app, keys("ll"));
let top = selected_summary(&app);
ctx.update(&mut app, keys("<pagedown>"));
let paged = selected_summary(&app);
assert_ne!(top, paged, "the cursor stayed on the first commit");
assert!(
ctx.redact_buffer().contains(&paged),
"selected {paged} is off screen:\n{}",
ctx.redact_buffer()
);
ctx.update(&mut app, keys("<pageup>"));
assert_eq!(top, selected_summary(&app), "paging back missed the commit");
}
fn selected_summary(app: &crate::app::App) -> String {
match &app.state.screens.last().unwrap().get_selected_item().data {
ItemData::Commit { summary, .. } => summary.clone(),
data => panic!("not a commit: {data:?}"),
}
}