Files
WizardMerge/backend/tests/test_git_cli.cpp
2025-12-29 18:45:12 +00:00

224 lines
6.2 KiB
C++

/**
* @file test_git_cli.cpp
* @brief Unit tests for Git CLI wrapper functionality
*/
#include "wizardmerge/git/git_cli.h"
#include <filesystem>
#include <fstream>
#include <gtest/gtest.h>
using namespace wizardmerge::git;
namespace fs = std::filesystem;
class GitCLITest : public ::testing::Test {
protected:
std::string test_dir;
void SetUp() override {
// Create temporary test directory using std::filesystem
std::filesystem::path temp_base = std::filesystem::temp_directory_path();
test_dir =
(temp_base / ("wizardmerge_git_test_" + std::to_string(time(nullptr))))
.string();
fs::create_directories(test_dir);
}
void TearDown() override {
// Clean up test directory
if (fs::exists(test_dir)) {
fs::remove_all(test_dir);
}
}
// Helper to initialize a git repo
void init_repo(const std::string &path) {
system(("git init \"" + path + "\" 2>&1 > /dev/null").c_str());
system(("git -C \"" + path + "\" config user.name \"Test User\"").c_str());
system(("git -C \"" + path + "\" config user.email \"test@example.com\"")
.c_str());
}
// Helper to create a file
void create_file(const std::string &path, const std::string &content) {
std::ofstream file(path);
file << content;
file.close();
}
};
/**
* Test Git availability check
*/
TEST_F(GitCLITest, GitAvailability) {
// Git should be available in CI environment
EXPECT_TRUE(is_git_available());
}
/**
* Test branch existence check
*/
TEST_F(GitCLITest, BranchExists) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Create initial commit (required for branch operations)
create_file(repo_path + "/test.txt", "initial content");
system(
("git -C \"" + repo_path + "\" add test.txt 2>&1 > /dev/null").c_str());
system(("git -C \"" + repo_path +
"\" commit -m \"Initial commit\" 2>&1 > /dev/null")
.c_str());
// Default branch should exist (main or master)
auto current_branch = get_current_branch(repo_path);
ASSERT_TRUE(current_branch.has_value());
EXPECT_TRUE(branch_exists(repo_path, current_branch.value()));
// Non-existent branch should not exist
EXPECT_FALSE(branch_exists(repo_path, "nonexistent-branch"));
}
/**
* Test getting current branch
*/
TEST_F(GitCLITest, GetCurrentBranch) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Create initial commit
create_file(repo_path + "/test.txt", "initial content");
system(
("git -C \"" + repo_path + "\" add test.txt 2>&1 > /dev/null").c_str());
system(("git -C \"" + repo_path +
"\" commit -m \"Initial commit\" 2>&1 > /dev/null")
.c_str());
auto branch = get_current_branch(repo_path);
ASSERT_TRUE(branch.has_value());
// Should be either "main" or "master" depending on Git version
EXPECT_TRUE(branch.value() == "main" || branch.value() == "master");
}
/**
* Test creating a new branch
*/
TEST_F(GitCLITest, CreateBranch) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Create initial commit
create_file(repo_path + "/test.txt", "initial content");
system(
("git -C \"" + repo_path + "\" add test.txt 2>&1 > /dev/null").c_str());
system(("git -C \"" + repo_path +
"\" commit -m \"Initial commit\" 2>&1 > /dev/null")
.c_str());
// Create new branch
GitResult result = create_branch(repo_path, "test-branch");
EXPECT_TRUE(result.success) << "Error: " << result.error;
// Verify we're on the new branch
auto current_branch = get_current_branch(repo_path);
ASSERT_TRUE(current_branch.has_value());
EXPECT_EQ(current_branch.value(), "test-branch");
// Verify branch exists
EXPECT_TRUE(branch_exists(repo_path, "test-branch"));
}
/**
* Test adding files
*/
TEST_F(GitCLITest, AddFiles) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Create test files
create_file(repo_path + "/file1.txt", "content1");
create_file(repo_path + "/file2.txt", "content2");
// Add files
GitResult result = add_files(repo_path, {"file1.txt", "file2.txt"});
EXPECT_TRUE(result.success) << "Error: " << result.error;
}
/**
* Test committing changes
*/
TEST_F(GitCLITest, Commit) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Create and add a file
create_file(repo_path + "/test.txt", "content");
add_files(repo_path, {"test.txt"});
// Commit
GitConfig config;
config.user_name = "Test User";
config.user_email = "test@example.com";
GitResult result = commit(repo_path, "Test commit", config);
EXPECT_TRUE(result.success) << "Error: " << result.error;
}
/**
* Test repository status
*/
TEST_F(GitCLITest, Status) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
GitResult result = status(repo_path);
EXPECT_TRUE(result.success);
EXPECT_FALSE(result.output.empty());
}
/**
* Test checkout branch
*/
TEST_F(GitCLITest, CheckoutBranch) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Create initial commit
create_file(repo_path + "/test.txt", "initial content");
system(
("git -C \"" + repo_path + "\" add test.txt 2>&1 > /dev/null").c_str());
system(("git -C \"" + repo_path +
"\" commit -m \"Initial commit\" 2>&1 > /dev/null")
.c_str());
// Create and switch to new branch
create_branch(repo_path, "test-branch");
// Get original branch
auto original_branch = get_current_branch(repo_path);
system(("git -C \"" + repo_path + "\" checkout " + original_branch.value() +
" 2>&1 > /dev/null")
.c_str());
// Checkout the test branch
GitResult result = checkout_branch(repo_path, "test-branch");
EXPECT_TRUE(result.success) << "Error: " << result.error;
// Verify we're on test-branch
auto current_branch = get_current_branch(repo_path);
ASSERT_TRUE(current_branch.has_value());
EXPECT_EQ(current_branch.value(), "test-branch");
}
/**
* Test empty file list
*/
TEST_F(GitCLITest, AddEmptyFileList) {
std::string repo_path = test_dir + "/test_repo";
init_repo(repo_path);
// Add empty file list should succeed without error
GitResult result = add_files(repo_path, {});
EXPECT_TRUE(result.success);
}