use super::*;
fn contrib(name: &str, fp: FailurePolicy, cp: CommitPolicy) -> Contribution {
Contribution {
name: name.into(),
failure_policy: fp,
commit_policy: cp,
}
}
const DEFAULT_MSG: &str = "balls: update external for bl-1234";
#[test]
fn empty_contributions_emits_no_ops() {
let ops = plan(&[], DEFAULT_MSG).unwrap();
assert!(ops.is_empty());
}
#[test]
fn all_default_commits_collapse_into_single_default_commit() {
let cs = vec![
contrib("a", FailurePolicy::BestEffort, CommitPolicy::default()),
contrib("b", FailurePolicy::BestEffort, CommitPolicy::default()),
];
assert_eq!(
plan(&cs, DEFAULT_MSG).unwrap(),
vec![
PlanOp::Apply(0),
PlanOp::Apply(1),
PlanOp::Commit(DEFAULT_MSG.into()),
]
);
}
#[test]
fn suppress_on_best_effort_defers_to_default_commit() {
let cs = vec![contrib(
"a",
FailurePolicy::BestEffort,
CommitPolicy::Suppress,
)];
assert_eq!(
plan(&cs, DEFAULT_MSG).unwrap(),
vec![PlanOp::Apply(0), PlanOp::Commit(DEFAULT_MSG.into())]
);
}
#[test]
fn suppress_followed_by_commit_some_lets_next_commit_capture() {
let cs = vec![
contrib("a", FailurePolicy::BestEffort, CommitPolicy::Suppress),
contrib(
"b",
FailurePolicy::BestEffort,
CommitPolicy::Commit { message: Some("hello".into()) },
),
];
assert_eq!(
plan(&cs, DEFAULT_MSG).unwrap(),
vec![
PlanOp::Apply(0),
PlanOp::Apply(1),
PlanOp::Commit("plugin: b: hello".into()),
]
);
}
#[test]
fn suppress_on_required_errors_before_any_apply() {
let cs = vec![
contrib("a", FailurePolicy::BestEffort, CommitPolicy::default()),
contrib("b", FailurePolicy::Required, CommitPolicy::Suppress),
];
let err = plan(&cs, DEFAULT_MSG).unwrap_err();
let msg = format!("{err}");
assert!(msg.contains("Suppress"), "{msg}");
assert!(msg.contains("Required"), "{msg}");
assert!(msg.contains('b'), "{msg}");
}
#[test]
fn batch_three_participants_coalesces_into_one_commit() {
let cs = vec![
contrib(
"a",
FailurePolicy::BestEffort,
CommitPolicy::Batch { tag: "x".into() },
),
contrib(
"b",
FailurePolicy::BestEffort,
CommitPolicy::Batch { tag: "x".into() },
),
contrib(
"c",
FailurePolicy::BestEffort,
CommitPolicy::Batch { tag: "x".into() },
),
];
assert_eq!(
plan(&cs, DEFAULT_MSG).unwrap(),
vec![
PlanOp::Apply(0),
PlanOp::Apply(1),
PlanOp::Apply(2),
PlanOp::Commit("balls: batch x\n\nparticipants: a, b, c".into()),
]
);
}
#[test]
fn batch_flush_captures_deferred_suppress_state() {
let cs = vec![
contrib("a", FailurePolicy::BestEffort, CommitPolicy::Suppress),
contrib(
"b",
FailurePolicy::BestEffort,
CommitPolicy::Batch { tag: "x".into() },
),
];
assert_eq!(
plan(&cs, DEFAULT_MSG).unwrap(),
vec![
PlanOp::Apply(0),
PlanOp::Apply(1),
PlanOp::Commit("balls: batch x\n\nparticipants: b".into()),
]
);
}
#[test]
fn batch_with_distinct_tags_emits_one_commit_per_tag() {
let cs = vec![
contrib(
"a",
FailurePolicy::BestEffort,
CommitPolicy::Batch { tag: "audit".into() },
),
contrib(
"b",
FailurePolicy::BestEffort,
CommitPolicy::Batch { tag: "ship".into() },
),
];
let ops = plan(&cs, DEFAULT_MSG).unwrap();
assert_eq!(ops.len(), 4);
assert_eq!(ops[0], PlanOp::Apply(0));
assert_eq!(ops[1], PlanOp::Apply(1));
assert_eq!(
ops[2],
PlanOp::Commit("balls: batch audit\n\nparticipants: a".into())
);
assert_eq!(
ops[3],
PlanOp::Commit("balls: batch ship\n\nparticipants: b".into())
);
}
#[test]
fn commit_some_emits_immediately_with_plugin_prefix() {
let cs = vec![contrib(
"mock",
FailurePolicy::BestEffort,
CommitPolicy::Commit { message: Some("Synced MOCK-1".into()) },
)];
assert_eq!(
plan(&cs, DEFAULT_MSG).unwrap(),
vec![
PlanOp::Apply(0),
PlanOp::Commit("plugin: mock: Synced MOCK-1".into()),
]
);
}
#[test]
fn plugin_commit_message_preserves_body_below_title() {
let m = plugin_commit_message("jira", "Sync PROJ-1\n\nDetails about the sync.");
assert_eq!(m, "plugin: jira: Sync PROJ-1\n\nDetails about the sync.");
}
#[test]
fn plugin_commit_message_handles_single_line() {
assert_eq!(plugin_commit_message("mock", "custom"), "plugin: mock: custom");
}
#[test]
fn plugin_commit_message_strips_only_blank_separator() {
let m = plugin_commit_message("p", "T\n\n\nbody1\n\nbody2");
assert_eq!(m, "plugin: p: T\n\nbody1\n\nbody2");
}
#[test]
fn plugin_commit_message_empty_input_yields_prefix_only() {
assert_eq!(plugin_commit_message("p", ""), "plugin: p: ");
}
#[test]
fn plugin_commit_message_blank_only_body_drops_to_prefix() {
assert_eq!(plugin_commit_message("p", "T\n\n"), "plugin: p: T");
}
#[test]
fn batch_commit_message_format() {
assert_eq!(
batch_commit_message("audit", &["a".into(), "b".into()]),
"balls: batch audit\n\nparticipants: a, b"
);
}