This repository has been archived on 2026-10-08. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
maestro/crates/maestro-daemon/tests/worktree.rs
T
naps62-yolo 946aa384a0
ci / rust (push) Failing after 3s
feat(maestro): add daemon tmux/sidecar/worktree primitives
Local primitives for `maestrod`, no network code yet:

- `tmux`: subprocess wrapper around new-session, kill-session,
  list-sessions (filtered to maestro-*), send-keys -l, pipe-pane -o,
  resize-window, kill-server.
- `sidecar`: atomic JSON metadata store keyed by session UUID, with
  load_all for daemon restart recovery.
- `worktree`: `git worktree add -b` with collision-proof generated paths
  and `git worktree remove --force` for cleanup_on_kill.

Integration tests use real tmux (isolated via unique socket + temp
TMUX_TMPDIR) and real git (tmpdir repo).

Closes NAP-212.
2026-05-24 13:02:41 +00:00

104 lines
2.9 KiB
Rust

//! Worktree-manager integration tests against a real `git` binary and a
//! tmpdir-backed source repo.
mod common;
use std::path::PathBuf;
use std::process::Command;
use common::init_repo;
use maestro_daemon::worktree::WorktreeManager;
use tempfile::TempDir;
fn worktree_branches(repo: &PathBuf) -> Vec<String> {
let out = Command::new("git")
.arg("-C")
.arg(repo)
.args(["worktree", "list", "--porcelain"])
.output()
.expect("git worktree list");
assert!(out.status.success());
let s = String::from_utf8_lossy(&out.stdout);
s.lines()
.filter_map(|l| l.strip_prefix("branch refs/heads/").map(String::from))
.collect()
}
#[test]
fn add_creates_worktree_on_new_branch() {
let repo_dir = TempDir::new().unwrap();
let repo = repo_dir.path().to_path_buf();
init_repo(&repo);
let wt_root = TempDir::new().unwrap();
let mgr = WorktreeManager::new(wt_root.path());
let path = mgr.add(&repo, "feat/example").expect("add worktree");
assert!(path.exists());
assert!(path.join("README").exists());
assert!(path.starts_with(wt_root.path()));
let branches = worktree_branches(&repo);
assert!(branches.iter().any(|b| b == "feat/example"), "{branches:?}");
}
#[test]
fn add_twice_generates_distinct_paths() {
let repo_dir = TempDir::new().unwrap();
let repo = repo_dir.path().to_path_buf();
init_repo(&repo);
let wt_root = TempDir::new().unwrap();
let mgr = WorktreeManager::new(wt_root.path());
let p1 = mgr.add(&repo, "feat/a").expect("add a");
let p2 = mgr.add(&repo, "feat/b").expect("add b");
assert_ne!(p1, p2);
assert!(p1.exists());
assert!(p2.exists());
}
#[test]
fn remove_prunes_worktree() {
let repo_dir = TempDir::new().unwrap();
let repo = repo_dir.path().to_path_buf();
init_repo(&repo);
let wt_root = TempDir::new().unwrap();
let mgr = WorktreeManager::new(wt_root.path());
let path = mgr.add(&repo, "feat/gone").expect("add");
assert!(path.exists());
mgr.remove(&repo, &path).expect("remove");
assert!(!path.exists());
let branches = worktree_branches(&repo);
// The branch itself still exists, but the worktree should be gone — only
// the base repo's main branch should show in `worktree list`.
assert_eq!(branches, vec!["main".to_string()]);
}
#[test]
fn add_fails_when_branch_already_exists() {
let repo_dir = TempDir::new().unwrap();
let repo = repo_dir.path().to_path_buf();
init_repo(&repo);
// pre-create the branch
let status = Command::new("git")
.arg("-C")
.arg(&repo)
.args(["branch", "feat/dup"])
.status()
.unwrap();
assert!(status.success());
let wt_root = TempDir::new().unwrap();
let mgr = WorktreeManager::new(wt_root.path());
let err = mgr.add(&repo, "feat/dup").unwrap_err();
let msg = format!("{err}");
assert!(msg.contains("git exited"), "{msg}");
}