feat(ui): add skip-and-continue batch merge orchestration
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
using ClaudeDo.Data.Models;
|
||||
using ClaudeDo.Ui.Services;
|
||||
using ClaudeDo.Ui.ViewModels.Modals;
|
||||
using TaskStatus = ClaudeDo.Data.Models.TaskStatus;
|
||||
using Xunit;
|
||||
@@ -28,4 +29,89 @@ public class WorktreesOverviewBatchMergeTests
|
||||
row.MergeOutcome = BatchMergeOutcome.Merged;
|
||||
Assert.False(row.IsConflict);
|
||||
}
|
||||
|
||||
private static WorktreesOverviewModalViewModel NewVm() =>
|
||||
new(new ClaudeDo.Ui.Services.WorkerClient("http://127.0.0.1:1/hub"), () => null!);
|
||||
|
||||
private static MergeResultDto Merged() => new("merged", System.Array.Empty<string>(), null);
|
||||
private static MergeResultDto Conflict() => new("conflict", new[] { "f.cs" }, null);
|
||||
private static MergeResultDto Blocked() => new("blocked", System.Array.Empty<string>(), "blocked");
|
||||
|
||||
[Fact]
|
||||
public async System.Threading.Tasks.Task MergeSelected_only_processes_checked_active_rows()
|
||||
{
|
||||
var vm = NewVm();
|
||||
var a = ActiveRow("a"); a.IsChecked = true;
|
||||
var b = ActiveRow("b"); b.IsChecked = false;
|
||||
var c = ActiveRow("c"); c.IsChecked = true; c.State = WorktreeState.Merged;
|
||||
vm.Rows.Add(a); vm.Rows.Add(b); vm.Rows.Add(c);
|
||||
vm.SelectedTarget = "main";
|
||||
|
||||
var seen = new System.Collections.Generic.List<string>();
|
||||
await vm.MergeSelectedAsync((id, target, remove, msg) =>
|
||||
{
|
||||
seen.Add(id);
|
||||
Assert.Equal("main", target);
|
||||
Assert.False(remove);
|
||||
return System.Threading.Tasks.Task.FromResult(Merged());
|
||||
});
|
||||
|
||||
Assert.Equal(new[] { "a" }, seen);
|
||||
Assert.Equal(BatchMergeOutcome.Merged, a.MergeOutcome);
|
||||
Assert.False(a.IsChecked);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async System.Threading.Tasks.Task MergeSelected_continues_past_conflict_and_collects_it()
|
||||
{
|
||||
var vm = NewVm();
|
||||
var a = ActiveRow("a"); a.IsChecked = true;
|
||||
var b = ActiveRow("b"); b.IsChecked = true;
|
||||
var c = ActiveRow("c"); c.IsChecked = true;
|
||||
vm.Rows.Add(a); vm.Rows.Add(b); vm.Rows.Add(c);
|
||||
vm.SelectedTarget = "main";
|
||||
|
||||
await vm.MergeSelectedAsync((id, target, remove, msg) =>
|
||||
System.Threading.Tasks.Task.FromResult(id == "b" ? Conflict() : Merged()));
|
||||
|
||||
Assert.Equal(BatchMergeOutcome.Merged, a.MergeOutcome);
|
||||
Assert.Equal(BatchMergeOutcome.Conflict, b.MergeOutcome);
|
||||
Assert.Equal(BatchMergeOutcome.Merged, c.MergeOutcome);
|
||||
Assert.Contains(b, vm.ConflictRows);
|
||||
Assert.Single(vm.ConflictRows);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async System.Threading.Tasks.Task MergeSelected_maps_blocked_and_exception_to_failure_outcomes()
|
||||
{
|
||||
var vm = NewVm();
|
||||
var a = ActiveRow("a"); a.IsChecked = true;
|
||||
var b = ActiveRow("b"); b.IsChecked = true;
|
||||
vm.Rows.Add(a); vm.Rows.Add(b);
|
||||
vm.SelectedTarget = "main";
|
||||
|
||||
await vm.MergeSelectedAsync((id, target, remove, msg) => id == "a"
|
||||
? System.Threading.Tasks.Task.FromResult(Blocked())
|
||||
: throw new System.InvalidOperationException("boom"));
|
||||
|
||||
Assert.Equal(BatchMergeOutcome.Blocked, a.MergeOutcome);
|
||||
Assert.Equal(BatchMergeOutcome.Failed, b.MergeOutcome);
|
||||
Assert.Empty(vm.ConflictRows);
|
||||
Assert.False(vm.IsMerging);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async System.Threading.Tasks.Task MergeSelected_noop_when_no_target()
|
||||
{
|
||||
var vm = NewVm();
|
||||
var a = ActiveRow("a"); a.IsChecked = true;
|
||||
vm.Rows.Add(a);
|
||||
vm.SelectedTarget = null;
|
||||
|
||||
var called = false;
|
||||
await vm.MergeSelectedAsync((id, t, r, m) => { called = true; return System.Threading.Tasks.Task.FromResult(Merged()); });
|
||||
|
||||
Assert.False(called);
|
||||
Assert.Equal(BatchMergeOutcome.None, a.MergeOutcome);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user