huskies: merge 1029
This commit is contained in:
@@ -1155,3 +1155,162 @@ fn display_section_returns_closed_for_new_terminal_variants() {
|
||||
Some("Closed")
|
||||
);
|
||||
}
|
||||
|
||||
// -- Story 1029: working tree dirty-files summary in status output -------
|
||||
|
||||
/// Initialise a bare-minimum git repo in `dir` with one commit.
|
||||
fn init_git_repo(dir: &std::path::Path) {
|
||||
use std::process::Command;
|
||||
Command::new("git")
|
||||
.args(["init", "-b", "main"])
|
||||
.current_dir(dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["config", "user.email", "test@test.com"])
|
||||
.current_dir(dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["config", "user.name", "Test"])
|
||||
.current_dir(dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
// Create an initial commit so the repo has a HEAD.
|
||||
std::fs::write(dir.join("README.md"), "# test").unwrap();
|
||||
Command::new("git")
|
||||
.args(["add", "README.md"])
|
||||
.current_dir(dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
Command::new("git")
|
||||
.args(["commit", "-m", "init"])
|
||||
.current_dir(dir)
|
||||
.output()
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_shows_working_tree_info_when_coder_has_uncommitted_changes() {
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let project_root = tmp.path();
|
||||
let story_id = "1029_story_dirty_worktree";
|
||||
|
||||
// Set up a fake worktree with committed + uncommitted changes.
|
||||
let wt_path = project_root
|
||||
.join(".huskies")
|
||||
.join("worktrees")
|
||||
.join(story_id);
|
||||
fs::create_dir_all(&wt_path).unwrap();
|
||||
init_git_repo(&wt_path);
|
||||
|
||||
// Modify a tracked file (unstaged) and add an untracked file.
|
||||
fs::write(wt_path.join("README.md"), "# changed").unwrap();
|
||||
fs::write(wt_path.join("new_feature.rs"), "fn foo() {}").unwrap();
|
||||
|
||||
let items = vec![make_item(
|
||||
story_id,
|
||||
"Dirty Worktree Story",
|
||||
Stage::Coding {
|
||||
claim: None,
|
||||
plan: Default::default(),
|
||||
retries: 0,
|
||||
},
|
||||
)];
|
||||
|
||||
let agents = AgentPool::new_test(3000);
|
||||
let output = build_status_from_items(project_root, &agents, &items);
|
||||
|
||||
assert!(
|
||||
output.contains("Working tree:"),
|
||||
"status should show working tree summary when changes exist: {output}"
|
||||
);
|
||||
assert!(
|
||||
output.contains("(uncommitted)"),
|
||||
"working tree line should say '(uncommitted)': {output}"
|
||||
);
|
||||
// Should list the dirty files.
|
||||
assert!(
|
||||
output.contains("README.md") || output.contains("new_feature.rs"),
|
||||
"status should list at least one dirty file: {output}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_clean_worktree_shows_no_working_tree_line() {
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let project_root = tmp.path();
|
||||
let story_id = "1029_story_clean_worktree";
|
||||
|
||||
// Set up a clean worktree with only committed changes.
|
||||
let wt_path = project_root
|
||||
.join(".huskies")
|
||||
.join("worktrees")
|
||||
.join(story_id);
|
||||
fs::create_dir_all(&wt_path).unwrap();
|
||||
init_git_repo(&wt_path);
|
||||
|
||||
let items = vec![make_item(
|
||||
story_id,
|
||||
"Clean Worktree Story",
|
||||
Stage::Coding {
|
||||
claim: None,
|
||||
plan: Default::default(),
|
||||
retries: 0,
|
||||
},
|
||||
)];
|
||||
|
||||
let agents = AgentPool::new_test(3000);
|
||||
let output = build_status_from_items(project_root, &agents, &items);
|
||||
|
||||
assert!(
|
||||
!output.contains("Working tree:"),
|
||||
"status should not show working tree line when working tree is clean: {output}"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn status_dirty_files_capped_at_twenty_with_overflow_line() {
|
||||
use std::fs;
|
||||
use tempfile::TempDir;
|
||||
|
||||
let tmp = TempDir::new().unwrap();
|
||||
let project_root = tmp.path();
|
||||
let story_id = "1029_story_many_files";
|
||||
|
||||
let wt_path = project_root
|
||||
.join(".huskies")
|
||||
.join("worktrees")
|
||||
.join(story_id);
|
||||
fs::create_dir_all(&wt_path).unwrap();
|
||||
init_git_repo(&wt_path);
|
||||
|
||||
// Create 25 untracked files.
|
||||
for i in 0..25 {
|
||||
fs::write(wt_path.join(format!("file_{i:02}.rs")), "fn f() {}").unwrap();
|
||||
}
|
||||
|
||||
let items = vec![make_item(
|
||||
story_id,
|
||||
"Many Files Story",
|
||||
Stage::Coding {
|
||||
claim: None,
|
||||
plan: Default::default(),
|
||||
retries: 0,
|
||||
},
|
||||
)];
|
||||
|
||||
let agents = AgentPool::new_test(3000);
|
||||
let output = build_status_from_items(project_root, &agents, &items);
|
||||
|
||||
assert!(
|
||||
output.contains("...and 5 more"),
|
||||
"overflow line should appear when more than 20 files: {output}"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user