mod common;
use common::TestRepo;
use assert_cmd::Command;
use predicates::prelude::*;
use std::process::Command as StdCommand;
fn gw() -> Command {
Command::cargo_bin("gw").unwrap()
}
#[test]
fn ls_emits_tsv_for_a_repo_with_one_worktree() {
let repo = TestRepo::new();
let repo_path = repo.path();
let wt_path = repo_path.parent().unwrap().join(format!(
"{}-feat-a",
repo_path.file_name().unwrap().to_str().unwrap()
));
let status = StdCommand::new("git")
.args(["worktree", "add", "-b", "feat-a", wt_path.to_str().unwrap()])
.current_dir(repo_path)
.env("GIT_AUTHOR_NAME", "Test")
.env("GIT_AUTHOR_EMAIL", "test@test.com")
.env("GIT_COMMITTER_NAME", "Test")
.env("GIT_COMMITTER_EMAIL", "test@test.com")
.status()
.expect("git worktree add");
assert!(status.success(), "git worktree add failed");
let output = StdCommand::new(TestRepo::cw_bin())
.arg("ls")
.current_dir(repo_path)
.env("CW_LAUNCH_METHOD", "foreground")
.output()
.expect("gw ls");
assert!(
output.status.success(),
"gw ls failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
let lines: Vec<&str> = stdout.lines().collect();
assert_eq!(lines.len(), 2, "expected 2 TSV lines, got: {:?}", lines);
for line in &lines {
let cols: Vec<&str> = line.split('\t').collect();
assert_eq!(
cols.len(),
6,
"expected 6 tab-separated columns, got {} in line: {:?}",
cols.len(),
line
);
}
let wt_line = lines
.iter()
.find(|l| l.contains("feat-a"))
.expect("feat-a line");
let last_col = wt_line.split('\t').next_back().unwrap();
assert!(
std::path::Path::new(last_col).is_absolute(),
"last column should be an absolute path, got: {:?}",
last_col
);
}
#[test]
fn ls_silent_when_no_worktrees() {
let repo = TestRepo::new();
let output = StdCommand::new(TestRepo::cw_bin())
.arg("ls")
.current_dir(repo.path())
.env("CW_LAUNCH_METHOD", "foreground")
.output()
.expect("gw ls");
assert!(
output.status.success(),
"gw ls failed: {}",
String::from_utf8_lossy(&output.stderr)
);
let stdout = String::from_utf8_lossy(&output.stdout);
let lines: Vec<&str> = stdout.lines().collect();
assert_eq!(
lines.len(),
1,
"expected exactly 1 TSV line for main worktree, got: {:?}",
lines
);
}
#[test]
fn ls_no_color_codes() {
let repo = TestRepo::new();
gw().arg("ls")
.current_dir(repo.path())
.env("CW_LAUNCH_METHOD", "foreground")
.env("TERM", "dumb")
.env("NO_COLOR", "1")
.assert()
.success()
.stdout(predicate::str::contains("\x1b[").not());
}
#[test]
fn ls_no_no_cache_flag() {
let repo = TestRepo::new();
gw().args(["ls", "--no-cache"])
.current_dir(repo.path())
.env("CW_LAUNCH_METHOD", "foreground")
.assert()
.failure()
.stderr(
predicate::str::contains("unexpected argument")
.or(predicate::str::contains("--no-cache"))
.or(predicate::str::contains("unrecognized")),
);
gw().args(["list", "--no-cache"])
.current_dir(repo.path())
.env("CW_LAUNCH_METHOD", "foreground")
.assert()
.failure()
.stderr(
predicate::str::contains("unexpected argument")
.or(predicate::str::contains("--no-cache"))
.or(predicate::str::contains("unrecognized")),
);
}