use super::*;
use crate::delivery::{Repo, Spec};
use crate::delivery_repo::tests::{project, tip};
use crate::delivery_repo::Project;
use std::fs;
#[test]
fn compose_falls_back_to_the_tagged_subject_with_no_override_or_work() {
assert_eq!(compose(None, &[], "Title [bl-x]", "[bl-x]"), "Title [bl-x]");
let blank = vec![" \n ".to_string()];
assert_eq!(compose(None, &blank, "Title [bl-x]", "[bl-x]"), "Title [bl-x]");
}
#[test]
fn compose_joins_multiple_work_messages_oldest_first_and_tags_the_subject() {
let work = vec!["first\n\nbody".to_string(), "second".to_string()];
assert_eq!(compose(None, &work, "Title [bl-x]", "[bl-x]"), "first [bl-x]\n\nbody\n\nsecond");
}
#[test]
fn compose_override_wins_and_an_empty_override_is_ignored() {
assert_eq!(compose(Some("Do it"), &["work".to_string()], "T [bl-x]", "[bl-x]"), "Do it [bl-x]");
assert_eq!(compose(Some(" "), &["work".to_string()], "T [bl-x]", "[bl-x]"), "work [bl-x]");
}
#[test]
fn with_marker_is_idempotent_and_tags_a_lone_subject_line() {
assert_eq!(compose(Some("Done [bl-x] already"), &[], "T [bl-x]", "[bl-x]"), "Done [bl-x] already");
assert_eq!(compose(Some("Just a subject"), &[], "T [bl-x]", "[bl-x]"), "Just a subject [bl-x]");
}
#[test]
fn work_messages_is_empty_for_a_branch_never_made() {
let (_tmp, _root, p) = project();
assert!(p.work_messages("work/bl-absent", "main").unwrap().is_empty());
}
#[test]
fn work_messages_lists_authored_commits_oldest_first_skipping_merges() {
let (tmp, root, p) = project();
let wt = tmp.path().join("wt");
p.materialize(&wt, "work/bl-x").unwrap();
fs::write(wt.join("a.txt"), "1\n").unwrap();
Project::run(&wt, &["add", "-A"]).unwrap();
Project::run(&wt, &["commit", "-q", "-m", "first commit\n\nbody one"]).unwrap();
fs::write(wt.join("b.txt"), "2\n").unwrap();
Project::run(&wt, &["add", "-A"]).unwrap();
Project::run(&wt, &["commit", "-q", "-m", "second commit"]).unwrap();
fs::write(root.join("c.txt"), "3\n").unwrap();
Project::run(&root, &["add", "-A"]).unwrap();
Project::run(&root, &["commit", "-q", "-m", "main moved"]).unwrap();
Project::run(&wt, &["merge", "--no-edit", "main"]).unwrap();
let got: Vec<String> =
p.work_messages("work/bl-x", "main").unwrap().iter().map(|m| m.trim().to_string()).filter(|m| !m.is_empty()).collect();
assert_eq!(got, ["first commit\n\nbody one", "second commit"]);
}
#[test]
fn deliver_close_carries_the_authors_rich_work_body_to_main() {
let (tmp, root, p) = project();
let wt = tmp.path().join("wt");
p.materialize(&wt, "work/bl-x").unwrap();
fs::write(wt.join("f.txt"), "x\n").unwrap();
Project::run(&wt, &["add", "-A"]).unwrap();
let rich = "Fix the squash message\n\nThe delivery commit used to be only the ball\ntitle; now it carries the body.";
Project::run(&wt, &["commit", "-q", "-m", rich]).unwrap();
let spec = Spec {
worktree: &wt,
branch: "work/bl-x",
subject: "ball title [bl-x]",
override_msg: None,
marker: "[bl-x]",
};
deliver_close(&p, &spec).unwrap();
let body = Project::run(&root, &["log", "-1", "--format=%B", "main"]).unwrap();
assert_eq!(body.trim(), "Fix the squash message [bl-x]\n\nThe delivery commit used to be only the ball\ntitle; now it carries the body.");
assert_eq!(tip(&root), "Fix the squash message [bl-x]");
}
#[test]
fn deliver_close_honors_an_m_override_over_the_work_body() {
let (tmp, root, p) = project();
let wt = tmp.path().join("wt");
p.materialize(&wt, "work/bl-x").unwrap();
fs::write(wt.join("f.txt"), "x\n").unwrap();
Project::run(&wt, &["add", "-A"]).unwrap();
Project::run(&wt, &["commit", "-q", "-m", "work body that loses"]).unwrap();
let spec = Spec {
worktree: &wt,
branch: "work/bl-x",
subject: "ball title [bl-x]",
override_msg: Some("Override wins\n\nthe full message"),
marker: "[bl-x]",
};
deliver_close(&p, &spec).unwrap();
let body = Project::run(&root, &["log", "-1", "--format=%B", "main"]).unwrap();
assert_eq!(body.trim(), "Override wins [bl-x]\n\nthe full message");
}