sal-git 0.1.0

SAL Git - Git repository management and operations
Documentation
use sal_git::*;
use std::fs;
use tempfile::TempDir;

#[test]
fn test_clone_existing_repository() {
    let temp_dir = TempDir::new().unwrap();
    let base_path = temp_dir.path().to_str().unwrap();

    let git_tree = GitTree::new(base_path).unwrap();

    // First clone
    let result1 = git_tree.get("https://github.com/octocat/Hello-World.git");

    // Second clone of same repo - should return existing
    let result2 = git_tree.get("https://github.com/octocat/Hello-World.git");

    match (result1, result2) {
        (Ok(repos1), Ok(repos2)) => {
            // git_tree.get() returns Vec<GitRepo>, should have exactly 1 repo
            assert_eq!(
                repos1.len(),
                1,
                "First clone should return exactly 1 repository"
            );
            assert_eq!(
                repos2.len(),
                1,
                "Second clone should return exactly 1 repository"
            );
            assert_eq!(
                repos1[0].path(),
                repos2[0].path(),
                "Both clones should point to same path"
            );

            // Verify the path actually exists
            assert!(
                std::path::Path::new(repos1[0].path()).exists(),
                "Repository path should exist"
            );
        }
        (Err(e1), Err(e2)) => {
            // Both failed - acceptable if network/git issues
            println!("Note: Clone test skipped due to errors: {} / {}", e1, e2);
        }
        _ => {
            panic!(
                "Inconsistent results: one clone succeeded, other failed - this indicates a bug"
            );
        }
    }
}

#[test]
fn test_repository_operations_on_cloned_repo() {
    let temp_dir = TempDir::new().unwrap();
    let base_path = temp_dir.path().to_str().unwrap();

    let git_tree = GitTree::new(base_path).unwrap();

    match git_tree.get("https://github.com/octocat/Hello-World.git") {
        Ok(repos) if repos.len() == 1 => {
            let repo = &repos[0];

            // Test has_changes on fresh clone
            match repo.has_changes() {
                Ok(has_changes) => assert!(!has_changes, "Fresh clone should have no changes"),
                Err(_) => println!("Note: has_changes test skipped due to git availability"),
            }

            // Test path is valid
            assert!(repo.path().len() > 0);
            assert!(std::path::Path::new(repo.path()).exists());
        }
        _ => {
            println!(
                "Note: Repository operations test skipped due to network/environment constraints"
            );
        }
    }
}

#[test]
fn test_multiple_repositories_in_git_tree() {
    let temp_dir = TempDir::new().unwrap();
    let base_path = temp_dir.path().to_str().unwrap();

    // Create some fake git repositories for testing
    let repo1_path = temp_dir.path().join("github.com/user1/repo1");
    let repo2_path = temp_dir.path().join("github.com/user2/repo2");

    fs::create_dir_all(&repo1_path).unwrap();
    fs::create_dir_all(&repo2_path).unwrap();
    fs::create_dir_all(repo1_path.join(".git")).unwrap();
    fs::create_dir_all(repo2_path.join(".git")).unwrap();

    let git_tree = GitTree::new(base_path).unwrap();
    let repos = git_tree.list().unwrap();

    assert!(repos.len() >= 2, "Should find at least 2 repositories");
}

#[test]
fn test_invalid_git_repository_handling() {
    let temp_dir = TempDir::new().unwrap();
    let fake_repo_path = temp_dir.path().join("fake_repo");
    fs::create_dir_all(&fake_repo_path).unwrap();

    // Create a directory that looks like a repo but isn't (no .git directory)
    let repo = GitRepo::new(fake_repo_path.to_str().unwrap().to_string());

    // Operations should fail gracefully on non-git directories
    // Note: has_changes might succeed if git is available and treats it as empty repo
    // So we test the operations that definitely require .git directory
    assert!(
        repo.pull().is_err(),
        "Pull should fail on non-git directory"
    );
    assert!(
        repo.reset().is_err(),
        "Reset should fail on non-git directory"
    );
}