stabilizaiton work - projects rework for maintenanceability and ui livening
This commit is contained in:
@@ -10,3 +10,4 @@ Source of truth: `docs-archived/implplan/2025-12-29-csproj-audit/SPRINT_20251229
|
||||
| AUDIT-0371-A | DONE | Waived (test project; revalidated 2026-01-07). |
|
||||
| AUDIT-TESTGAP-CORELIB-INTEROP-0001 | DONE | Added ToolManager unit tests + skip gating (2026-01-13). |
|
||||
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |
|
||||
| REMED-08 | DONE | Added stubbed ToolManager unit tests for deterministic path/process checks. |
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
using FluentAssertions;
|
||||
using StellaOps.Interop;
|
||||
using InteropToolResult = StellaOps.Interop.ToolResult;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Xunit;
|
||||
|
||||
namespace StellaOps.Interop.Tests;
|
||||
|
||||
public sealed class ToolManagerUnitTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task RunAsync_ReturnsFailure_WhenResolverReturnsNull()
|
||||
{
|
||||
var resolver = new StubPathResolver(null);
|
||||
var runner = new StubProcessRunner(InteropToolResult.Ok("ok", string.Empty, 0));
|
||||
var manager = new ToolManager("work", pathResolver: resolver, processRunner: runner);
|
||||
|
||||
var result = await manager.RunAsync("missing-tool", "--version", CancellationToken.None);
|
||||
|
||||
result.Success.Should().BeFalse();
|
||||
result.Error.Should().Be("Tool not found: missing-tool");
|
||||
runner.Calls.Should().Be(0);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task RunAsync_DelegatesToRunner()
|
||||
{
|
||||
var expected = InteropToolResult.Ok("out", "err", 0);
|
||||
var resolver = new StubPathResolver("/tmp/tool");
|
||||
var runner = new StubProcessRunner(expected);
|
||||
var manager = new ToolManager("work", pathResolver: resolver, processRunner: runner);
|
||||
|
||||
var result = await manager.RunAsync("stub-tool", "--help", CancellationToken.None);
|
||||
|
||||
result.Should().Be(expected);
|
||||
runner.Calls.Should().Be(1);
|
||||
runner.LastTool.Should().Be("stub-tool");
|
||||
runner.LastToolPath.Should().Be("/tmp/tool");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task VerifyToolAsync_ThrowsWhenRunnerFails()
|
||||
{
|
||||
var failure = InteropToolResult.Failed("boom");
|
||||
var resolver = new StubPathResolver("/tmp/tool");
|
||||
var runner = new StubProcessRunner(failure);
|
||||
var manager = new ToolManager("work", pathResolver: resolver, processRunner: runner);
|
||||
|
||||
var act = () => manager.VerifyToolAsync("stub-tool", "--help", CancellationToken.None);
|
||||
|
||||
var thrown = await act.Should().ThrowAsync<ToolExecutionException>();
|
||||
thrown.Which.Result.Should().Be(failure);
|
||||
}
|
||||
|
||||
private sealed class StubPathResolver : IToolPathResolver
|
||||
{
|
||||
private readonly string? _toolPath;
|
||||
|
||||
public StubPathResolver(string? toolPath)
|
||||
{
|
||||
_toolPath = toolPath;
|
||||
}
|
||||
|
||||
public string? ResolveToolPath(string tool) => _toolPath;
|
||||
}
|
||||
|
||||
private sealed class StubProcessRunner : IToolProcessRunner
|
||||
{
|
||||
private readonly InteropToolResult _result;
|
||||
|
||||
public StubProcessRunner(InteropToolResult result)
|
||||
{
|
||||
_result = result;
|
||||
}
|
||||
|
||||
public int Calls { get; private set; }
|
||||
|
||||
public string? LastTool { get; private set; }
|
||||
|
||||
public string? LastToolPath { get; private set; }
|
||||
|
||||
public Task<InteropToolResult> RunAsync(
|
||||
string tool,
|
||||
string toolPath,
|
||||
string args,
|
||||
string workingDirectory,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
Calls++;
|
||||
LastTool = tool;
|
||||
LastToolPath = toolPath;
|
||||
return Task.FromResult(_result);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user