#![expect(clippy::unwrap_used, reason = "Tests should panic on failure")]
mod support;
use std::fs;
use tempfile::TempDir;
use thoughts_tool::git::clone::CloneOptions;
use thoughts_tool::git::clone::clone_repository;
fn init_bare_remote_with_commit() -> (TempDir, String) {
let remote_dir = TempDir::new().unwrap();
let remote_path = remote_dir.path().to_path_buf();
support::git_ok(&remote_path, &["init", "--bare", "."]);
let work = TempDir::new().unwrap();
support::git_ok(work.path(), &["init"]);
fs::write(work.path().join("README.md"), "hello").unwrap();
support::git_ok(work.path(), &["add", "."]);
support::git_ok(
work.path(),
&[
"-c",
"user.name=Test",
"-c",
"user.email=test@example.com",
"commit",
"-m",
"init",
],
);
support::git_ok(work.path(), &["branch", "-M", "main"]);
support::git_ok(
work.path(),
&["remote", "add", "origin", remote_path.to_str().unwrap()],
);
support::git_ok(
work.path(),
&["push", "-u", "origin", "HEAD:refs/heads/main"],
);
support::git_ok(work.path(), &["tag", "v1.0.0"]);
support::git_ok(work.path(), &["push", "origin", "refs/tags/v1.0.0"]);
support::git_ok(work.path(), &["checkout", "-b", "feature/demo"]);
fs::write(work.path().join("README.md"), "feature").unwrap();
support::git_ok(work.path(), &["add", "."]);
support::git_ok(
work.path(),
&[
"-c",
"user.name=Test",
"-c",
"user.email=test@example.com",
"commit",
"-m",
"feature",
],
);
support::git_ok(
work.path(),
&["push", "-u", "origin", "HEAD:refs/heads/feature/demo"],
);
(remote_dir, remote_path.to_string_lossy().into())
}
#[ignore = "integration test - run with: just test-integration"]
#[test]
fn clone_with_gitoxide_from_file_remote() {
let (_remote_guard, remote_path) = init_bare_remote_with_commit();
let target = TempDir::new().unwrap();
let opts = CloneOptions {
url: remote_path,
target_path: target.path().join("cloned"),
branch: Some("main".to_string()),
};
clone_repository(&opts).expect("clone should succeed");
assert!(target.path().join("cloned/.git").exists());
assert!(target.path().join("cloned/README.md").exists());
let content = fs::read_to_string(target.path().join("cloned/README.md")).unwrap();
assert_eq!(content, "hello");
}
#[ignore = "integration test - run with: just test-integration"]
#[test]
fn clone_creates_parent_directories() {
let (_remote_guard, remote_path) = init_bare_remote_with_commit();
let target = TempDir::new().unwrap();
let opts = CloneOptions {
url: remote_path,
target_path: target.path().join("deep/nested/path/cloned"),
branch: Some("main".to_string()),
};
clone_repository(&opts).expect("clone should succeed");
assert!(target.path().join("deep/nested/path/cloned/.git").exists());
}
#[ignore = "integration test - run with: just test-integration"]
#[test]
fn clone_fails_on_nonempty_directory() {
let (_remote_guard, remote_path) = init_bare_remote_with_commit();
let target = TempDir::new().unwrap();
let target_dir = target.path().join("cloned");
fs::create_dir_all(&target_dir).unwrap();
fs::write(target_dir.join("existing.txt"), "content").unwrap();
let opts = CloneOptions {
url: remote_path,
target_path: target_dir,
branch: Some("main".to_string()),
};
let result = clone_repository(&opts);
assert!(result.is_err());
assert!(result.unwrap_err().to_string().contains("not empty"));
}
#[ignore = "integration test - run with: just test-integration"]
#[test]
fn clone_named_branch_from_file_remote() {
let (_remote_guard, remote_path) = init_bare_remote_with_commit();
let target = TempDir::new().unwrap();
let opts = CloneOptions {
url: remote_path,
target_path: target.path().join("cloned-feature"),
branch: Some("refs/heads/feature/demo".to_string()),
};
clone_repository(&opts).expect("clone should succeed");
let content = fs::read_to_string(target.path().join("cloned-feature/README.md")).unwrap();
assert_eq!(content, "feature");
}
#[ignore = "integration test - run with: just test-integration"]
#[test]
fn clone_tag_ref_from_file_remote() {
let (_remote_guard, remote_path) = init_bare_remote_with_commit();
let target = TempDir::new().unwrap();
let opts = CloneOptions {
url: remote_path,
target_path: target.path().join("cloned-tag"),
branch: Some("refs/tags/v1.0.0".to_string()),
};
clone_repository(&opts).expect("clone should succeed");
let content = fs::read_to_string(target.path().join("cloned-tag/README.md")).unwrap();
assert_eq!(content, "hello");
}