mod common;
use std::path::Path;
use common::TestRepo;
use git_worktree_manager::cwshare_setup;
fn init_git_repo(path: &Path) {
use std::process::Command;
let run = |args: &[&str]| {
Command::new("git")
.args(args)
.current_dir(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")
.output()
.expect("Failed to run git");
};
run(&["init", "-b", "main"]);
run(&["config", "user.name", "Test"]);
run(&["config", "user.email", "test@test.com"]);
run(&["config", "commit.gpgsign", "false"]);
std::fs::write(path.join("README.md"), "# test\n").unwrap();
run(&["add", "."]);
run(&["commit", "-m", "Initial commit"]);
}
#[test]
fn test_detect_common_files_none() {
let tmp = tempfile::TempDir::new().unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert!(detected.is_empty(), "Empty dir should have no common files");
}
#[test]
fn test_detect_common_files_env() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::write(tmp.path().join(".env"), "SECRET=val").unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert!(detected.contains(&".env".to_string()));
}
#[test]
fn test_detect_common_files_env_local() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::write(tmp.path().join(".env.local"), "LOCAL=val").unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert!(detected.contains(&".env.local".to_string()));
}
#[test]
fn test_detect_common_files_multiple() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::write(tmp.path().join(".env"), "A=1").unwrap();
std::fs::write(tmp.path().join(".env.local"), "B=2").unwrap();
std::fs::write(tmp.path().join(".env.test"), "C=3").unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert_eq!(detected.len(), 3);
}
#[test]
fn test_detect_common_files_vscode() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::create_dir_all(tmp.path().join(".vscode")).unwrap();
std::fs::write(tmp.path().join(".vscode/settings.json"), "{}").unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert!(detected.contains(&".vscode/settings.json".to_string()));
}
#[test]
fn test_detect_common_files_config_yaml() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::create_dir_all(tmp.path().join("config")).unwrap();
std::fs::write(tmp.path().join("config/local.yaml"), "key: val").unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert!(detected.contains(&"config/local.yaml".to_string()));
}
#[test]
fn test_detect_common_files_ignores_non_common() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::write(tmp.path().join("README.md"), "hello").unwrap();
std::fs::write(tmp.path().join("Cargo.toml"), "[package]").unwrap();
let detected = cwshare_setup::detect_common_files(tmp.path());
assert!(detected.is_empty());
}
#[test]
fn test_has_cwshare_file_false() {
let tmp = tempfile::TempDir::new().unwrap();
assert!(!cwshare_setup::has_cwshare_file(tmp.path()));
}
#[test]
fn test_has_cwshare_file_true() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::write(tmp.path().join(".cwshare"), ".env\n").unwrap();
assert!(cwshare_setup::has_cwshare_file(tmp.path()));
}
#[test]
fn test_is_cwshare_prompted_false() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
assert!(!cwshare_setup::is_cwshare_prompted(tmp.path()));
}
#[test]
fn test_mark_cwshare_prompted() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
assert!(!cwshare_setup::is_cwshare_prompted(tmp.path()));
cwshare_setup::mark_cwshare_prompted(tmp.path());
assert!(cwshare_setup::is_cwshare_prompted(tmp.path()));
}
#[test]
fn test_is_cwshare_prompted_true() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
cwshare_setup::mark_cwshare_prompted(tmp.path());
assert!(cwshare_setup::is_cwshare_prompted(tmp.path()));
}
#[test]
fn test_is_cwshare_prompted_non_git() {
let tmp = tempfile::TempDir::new().unwrap();
assert!(!cwshare_setup::is_cwshare_prompted(tmp.path()));
}
#[test]
fn test_mark_cwshare_prompted_idempotent() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
cwshare_setup::mark_cwshare_prompted(tmp.path());
cwshare_setup::mark_cwshare_prompted(tmp.path());
assert!(cwshare_setup::is_cwshare_prompted(tmp.path()));
}
#[test]
fn test_create_cwshare_template_no_files() {
let tmp = tempfile::TempDir::new().unwrap();
cwshare_setup::create_cwshare_template(tmp.path(), &[]);
let content = std::fs::read_to_string(tmp.path().join(".cwshare")).unwrap();
assert!(content.contains("# .cwshare"));
assert!(content.contains("No common files detected"));
}
#[test]
fn test_create_cwshare_template_with_files() {
let tmp = tempfile::TempDir::new().unwrap();
let files = vec![".env".to_string(), ".env.local".to_string()];
cwshare_setup::create_cwshare_template(tmp.path(), &files);
let content = std::fs::read_to_string(tmp.path().join(".cwshare")).unwrap();
assert!(content.contains("# .env"));
assert!(content.contains("# .env.local"));
}
#[test]
fn test_cwshare_template_content_format() {
let tmp = tempfile::TempDir::new().unwrap();
cwshare_setup::create_cwshare_template(tmp.path(), &[]);
let content = std::fs::read_to_string(tmp.path().join(".cwshare")).unwrap();
assert!(content.contains("Files to copy to new worktrees"));
assert!(content.contains("gw new"));
}
#[test]
fn test_cwshare_template_commented_files() {
let tmp = tempfile::TempDir::new().unwrap();
let files = vec!["config/local.json".to_string()];
cwshare_setup::create_cwshare_template(tmp.path(), &files);
let content = std::fs::read_to_string(tmp.path().join(".cwshare")).unwrap();
assert!(content.contains("# config/local.json"));
assert!(content.contains("Detected files"));
}
#[test]
fn test_cwshare_template_creates_file() {
let tmp = tempfile::TempDir::new().unwrap();
assert!(!tmp.path().join(".cwshare").exists());
cwshare_setup::create_cwshare_template(tmp.path(), &[]);
assert!(tmp.path().join(".cwshare").exists());
}
#[test]
fn test_cwshare_template_overwrites() {
let tmp = tempfile::TempDir::new().unwrap();
std::fs::write(tmp.path().join(".cwshare"), "old content").unwrap();
cwshare_setup::create_cwshare_template(tmp.path(), &[]);
let content = std::fs::read_to_string(tmp.path().join(".cwshare")).unwrap();
assert!(!content.contains("old content"));
assert!(content.contains("# .cwshare"));
}
#[test]
fn test_cwshare_integration_copies_env() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
std::fs::write(tmp.path().join(".env"), "API_KEY=test123").unwrap();
std::fs::write(tmp.path().join(".cwshare"), ".env\n").unwrap();
let target = tmp.path().join("worktree-dir");
std::fs::create_dir(&target).unwrap();
git_worktree_manager::shared_files::share_files(tmp.path(), &target);
assert!(target.join(".env").exists());
let content = std::fs::read_to_string(target.join(".env")).unwrap();
assert_eq!(content, "API_KEY=test123");
}
#[test]
fn test_cwshare_integration_skips_existing() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
std::fs::write(tmp.path().join(".env"), "ORIGINAL=val").unwrap();
std::fs::write(tmp.path().join(".cwshare"), ".env\n").unwrap();
let target = tmp.path().join("worktree-dir");
std::fs::create_dir(&target).unwrap();
std::fs::write(target.join(".env"), "EXISTING=val").unwrap();
git_worktree_manager::shared_files::share_files(tmp.path(), &target);
let content = std::fs::read_to_string(target.join(".env")).unwrap();
assert_eq!(content, "EXISTING=val");
}
#[test]
fn test_cwshare_integration_no_cwshare_file() {
let tmp = tempfile::TempDir::new().unwrap();
let target = tmp.path().join("worktree-dir");
std::fs::create_dir(&target).unwrap();
git_worktree_manager::shared_files::share_files(tmp.path(), &target);
let entries: Vec<_> = std::fs::read_dir(&target).unwrap().collect();
assert!(entries.is_empty());
}
#[test]
fn test_cwshare_comments_ignored() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
std::fs::write(tmp.path().join(".env"), "VAL=1").unwrap();
std::fs::write(tmp.path().join(".cwshare"), "# .env\n").unwrap();
let target = tmp.path().join("worktree-dir");
std::fs::create_dir(&target).unwrap();
git_worktree_manager::shared_files::share_files(tmp.path(), &target);
assert!(!target.join(".env").exists());
}
#[test]
fn test_cwshare_empty_lines_ignored() {
let tmp = tempfile::TempDir::new().unwrap();
init_git_repo(tmp.path());
std::fs::write(tmp.path().join(".env"), "VAL=1").unwrap();
std::fs::write(tmp.path().join(".cwshare"), "\n\n.env\n\n").unwrap();
let target = tmp.path().join("worktree-dir");
std::fs::create_dir(&target).unwrap();
git_worktree_manager::shared_files::share_files(tmp.path(), &target);
assert!(target.join(".env").exists());
}
#[test]
fn test_cwshare_cli_worktree_copies_env() {
let repo = TestRepo::new();
std::fs::write(repo.path().join(".cwshare"), ".env\n").unwrap();
std::fs::write(repo.path().join(".env"), "SECRET=cli_test").unwrap();
let wt = repo.create_worktree("cwshare-cli");
assert!(
wt.join(".env").exists(),
".env should be copied to worktree via .cwshare"
);
assert_eq!(
std::fs::read_to_string(wt.join(".env")).unwrap(),
"SECRET=cli_test"
);
}
#[test]
fn test_cwshare_cli_no_cwshare_no_copy() {
let repo = TestRepo::new();
std::fs::write(repo.path().join(".env"), "SECRET=nope").unwrap();
let wt = repo.create_worktree("no-cwshare-cli");
assert!(
!wt.join(".env").exists(),
".env should not appear without .cwshare"
);
}
#[test]
fn test_cwshare_cli_multiple_files() {
let repo = TestRepo::new();
std::fs::write(repo.path().join(".cwshare"), ".env\n.env.local\n").unwrap();
std::fs::write(repo.path().join(".env"), "A=1").unwrap();
std::fs::write(repo.path().join(".env.local"), "B=2").unwrap();
let wt = repo.create_worktree("multi-cli");
assert!(wt.join(".env").exists());
assert!(wt.join(".env.local").exists());
}