44 lines
1.6 KiB
C#
44 lines
1.6 KiB
C#
using ClaudeDo.Worker.Skills;
|
|
|
|
namespace ClaudeDo.Worker.Tests.Skills;
|
|
|
|
/// <summary>
|
|
/// Test double for IRepoCloner: "clones" by copying a pre-built local fixture directory,
|
|
/// so tests never touch the network or invoke real git. One fixture dir + pinned ref can
|
|
/// be registered per source URL.
|
|
/// </summary>
|
|
public sealed class FakeRepoCloner : IRepoCloner
|
|
{
|
|
private readonly Dictionary<string, (string FixtureDir, string PinnedRef)> _sources = new();
|
|
private int _cloneCount;
|
|
|
|
public int CloneCount => _cloneCount;
|
|
|
|
public void Register(string url, string fixtureDir, string pinnedRef) =>
|
|
_sources[url] = (fixtureDir, pinnedRef);
|
|
|
|
public Task<ClonedRepo> CloneAsync(string url, string destDir, CancellationToken ct)
|
|
{
|
|
_cloneCount++;
|
|
if (!_sources.TryGetValue(url, out var source))
|
|
throw new InvalidOperationException($"FakeRepoCloner has no fixture registered for '{url}'.");
|
|
|
|
CopyDirectory(source.FixtureDir, destDir);
|
|
return Task.FromResult(new ClonedRepo(destDir, source.PinnedRef));
|
|
}
|
|
|
|
private static void CopyDirectory(string sourceDir, string destDir)
|
|
{
|
|
Directory.CreateDirectory(destDir);
|
|
foreach (var file in Directory.EnumerateFiles(sourceDir, "*", SearchOption.AllDirectories))
|
|
{
|
|
var relative = Path.GetRelativePath(sourceDir, file);
|
|
var destPath = Path.Combine(destDir, relative);
|
|
var destParent = Path.GetDirectoryName(destPath);
|
|
if (!string.IsNullOrEmpty(destParent))
|
|
Directory.CreateDirectory(destParent);
|
|
File.Copy(file, destPath, overwrite: true);
|
|
}
|
|
}
|
|
}
|