feat(interactive): New session button for ad-hoc ConPTY sessions
Adds a 'New session' header button in Mission Control that opens a folder picker and starts a task-less embedded ConPTY session in the chosen directory. ConPtyPaneViewModel TaskId is now nullable (ad-hoc panes have no task and are never deduped) with a CreateAdHoc factory; the view does the picking, the VM stays picker-agnostic.
This commit is contained in:
@@ -341,6 +341,71 @@ public class MissionControlViewModelTests : IDisposable
|
||||
Assert.Empty(vm.Panes);
|
||||
}
|
||||
|
||||
private sealed class ThrowingAdHocLaunchSpecWorker : StubWorkerClient
|
||||
{
|
||||
public override Task<LaunchSpec> GetAdHocLaunchSpecAsync(string directory, CancellationToken ct = default)
|
||||
=> throw new InvalidOperationException("bad directory");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenAdHocConPtySessionAsync_AddsPane_TitleFromDirectoryLeaf()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = BuildVm(worker);
|
||||
|
||||
await vm.OpenAdHocConPtySessionAsync(Path.Combine("C:", "Some", "Path", "MyProject"));
|
||||
|
||||
Assert.Single(vm.ConPtySessions);
|
||||
Assert.Null(vm.ConPtySessions[0].TaskId);
|
||||
Assert.Equal("MyProject", vm.ConPtySessions[0].DisplayTitle);
|
||||
Assert.Single(vm.Panes);
|
||||
Assert.Same(vm.ConPtySessions[0], vm.Panes[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenAdHocConPtySessionAsync_TwoOpens_NeverDeduped_YieldsTwoPanes()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = BuildVm(worker);
|
||||
|
||||
var dir = Path.Combine("C:", "Some", "Path");
|
||||
await vm.OpenAdHocConPtySessionAsync(dir);
|
||||
await vm.OpenAdHocConPtySessionAsync(dir);
|
||||
|
||||
Assert.Equal(2, vm.ConPtySessions.Count);
|
||||
Assert.Equal(2, vm.Panes.Count);
|
||||
Assert.All(vm.ConPtySessions, s => Assert.Null(s.TaskId));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task OpenAdHocConPtySessionAsync_WorkerThrows_RaisesErrorReported_NoPaneAdded()
|
||||
{
|
||||
var worker = new ThrowingAdHocLaunchSpecWorker();
|
||||
using var vm = BuildVm(worker);
|
||||
string? error = null;
|
||||
vm.ErrorReported += msg => error = msg;
|
||||
|
||||
await vm.OpenAdHocConPtySessionAsync(Path.Combine("C:", "Some", "Path"));
|
||||
|
||||
Assert.Empty(vm.ConPtySessions);
|
||||
Assert.Empty(vm.Panes);
|
||||
Assert.NotNull(error);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CloseConPtySession_RemovesAdHocPane_FromConPtySessionsAndPanes()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = BuildVm(worker);
|
||||
await vm.OpenAdHocConPtySessionAsync(Path.Combine("C:", "Some", "Path"));
|
||||
var pane = vm.ConPtySessions[0];
|
||||
|
||||
pane.CloseCommand.Execute(null);
|
||||
|
||||
Assert.Empty(vm.ConPtySessions);
|
||||
Assert.Empty(vm.Panes);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ToggleLayoutCommand_FlipsIsFocusMode()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user