use super::*;
use crate::reads::test_support::{git_store, task};
use crate::task::Task;
fn plain() -> Style {
Style { plain: true }
}
fn bodied(text: &str) -> Task {
Task { body: text.into(), ..task("A ball", 100) }
}
fn appended(body: &str, text: &str) -> String {
format!("{}\n\n---\n\n{}\n", body.trim_end(), text.trim_end())
}
#[test]
fn each_comment_carries_its_byline_and_the_original_body_stays_bare() {
let s = git_store();
let t = bodied("The original body, as filed.\n");
let one = appended(&t.body, "single-clone runs pass; needs a second clone");
let two = appended(&one, "second comment\nspanning two lines");
s.create("bl-1", &t, 100);
s.edit("bl-1", &t, "comment", &one, 200);
s.edit("bl-1", &t, "comment", &two, 300);
let out = annotate(s.dir(), "HEAD", "bl-1", &two, &plain()).unwrap();
assert_eq!(
out,
"The original body, as filed.\n\
\n\
---\n\
\n\
single-clone runs pass; needs a second clone\n\
\x20 1970-01-01T00:03:20Z t\n\
\n\
---\n\
\n\
second comment\n\
spanning two lines\n\
\x20 1970-01-01T00:05:00Z t\n"
);
}
#[test]
fn a_create_body_and_a_body_rewrite_are_left_bare() {
let s = git_store();
let t = bodied("as filed\n");
s.create("bl-1", &t, 100);
assert_eq!(annotate(s.dir(), "HEAD", "bl-1", &t.body, &plain()).unwrap(), "as filed\n");
let rewritten = "rewritten wholesale\nover two lines\n";
s.edit("bl-1", &t, "update", rewritten, 200);
assert_eq!(annotate(s.dir(), "HEAD", "bl-1", rewritten, &plain()).unwrap(), rewritten);
}
#[test]
fn an_imported_ball_collapses_onto_its_import_commit_and_renders_bare() {
let s = git_store();
let t = bodied(&appended("as filed", "a real comment, in the source store"));
s.edit("bl-1", &t, "import", &t.body, 100);
let out = annotate(s.dir(), "HEAD", "bl-1", &t.body, &plain()).unwrap();
assert_eq!(out, t.body, "every line is the importer's, so none is a comment");
}
#[test]
fn a_closed_ball_is_blamed_where_its_bytes_last_lived() {
let s = git_store();
let t = bodied("what it did\n");
let commented = appended(&t.body, "and how it went");
s.create("bl-1", &t, 100);
s.edit("bl-1", &t, "comment", &commented, 200);
s.retire("bl-1", "close", 300);
let dead = crate::reads::resolve_dead(s.dir(), "bl-1").unwrap().unwrap();
let out = annotate(s.dir(), &dead.rev, "bl-1", &dead.task.body, &plain()).unwrap();
assert_eq!(out, "what it did\n\n---\n\nand how it went\n 1970-01-01T00:03:20Z t\n");
}
#[test]
fn an_empty_body_makes_no_blame_call_at_all() {
let nostore = std::path::Path::new("/balls-no-such-store");
assert_eq!(annotate(nostore, "HEAD", "bl-1", "", &plain()).unwrap(), "");
}
#[test]
fn a_body_git_cannot_blame_renders_bare_rather_than_erroring() {
let s = git_store();
s.create("bl-other", &task("Other", 1), 1);
let t = bodied("written but never sealed\n");
crate::taskfile::write_task(s.dir(), "bl-new", &t).unwrap();
let out = annotate(s.dir(), "HEAD", "bl-new", &t.body, &plain()).unwrap();
assert_eq!(out, "written but never sealed\n");
}
#[test]
fn a_body_with_no_trailing_newline_still_gets_its_byline_on_its_own_line() {
let s = git_store();
let t = bodied("as filed\n");
let unterminated = "as filed\n\n---\n\nunterminated";
s.create("bl-1", &t, 100);
s.edit("bl-1", &t, "comment", unterminated, 200);
let out = annotate(s.dir(), "HEAD", "bl-1", unterminated, &plain()).unwrap();
assert_eq!(out, "as filed\n\n---\n\nunterminated\n 1970-01-01T00:03:20Z t\n");
}
#[test]
fn the_rich_byline_is_dim_and_the_plain_one_is_the_same_line_bare() {
assert_eq!(Style { plain: false }.byline(200, "alice"), "\u{1b}[90m 1970-01-01T00:03:20Z alice\u{1b}[0m");
assert_eq!(plain().byline(200, "alice"), " 1970-01-01T00:03:20Z alice");
}