Files
ClaudeDo/tests/ClaudeDo.Worker.Tests/Infrastructure/GitRepoFixture.cs
mika kuns 0da527dbbc test(worker): adapt planning tests to git-backed worktree flow
Update constructor calls (6-arg), seed AppSettings with sibling strategy,
git-init working dirs via GitRepoFixture.InitRepoWithInitialCommit, and
replace McpConfigPath assertions with worktree-path / .mcp.json checks.
Also fixes PlanningHubTests which had the same 3-arg constructor.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 12:14:46 +02:00

106 lines
3.2 KiB
C#

using System.Diagnostics;
namespace ClaudeDo.Worker.Tests.Infrastructure;
public sealed class GitRepoFixture : IDisposable
{
public string RepoDir { get; }
public string BaseCommit { get; }
public GitRepoFixture()
{
RepoDir = Path.Combine(Path.GetTempPath(), $"claudedo_gittest_{Guid.NewGuid():N}");
Directory.CreateDirectory(RepoDir);
RunGit(RepoDir, "init");
RunGit(RepoDir, "config", "user.name", "test");
RunGit(RepoDir, "config", "user.email", "test@example.com");
File.WriteAllText(Path.Combine(RepoDir, "README.md"), "# test repo");
RunGit(RepoDir, "add", "-A");
RunGit(RepoDir, "commit", "-m", "initial commit");
BaseCommit = RunGit(RepoDir, "rev-parse", "HEAD").Trim();
}
public void Dispose()
{
try
{
// Force-remove read-only .git objects on Windows.
ForceDeleteDirectory(RepoDir);
}
catch { /* best effort */ }
}
public static bool IsGitAvailable()
{
try
{
var psi = new ProcessStartInfo("git", "--version")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using var p = Process.Start(psi)!;
p.WaitForExit(5000);
return p.ExitCode == 0;
}
catch
{
return false;
}
}
internal static string RunGit(string workDir, params string[] args)
{
var psi = new ProcessStartInfo("git")
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
psi.ArgumentList.Add("-C");
psi.ArgumentList.Add(workDir);
foreach (var a in args) psi.ArgumentList.Add(a);
using var proc = Process.Start(psi)!;
var stdout = proc.StandardOutput.ReadToEnd();
var stderr = proc.StandardError.ReadToEnd();
proc.WaitForExit();
if (proc.ExitCode != 0)
throw new InvalidOperationException($"git {string.Join(' ', args)} failed: {stderr}");
return stdout;
}
/// <summary>
/// Creates a new git repo at <paramref name="dir"/> with a seed commit.
/// Used by planning tests that need a real git repo as list working directory.
/// </summary>
public static void InitRepoWithInitialCommit(string dir)
{
Directory.CreateDirectory(dir);
RunGit(dir, "init", "-b", "main");
RunGit(dir, "config", "user.email", "test@claudedo.local");
RunGit(dir, "config", "user.name", "test");
File.WriteAllText(Path.Combine(dir, "README.md"), "seed\n");
RunGit(dir, "add", "-A");
RunGit(dir, "commit", "-m", "chore: seed");
}
private static void ForceDeleteDirectory(string path)
{
if (!Directory.Exists(path)) return;
foreach (var file in Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories))
{
File.SetAttributes(file, FileAttributes.Normal);
}
Directory.Delete(path, true);
}
}