mod common;
use common::{OutputAssertions, TestRepo};
#[test]
fn test_downstack_get_from_top_shows_full_stack() {
let repo = TestRepo::new();
repo.create_stack(&["feature-1", "feature-2", "feature-3"]);
assert!(repo.current_branch_contains("feature-3"));
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("feature-1"),
"Expected feature-1 in downstack output: {}",
stdout
);
assert!(
stdout.contains("feature-2"),
"Expected feature-2 in downstack output: {}",
stdout
);
assert!(
stdout.contains("feature-3"),
"Expected feature-3 in downstack output: {}",
stdout
);
assert!(
stdout.contains("main"),
"Expected main in downstack output: {}",
stdout
);
}
#[test]
fn test_downstack_get_from_middle_shows_ancestors() {
let repo = TestRepo::new();
let branches = repo.create_stack(&["feature-1", "feature-2", "feature-3"]);
repo.run_stax(&["checkout", &branches[1]]);
assert!(repo.current_branch_contains("feature-2"));
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("feature-1"),
"Expected feature-1 in downstack: {}",
stdout
);
assert!(
stdout.contains("feature-2"),
"Expected feature-2 in downstack: {}",
stdout
);
assert!(
stdout.contains("main"),
"Expected main in downstack: {}",
stdout
);
}
#[test]
fn test_downstack_get_from_first_branch() {
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(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("feature-1"),
"Expected feature-1: {}",
stdout
);
assert!(stdout.contains("main"), "Expected main: {}", stdout);
}
#[test]
fn test_downstack_get_on_trunk() {
let repo = TestRepo::new();
repo.create_stack(&["feature-1"]);
repo.run_stax(&["t"]);
assert_eq!(repo.current_branch(), "main");
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(stdout.contains("main"), "Expected main: {}", stdout);
}
#[test]
fn test_downstack_alias_ds() {
let repo = TestRepo::new();
repo.create_stack(&["feature-1"]);
let output = repo.run_stax(&["ds", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("feature-1"),
"Expected feature-1 in ds output: {}",
stdout
);
}
#[test]
fn test_downstack_help() {
let repo = TestRepo::new();
let output = repo.run_stax(&["downstack", "--help"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("get") || stdout.contains("Get"),
"Expected 'get' subcommand in help: {}",
stdout
);
}
#[test]
fn test_downstack_get_help() {
let repo = TestRepo::new();
let output = repo.run_stax(&["downstack", "get", "--help"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("below") || stdout.contains("Show") || stdout.contains("branch"),
"Expected help text: {}",
stdout
);
}
#[test]
fn test_downstack_get_single_branch() {
let repo = TestRepo::new();
repo.create_stack(&["solo-feature"]);
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(stdout.contains("solo-feature") || stdout.contains("solo"));
assert!(stdout.contains("main"));
}
#[test]
fn test_downstack_get_with_multiple_stacks() {
let repo = TestRepo::new();
repo.create_stack(&["stack1-a", "stack1-b"]);
repo.run_stax(&["t"]);
repo.create_stack(&["stack2-a", "stack2-b"]);
assert!(repo.current_branch_contains("stack2-b"));
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(stdout.contains("stack2-a") || stdout.contains("stack2"));
assert!(stdout.contains("stack2-b") || stdout.contains("stack2"));
assert!(stdout.contains("main"));
}
#[test]
fn test_downstack_get_long_stack() {
let repo = TestRepo::new();
repo.create_stack(&["f1", "f2", "f3", "f4", "f5"]);
assert!(repo.current_branch_contains("f5"));
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
for i in 1..=5 {
let name = format!("f{}", i);
assert!(
stdout.contains(&name),
"Expected {} in downstack: {}",
name,
stdout
);
}
}
#[test]
fn test_downstack_get_untracked_branch() {
let repo = TestRepo::new();
repo.git(&["checkout", "-b", "untracked"]);
repo.create_file("test.txt", "content");
repo.commit("Untracked commit");
let output = repo.run_stax(&["downstack", "get"]);
let stdout = TestRepo::stdout(&output);
let stderr = TestRepo::stderr(&output);
let combined = format!("{}{}", stdout, stderr);
assert!(
combined.contains("main")
|| combined.contains("untracked")
|| combined.contains("not tracked")
|| !output.status.success(),
"Expected some output or graceful failure: {}",
combined
);
}
#[test]
fn test_downstack_get_output_format() {
let repo = TestRepo::new();
repo.create_stack(&["feature-1", "feature-2"]);
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(stdout.contains("main"), "Should show trunk in output");
assert!(stdout.contains("feature-1"), "Should show feature-1");
assert!(stdout.contains("feature-2"), "Should show feature-2");
}
#[test]
fn test_downstack_get_shows_current_indicator() {
let repo = TestRepo::new();
let branches = repo.create_stack(&["feature-1", "feature-2"]);
repo.run_stax(&["checkout", &branches[0]]);
let output = repo.run_stax(&["downstack", "get"]);
output.assert_success();
let stdout = TestRepo::stdout(&output);
assert!(
stdout.contains("feature-1"),
"Should show current branch feature-1"
);
}