aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuben Beltran del Rio <git@r.bdr.sh>2025-01-07 21:18:59 +0100
committerRuben Beltran del Rio <git@r.bdr.sh>2025-01-07 21:18:59 +0100
commit1016849fce02a25f35fb00ce80ba1021eb54fe08 (patch)
tree96c27f700488d42553359c20c0eb782185643997 /src
parent9c537e473ac117eadad86b68d21f3aaf8d8937c4 (diff)
Add tests for git remote
Diffstat (limited to 'src')
-rw-r--r--src/remote/git.rs207
1 files changed, 207 insertions, 0 deletions
diff --git a/src/remote/git.rs b/src/remote/git.rs
index 5a79164..d15e002 100644
--- a/src/remote/git.rs
+++ b/src/remote/git.rs
@@ -71,3 +71,210 @@ impl super::Remote for Git {
Ok(())
}
}
+
+#[cfg(test)]
+mod tests {
+ use std::fs::create_dir_all;
+ use std::path::Path;
+ use std::process::{Command, Stdio};
+
+ use super::*;
+ use crate::remote::Remote;
+
+ use test_utilities::*;
+
+ fn create_remote(path: &Path) {
+ let remote_path = path.display();
+ Command::new("sh")
+ .arg("-c")
+ .arg(&format!("cd {remote_path} && git init --bare"))
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .status()
+ .expect("Failed to initialize bare repository");
+ }
+
+ fn assert_file_does_not_exist(repo_path: &str, file_path: &str) {
+ let output = Command::new("sh")
+ .arg("-c")
+ .arg(&format!("cd {repo_path} && git show main:{file_path}"))
+ .stderr(Stdio::null())
+ .output()
+ .expect("Failed to read from repo");
+
+ assert!(output.status.code().unwrap() != 0);
+ }
+
+ fn assert_file_in_repo_with_contents(repo_path: &str, file_path: &str, contents: &str) {
+ let output = Command::new("sh")
+ .arg("-c")
+ .arg(&format!("cd {repo_path} && git show main:{file_path}"))
+ .stderr(Stdio::null())
+ .output()
+ .expect("Failed to read from repo");
+
+ assert!(String::from_utf8(output.stdout)
+ .map(|file| file.trim() == contents)
+ .unwrap_or(false));
+ }
+
+ fn commit_file_to_remote(repo_path: &str, file_path: &str, contents: &str) {
+ let test_dir = setup_test_dir();
+ let test_dir_display = test_dir.display();
+
+ Command::new("sh")
+ .arg("-c")
+ .arg(&format!(
+ "cd {test_dir_display} && \
+ git clone {repo_path} . && \
+ echo '{contents}' > {file_path} && \
+ git add {file_path} && \
+ git -c user.name='test' -c user.email='test@example.com' commit -m 'test commit' && \
+ git push origin main",
+ ))
+ .stdout(Stdio::null())
+ .stderr(Stdio::null())
+ .status()
+ .expect("Failed to commit file");
+
+ cleanup_test_dir(&test_dir);
+ }
+
+ #[test]
+ fn test_dummy_handle() {
+ let git = Git::new();
+ let can_handle = git.can_handle("anything");
+ assert!(can_handle);
+ }
+
+ #[test]
+ fn test_syncs_remote_up() {
+ let git = Git::new();
+ let test_dir = setup_test_dir();
+ let local_dir = test_dir.join("local");
+ let remote_dir = test_dir.join("remote");
+ create_dir_all(&local_dir).expect("Could not create local test directory");
+ create_dir_all(&remote_dir).expect("Could not create remote test directory");
+
+ create_remote(&remote_dir);
+
+ let remote_dir_as_string = remote_dir.display().to_string();
+
+ create_test_file(&local_dir.join("file1.txt"), "I exist");
+ git.sync_up(&remote_dir_as_string, &local_dir)
+ .expect("Could not sync up to remote");
+ assert_file_in_repo_with_contents(&remote_dir_as_string, "file1.txt", "I exist");
+ assert_file_does_not_exist(&remote_dir_as_string, "file2.txt");
+
+ create_test_file(&local_dir.join("file2.txt"), "I also exist now, btw");
+ git.sync_up(&remote_dir_as_string, &local_dir)
+ .expect("Could not sync up to remote");
+ assert_file_in_repo_with_contents(&remote_dir_as_string, "file1.txt", "I exist");
+ assert_file_in_repo_with_contents(&remote_dir_as_string, "file2.txt", "I also exist now, btw");
+ }
+
+ #[test]
+ fn test_remote_up_force_pushes() {
+ let git = Git::new();
+ let test_dir = setup_test_dir();
+ let local_dir = test_dir.join("local");
+ let remote_dir = test_dir.join("remote");
+ create_dir_all(&local_dir).expect("Could not create local test directory");
+ create_dir_all(&remote_dir).expect("Could not create remote test directory");
+
+ create_remote(&remote_dir);
+
+ let remote_dir_as_string = remote_dir.display().to_string();
+ commit_file_to_remote(&remote_dir_as_string, "boo.txt", "A ghost");
+
+ assert_file_does_not_exist(&remote_dir_as_string, "file1.txt");
+ assert_file_in_repo_with_contents(&remote_dir_as_string, "boo.txt", "A ghost");
+
+ create_test_file(&local_dir.join("file1.txt"), "I exist");
+ git.sync_up(&remote_dir_as_string, &local_dir)
+ .expect("Could not sync up to remote");
+
+ assert_file_in_repo_with_contents(&remote_dir_as_string, "file1.txt", "I exist");
+ assert_file_does_not_exist(&remote_dir_as_string, "boo.txt");
+ }
+
+ #[test]
+ fn test_sync_up_fails_with_an_invalid_remote() {
+ let git = Git::new();
+ let test_dir = setup_test_dir();
+ let local_dir = test_dir.join("local");
+ create_dir_all(&local_dir).expect("Could not create local test directory");
+
+ let invalid_remote = String::from("test\0");
+
+ let result = git.sync_up(&invalid_remote, &local_dir);
+
+ assert!(result.is_err());
+ }
+
+ #[test]
+ fn test_syncs_remote_down() {
+ let git = Git::new();
+ let test_dir = setup_test_dir();
+ let local_dir = test_dir.join("local");
+ let remote_dir = test_dir.join("remote");
+ create_dir_all(&local_dir).expect("Could not create local test directory");
+ create_dir_all(&remote_dir).expect("Could not create remote test directory");
+
+ create_remote(&remote_dir);
+
+ let remote_dir_as_string = remote_dir.display().to_string();
+
+ commit_file_to_remote(&remote_dir_as_string, "file1.txt", "I exist, but remotely");
+ assert!(!&local_dir.join("file1.txt").exists());
+ assert!(!&local_dir.join("file2.txt").exists());
+ git.sync_down(&remote_dir_as_string, &local_dir)
+ .expect("Could not sync down from remote");
+ assert_file_contents(&local_dir.join("file1.txt"), "I exist, but remotely");
+ assert!(!&local_dir.join("file2.txt").exists());
+
+ commit_file_to_remote(&remote_dir_as_string, "file2.txt", "I also exist, but remotely");
+ assert!(!&local_dir.join("file2.txt").exists());
+ git.sync_down(&remote_dir_as_string, &local_dir)
+ .expect("Could not sync down from remote");
+ assert_file_contents(&local_dir.join("file1.txt"), "I exist, but remotely");
+ assert_file_contents(&local_dir.join("file2.txt"), "I also exist, but remotely");
+ }
+
+ #[test]
+ fn test_sync_down_overwrites_local() {
+ let git = Git::new();
+ let test_dir = setup_test_dir();
+ let local_dir = test_dir.join("local");
+ let remote_dir = test_dir.join("remote");
+ create_dir_all(&local_dir).expect("Could not create local test directory");
+ create_dir_all(&remote_dir).expect("Could not create remote test directory");
+
+ create_remote(&remote_dir);
+
+ let remote_dir_as_string = remote_dir.display().to_string();
+
+ create_test_file(&local_dir.join("nooo.txt"), "I will no longer exist");
+ commit_file_to_remote(&remote_dir_as_string, "file1.txt", "I exist, but remotely");
+ assert!(&local_dir.join("nooo.txt").exists());
+ assert!(!&local_dir.join("file1.txt").exists());
+ git.sync_down(&remote_dir_as_string, &local_dir)
+ .expect("Could not sync down from remote");
+ assert_file_contents(&local_dir.join("file1.txt"), "I exist, but remotely");
+ assert!(!&local_dir.join("nooo.txt").exists());
+ }
+
+ #[test]
+ fn test_sync_down_fails_with_an_invalid_remote() {
+ let git = Git::new();
+ let test_dir = setup_test_dir();
+ let local_dir = test_dir.join("local");
+ create_dir_all(&local_dir).expect("Could not create local test directory");
+
+ let invalid_remote = String::from("test\0");
+
+ let result = git.sync_down(&invalid_remote, &local_dir);
+
+ assert!(result.is_err());
+ }
+}