Files
ClaudeDo/tests/ClaudeDo.Worker.Tests/Lifecycle/RunningOperationRegistryTests.cs
T
mika kunsandClaude Sonnet 5.5 2dbec543df feat(mission-control): show running Worker operations in a Running now section
Registry of active verify/merge/rebase/worktree-creation operations in the Worker,
GetActiveOperations snapshot + OperationStarted/OperationEnded hub events, and a
Running now section in Mission Control with ticking elapsed time.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-01 12:08:43 +02:00

56 lines
1.7 KiB
C#

using ClaudeDo.Worker.Hub;
using ClaudeDo.Worker.Lifecycle;
using ClaudeDo.Worker.Tests.Services;
namespace ClaudeDo.Worker.Tests.Lifecycle;
public class RunningOperationRegistryTests
{
[Fact]
public void Begin_AddsEntry_DisposeRemovesIt_AndIsIdempotent()
{
var ops = new RunningOperationRegistry();
var scope = ops.Begin(OperationKinds.Merging, "title", taskId: "t1", taskNumber: 7);
var op = Assert.Single(ops.Snapshot());
Assert.Equal(OperationKinds.Merging, op.Kind);
Assert.Equal("t1", op.TaskId);
Assert.Equal(7, op.TaskNumber);
scope.Dispose();
scope.Dispose();
Assert.Empty(ops.Snapshot());
}
[Fact]
public void Entry_IsRemovedWhenTheOperationThrows()
{
var ops = new RunningOperationRegistry();
Action act = () =>
{
using var _ = ops.Begin(OperationKinds.Rebasing, "title", taskId: "t1");
Assert.Single(ops.Snapshot());
throw new InvalidOperationException("boom");
};
Assert.Throws<InvalidOperationException>(act);
Assert.Empty(ops.Snapshot());
}
[Fact]
public void BeginAndDispose_BroadcastStartedAndEnded()
{
var hub = new MergeRecordingHubContext();
var ops = new RunningOperationRegistry(new HubBroadcaster(hub));
var scope = ops.Begin(OperationKinds.CreatingWorktree, "title", taskId: "t1");
var id = ops.Snapshot().Single().Id;
scope.Dispose();
Assert.Collection(hub.Proxy.Calls,
c => { Assert.Equal("OperationStarted", c.Method); Assert.Equal(id, ((RunningOperationDto)c.Args[0]!).Id); },
c => { Assert.Equal("OperationEnded", c.Method); Assert.Equal(id, c.Args[0]); });
}
}