mod common;
use common::{OutputAssertions, TestRepo};
#[test]
fn edit_on_trunk_fails() {
let repo = TestRepo::new();
repo.run_stax(&["init"]).assert_success();
let output = repo.run_stax(&["edit", "--yes"]);
output.assert_failure();
let stderr = TestRepo::stderr(&output);
assert!(
stderr.contains("trunk"),
"Should mention trunk in error: {}",
stderr
);
}
#[test]
fn edit_on_branch_with_no_commits_shows_message() {
let repo = TestRepo::new();
repo.run_stax(&["init"]).assert_success();
repo.run_stax(&["create", "empty-branch"]).assert_success();
let output = repo.run_stax(&["edit", "--yes"]);
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("No commits") || stdout.contains("no commits"),
"Should indicate no commits on branch: stdout={} stderr={}",
stdout,
TestRepo::stderr(&output)
);
}
#[test]
fn edit_on_dirty_tree_fails() {
let repo = TestRepo::new();
repo.run_stax(&["init"]).assert_success();
repo.create_file("a.txt", "hello");
repo.run_stax(&["create", "-a", "-m", "initial work"])
.assert_success();
repo.create_file("b.txt", "dirty");
let output = repo.run_stax(&["edit", "--yes"]);
output.assert_failure();
let stderr = TestRepo::stderr(&output);
assert!(
stderr.contains("uncommitted") || stderr.contains("dirty"),
"Should mention uncommitted changes: {}",
stderr
);
}
#[test]
fn edit_drop_removes_commit() {
let repo = TestRepo::new();
repo.run_stax(&["init"]).assert_success();
repo.run_stax(&["create", "feature"]).assert_success();
repo.create_file("a.txt", "first");
repo.commit("first commit");
repo.create_file("b.txt", "second");
repo.commit("second commit");
let log = repo.git(&["log", "--oneline", "main..HEAD"]);
let commit_count = TestRepo::stdout(&log).lines().count();
assert_eq!(commit_count, 2, "Should have 2 commits before edit");
let log_output = repo.git(&["log", "--reverse", "--format=%H %s", "main..HEAD"]);
let log_str = TestRepo::stdout(&log_output);
let commits: Vec<&str> = log_str.lines().collect();
assert_eq!(commits.len(), 2);
let todo = format!(
"drop {}\npick {}",
commits[0].split_whitespace().next().unwrap(),
commits[1].split_whitespace().next().unwrap()
);
let todo_path = repo.path().join(".git").join("stax-edit-todo");
std::fs::write(&todo_path, &todo).unwrap();
let rebase = repo.git(&[
"-c",
&format!("sequence.editor=cp {}", todo_path.to_string_lossy()),
"rebase",
"-i",
"main",
]);
assert!(
rebase.status.success(),
"Rebase should succeed: {}",
TestRepo::stderr(&rebase)
);
let log_after = repo.git(&["log", "--oneline", "main..HEAD"]);
let count_after = TestRepo::stdout(&log_after).lines().count();
assert_eq!(count_after, 1, "Should have 1 commit after dropping one");
let remaining = TestRepo::stdout(&log_after);
assert!(
remaining.contains("second commit"),
"Remaining commit should be 'second commit': {}",
remaining
);
}
#[test]
fn edit_requires_interactive_terminal() {
let repo = TestRepo::new();
repo.run_stax(&["init"]).assert_success();
repo.run_stax(&["create", "feature"]).assert_success();
repo.create_file("a.txt", "content");
repo.commit("a commit");
let output = repo.run_stax(&["edit"]);
output.assert_failure();
}
#[test]
fn edit_yes_still_requires_terminal_for_action_selection() {
let repo = TestRepo::new();
repo.run_stax(&["init"]).assert_success();
repo.run_stax(&["create", "feature"]).assert_success();
repo.create_file("a.txt", "content");
repo.commit("a commit");
let output = repo.run_stax(&["edit", "--yes"]);
output.assert_failure();
let stderr = TestRepo::stderr(&output);
assert!(
stderr.contains("--yes") && stderr.contains("Interactive terminal"),
"Expected explicit --yes terminal guidance, got: {}",
stderr
);
}