mod common;
use common::{OutputAssertions, TestRepo};
#[test]
fn test_fold_into_trunk_not_allowed() {
let repo = TestRepo::new();
repo.create_stack(&["feature-1"]);
assert!(repo.current_branch_contains("feature-1"));
let output = repo.run_stax(&["branch", "fold"]);
let stdout = TestRepo::stdout(&output);
let stderr = TestRepo::stderr(&output);
let combined = format!("{}{}", stdout, stderr);
assert!(
combined.contains("trunk")
|| combined.contains("Cannot fold")
|| combined.contains("submit"),
"Expected message about trunk, got: {}",
combined
);
}
#[test]
fn test_fold_with_children_not_allowed() {
let repo = TestRepo::new();
let branches = repo.create_stack(&["feature-1", "feature-2"]);
repo.run_stax(&["checkout", &branches[0]]);
assert!(repo.current_branch_contains("feature-1"));
let output = repo.run_stax(&["branch", "fold"]);
let stdout = TestRepo::stdout(&output);
let stderr = TestRepo::stderr(&output);
let combined = format!("{}{}", stdout, stderr);
assert!(
combined.contains("children")
|| combined.contains("child")
|| combined.contains("Cannot fold"),
"Expected message about children, got: {}",
combined
);
}
#[test]
fn test_fold_untracked_branch_fails() {
let repo = TestRepo::new();
repo.git(&["checkout", "-b", "untracked-branch"]);
repo.create_file("test.txt", "content");
repo.commit("Untracked commit");
let output = repo.run_stax(&["branch", "fold"]);
let stdout = TestRepo::stdout(&output);
let stderr = TestRepo::stderr(&output);
let combined = format!("{}{}", stdout, stderr);
assert!(
combined.contains("not tracked") || combined.contains("track") || !output.status.success(),
"Expected message about tracking or failure, got: {}",
combined
);
}
#[test]
fn test_fold_on_trunk_not_allowed() {
let repo = TestRepo::new();
repo.create_stack(&["feature-1"]);
repo.run_stax(&["t"]);
assert_eq!(repo.current_branch(), "main");
let output = repo.run_stax(&["branch", "fold"]);
let stdout = TestRepo::stdout(&output);
let stderr = TestRepo::stderr(&output);
let combined = format!("{}{}", stdout, stderr);
assert!(
combined.contains("trunk") || combined.contains("not tracked") || !output.status.success(),
"Expected failure on trunk, got: {}",
combined
);
}
#[test]
fn test_fold_no_commits_to_fold() {
let repo = TestRepo::new();
repo.run_stax(&["bc", "feature-1"]);
let feature1 = repo.current_branch();
repo.create_file("f1.txt", "content");
repo.commit("Feature 1");
repo.run_stax(&["bc", "feature-2"]);
let feature2 = repo.current_branch();
repo.run_stax(&["checkout", &feature1]);
repo.run_stax(&["branch", "delete", &feature2, "--force"]);
repo.git(&["checkout", "-b", "empty-branch"]);
repo.run_stax(&["branch", "track", "--parent", &feature1]);
let output = repo.run_stax(&["branch", "fold"]);
let stdout = TestRepo::stdout(&output);
let stderr = TestRepo::stderr(&output);
let combined = format!("{}{}", stdout, stderr);
assert!(
combined.contains("No commits")
|| combined.contains("no commits")
|| combined.contains("0 commit"),
"Expected 'no commits' message, got: {}",
combined
);
}
#[test]
fn test_fold_help() {
let repo = TestRepo::new();
let output = repo.run_stax(&["branch", "fold", "--help"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("--keep") || stdout.contains("-k"),
"Expected --keep flag in help"
);
assert!(
stdout.contains("fold") || stdout.contains("Fold"),
"Expected 'fold' in help"
);
}
#[test]
fn test_fold_alias_f() {
let repo = TestRepo::new();
let output = repo.run_stax(&["b", "f", "--help"]);
output.assert_success();
}
#[test]
fn test_fold_keep_flag_in_help() {
let repo = TestRepo::new();
let output = repo.run_stax(&["branch", "fold", "--help"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("keep") || stdout.contains("Keep"),
"Expected 'keep' in fold help: {}",
stdout
);
}
#[test]
fn test_fold_scenario_valid_setup() {
let repo = TestRepo::new();
repo.run_stax(&["bc", "feature-1"]);
repo.create_file("f1.txt", "content 1");
repo.commit("Feature 1 commit");
repo.run_stax(&["bc", "feature-2"]);
repo.create_file("f2.txt", "content 2");
repo.commit("Feature 2 commit");
let json = repo.get_status_json();
let branches = json["branches"].as_array().unwrap();
let f2_branch = branches
.iter()
.find(|b| b["name"].as_str().unwrap_or("").contains("feature-2"))
.expect("Should find feature-2");
assert!(
f2_branch["parent"]
.as_str()
.unwrap_or("")
.contains("feature-1"),
"feature-2 should have feature-1 as parent"
);
let ahead = f2_branch["ahead"].as_i64().unwrap_or(0);
assert!(ahead > 0, "feature-2 should have commits ahead: {}", ahead);
}
#[test]
fn test_fold_scenario_branch_with_children_detected() {
let repo = TestRepo::new();
repo.run_stax(&["bc", "feature-1"]);
let feature1 = repo.current_branch();
repo.create_file("f1.txt", "content 1");
repo.commit("Feature 1 commit");
repo.run_stax(&["bc", "feature-2"]);
repo.create_file("f2.txt", "content 2");
repo.commit("Feature 2 commit");
let children = repo.get_children(&feature1);
assert!(
!children.is_empty(),
"feature-1 should have children: {:?}",
children
);
assert!(
children.iter().any(|c| c.contains("feature-2")),
"feature-1 should have feature-2 as child"
);
}
#[test]
fn test_fold_scenario_parent_is_not_trunk() {
let repo = TestRepo::new();
repo.run_stax(&["bc", "feature-1"]);
repo.create_file("f1.txt", "content");
repo.commit("Feature 1");
repo.run_stax(&["bc", "feature-2"]);
let parent = repo.get_current_parent();
assert!(parent.is_some(), "feature-2 should have a parent");
assert!(
parent.unwrap().contains("feature-1"),
"feature-2's parent should be feature-1"
);
}