test(panes): satisfy eject lint checks
- commit
- 84bb9d408e6f6b33591da3481d4d9c180e9a4578
- author
- brice · · 2026-06-18 11:17 UTC
- parent
- 54d60a9
- signature
- GPG Verified
CD88F9E564E0102646FB6077A1A07C7C7C3E349D· arch-gpg Verified for the committer email
2 files · +74 -51
M internal/application/usecase/extract_pane_to_tab_list_test.go +6 -6
| @@ -15,7 +15,7 @@ func TestExtractPaneToTabList_FromThreePaneStack(t *testing.T) { | |||
| 15 | 15 | paneA := entity.NewPane(entity.PaneID("pA")) | |
| 16 | 16 | paneB := entity.NewPane(entity.PaneID("pB")) | |
| 17 | 17 | paneC := entity.NewPane(entity.PaneID("pC")) | |
| 18 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB, paneC) | |
| 18 | + | sourceTab := newStackedTab(paneA, paneB, paneC) | |
| 19 | 19 | sourceTab.Workspace.ActivePaneID = paneB.ID | |
| 20 | 20 | sourceTabs.Add(sourceTab) | |
| 21 | 21 | ||
| @@ -53,7 +53,7 @@ func TestExtractPaneToTabList_FromThreePaneStackUsesWorkspaceActivePaneWhenStack | |||
| 53 | 53 | paneA := entity.NewPane(entity.PaneID("pA")) | |
| 54 | 54 | paneB := entity.NewPane(entity.PaneID("pB")) | |
| 55 | 55 | paneC := entity.NewPane(entity.PaneID("pC")) | |
| 56 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB, paneC) | |
| 56 | + | sourceTab := newStackedTab(paneA, paneB, paneC) | |
| 57 | 57 | // ActivePaneID is the workspace source of truth, but stacked UI state can lag. | |
| 58 | 58 | // Eject should remove pB deterministically and activate the pane that takes its slot. | |
| 59 | 59 | sourceTab.Workspace.ActivePaneID = paneB.ID | |
| @@ -85,7 +85,7 @@ func TestExtractPaneToTabList_FromTwoPaneStackDissolvesSource(t *testing.T) { | |||
| 85 | 85 | ||
| 86 | 86 | paneA := entity.NewPane(entity.PaneID("pA")) | |
| 87 | 87 | paneB := entity.NewPane(entity.PaneID("pB")) | |
| 88 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB) | |
| 88 | + | sourceTab := newStackedTab(paneA, paneB) | |
| 89 | 89 | sourceTab.Workspace.ActivePaneID = paneB.ID | |
| 90 | 90 | sourceTabs.Add(sourceTab) | |
| 91 | 91 | ||
| @@ -333,7 +333,7 @@ func TestExtractPaneToTabList_ParentPointerTreeIntegrity(t *testing.T) { | |||
| 333 | 333 | paneA := entity.NewPane(entity.PaneID("pA")) | |
| 334 | 334 | paneB := entity.NewPane(entity.PaneID("pB")) | |
| 335 | 335 | paneC := entity.NewPane(entity.PaneID("pC")) | |
| 336 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB, paneC) | |
| 336 | + | sourceTab := newStackedTab(paneA, paneB, paneC) | |
| 337 | 337 | sourceTabs.Add(sourceTab) | |
| 338 | 338 | ||
| 339 | 339 | out, err := uc.Execute(ExtractPaneToTabListInput{ | |
| @@ -349,8 +349,8 @@ func TestExtractPaneToTabList_ParentPointerTreeIntegrity(t *testing.T) { | |||
| 349 | 349 | require.Nil(t, out.MovedPaneNode.Parent) | |
| 350 | 350 | } | |
| 351 | 351 | ||
| 352 | - | func newStackedTab(tabID entity.TabID, workspaceID entity.WorkspaceID, panes ...*entity.Pane) *entity.Tab { | |
| 353 | - | tab := entity.NewTab(tabID, workspaceID, panes[0]) | |
| 352 | + | func newStackedTab(panes ...*entity.Pane) *entity.Tab { | |
| 353 | + | tab := entity.NewTab("tA", "wA", panes[0]) | |
| 354 | 354 | stack := &entity.PaneNode{ID: "stack", IsStacked: true, ActiveStackIndex: 0} | |
| 355 | 355 | for _, pane := range panes { | |
| 356 | 356 | child := &entity.PaneNode{ID: string(pane.ID), Pane: pane, Parent: stack} | |
| @@ -15,7 +15,7 @@ func TestExtractPaneToTabList_FromThreePaneStack(t *testing.T) { | |||||
| 15 | paneA := entity.NewPane(entity.PaneID("pA")) | 15 | paneA := entity.NewPane(entity.PaneID("pA")) | ||
| 16 | paneB := entity.NewPane(entity.PaneID("pB")) | 16 | paneB := entity.NewPane(entity.PaneID("pB")) | ||
| 17 | paneC := entity.NewPane(entity.PaneID("pC")) | 17 | paneC := entity.NewPane(entity.PaneID("pC")) | ||
| 18 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB, paneC) | 18 | + | sourceTab := newStackedTab(paneA, paneB, paneC) |
| 19 | sourceTab.Workspace.ActivePaneID = paneB.ID | 19 | sourceTab.Workspace.ActivePaneID = paneB.ID | ||
| 20 | sourceTabs.Add(sourceTab) | 20 | sourceTabs.Add(sourceTab) | ||
| 21 | 21 | ||||
| @@ -53,7 +53,7 @@ func TestExtractPaneToTabList_FromThreePaneStackUsesWorkspaceActivePaneWhenStack | |||||
| 53 | paneA := entity.NewPane(entity.PaneID("pA")) | 53 | paneA := entity.NewPane(entity.PaneID("pA")) | ||
| 54 | paneB := entity.NewPane(entity.PaneID("pB")) | 54 | paneB := entity.NewPane(entity.PaneID("pB")) | ||
| 55 | paneC := entity.NewPane(entity.PaneID("pC")) | 55 | paneC := entity.NewPane(entity.PaneID("pC")) | ||
| 56 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB, paneC) | 56 | + | sourceTab := newStackedTab(paneA, paneB, paneC) |
| 57 | // ActivePaneID is the workspace source of truth, but stacked UI state can lag. | 57 | // ActivePaneID is the workspace source of truth, but stacked UI state can lag. | ||
| 58 | // Eject should remove pB deterministically and activate the pane that takes its slot. | 58 | // Eject should remove pB deterministically and activate the pane that takes its slot. | ||
| 59 | sourceTab.Workspace.ActivePaneID = paneB.ID | 59 | sourceTab.Workspace.ActivePaneID = paneB.ID | ||
| @@ -85,7 +85,7 @@ func TestExtractPaneToTabList_FromTwoPaneStackDissolvesSource(t *testing.T) { | |||||
| 85 | 85 | ||||
| 86 | paneA := entity.NewPane(entity.PaneID("pA")) | 86 | paneA := entity.NewPane(entity.PaneID("pA")) | ||
| 87 | paneB := entity.NewPane(entity.PaneID("pB")) | 87 | paneB := entity.NewPane(entity.PaneID("pB")) | ||
| 88 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB) | 88 | + | sourceTab := newStackedTab(paneA, paneB) |
| 89 | sourceTab.Workspace.ActivePaneID = paneB.ID | 89 | sourceTab.Workspace.ActivePaneID = paneB.ID | ||
| 90 | sourceTabs.Add(sourceTab) | 90 | sourceTabs.Add(sourceTab) | ||
| 91 | 91 | ||||
| @@ -333,7 +333,7 @@ func TestExtractPaneToTabList_ParentPointerTreeIntegrity(t *testing.T) { | |||||
| 333 | paneA := entity.NewPane(entity.PaneID("pA")) | 333 | paneA := entity.NewPane(entity.PaneID("pA")) | ||
| 334 | paneB := entity.NewPane(entity.PaneID("pB")) | 334 | paneB := entity.NewPane(entity.PaneID("pB")) | ||
| 335 | paneC := entity.NewPane(entity.PaneID("pC")) | 335 | paneC := entity.NewPane(entity.PaneID("pC")) | ||
| 336 | - | sourceTab := newStackedTab("tA", "wA", paneA, paneB, paneC) | 336 | + | sourceTab := newStackedTab(paneA, paneB, paneC) |
| 337 | sourceTabs.Add(sourceTab) | 337 | sourceTabs.Add(sourceTab) | ||
| 338 | 338 | ||||
| 339 | out, err := uc.Execute(ExtractPaneToTabListInput{ | 339 | out, err := uc.Execute(ExtractPaneToTabListInput{ | ||
| @@ -349,8 +349,8 @@ func TestExtractPaneToTabList_ParentPointerTreeIntegrity(t *testing.T) { | |||||
| 349 | require.Nil(t, out.MovedPaneNode.Parent) | 349 | require.Nil(t, out.MovedPaneNode.Parent) | ||
| 350 | } | 350 | } | ||
| 351 | 351 | ||||
| 352 | - | func newStackedTab(tabID entity.TabID, workspaceID entity.WorkspaceID, panes ...*entity.Pane) *entity.Tab { | 352 | + | func newStackedTab(panes ...*entity.Pane) *entity.Tab { |
| 353 | - | tab := entity.NewTab(tabID, workspaceID, panes[0]) | 353 | + | tab := entity.NewTab("tA", "wA", panes[0]) |
| 354 | stack := &entity.PaneNode{ID: "stack", IsStacked: true, ActiveStackIndex: 0} | 354 | stack := &entity.PaneNode{ID: "stack", IsStacked: true, ActiveStackIndex: 0} | ||
| 355 | for _, pane := range panes { | 355 | for _, pane := range panes { | ||
| 356 | child := &entity.PaneNode{ID: string(pane.ID), Pane: pane, Parent: stack} | 356 | child := &entity.PaneNode{ID: string(pane.ID), Pane: pane, Parent: stack} | ||
M internal/ui/app_eject_pane_to_window_test.go +68 -45
| @@ -139,51 +139,9 @@ func TestApp_EjectActivePaneToWindowHandlesThreePaneSplitTree(t *testing.T) { | |||
| 139 | 139 | t.Fatalf("EjectActivePaneToWindow returned error: %v", err) | |
| 140 | 140 | } | |
| 141 | 141 | ||
| 142 | - | if got := len(app.browserWindows); got != 2 { | |
| 143 | - | t.Fatalf("browserWindows length = %d, want source and target", got) | |
| 144 | - | } | |
| 145 | - | if app.browserWindows[sourceWindow.id] == nil { | |
| 146 | - | t.Fatal("source window should remain registered") | |
| 147 | - | } | |
| 148 | - | if got := sourceTab.Workspace.PaneCount(); got != 2 { | |
| 149 | - | t.Fatalf("source pane count = %d, want 2", got) | |
| 150 | - | } | |
| 151 | - | if sourceTab.Workspace.FindPane("pane-a") == nil || sourceTab.Workspace.FindPane("pane-b") == nil { | |
| 152 | - | t.Fatal("source workspace missing remaining split panes") | |
| 153 | - | } | |
| 154 | - | if got := sourceTab.Workspace.FindPane("pane-c"); got != nil { | |
| 155 | - | t.Fatal("source workspace still contains moved split pane") | |
| 156 | - | } | |
| 157 | - | if got := sourceTab.Workspace.ActivePaneID; got != entity.PaneID("pane-b") { | |
| 158 | - | t.Fatalf("source active pane = %q, want pane-b", got) | |
| 159 | - | } | |
| 160 | - | if sourceTab.Workspace.Root == nil || sourceTab.Workspace.Root.ID != "left-split" || !sourceTab.Workspace.Root.IsSplit() { | |
| 161 | - | t.Fatalf("source root = %#v, want promoted left split", sourceTab.Workspace.Root) | |
| 162 | - | } | |
| 163 | - | if got := sourceTab.Workspace.Root.Parent; got != nil { | |
| 164 | - | t.Fatalf("source root parent = %#v, want nil", got) | |
| 165 | - | } | |
| 166 | - | if got := sourceTab.Workspace.Root.Left(); got == nil || got.Pane == nil || got.Pane.ID != entity.PaneID("pane-a") { | |
| 167 | - | t.Fatalf("source left leaf = %#v, want pane-a", got) | |
| 168 | - | } | |
| 169 | - | if got := sourceTab.Workspace.Root.Right(); got == nil || got.Pane == nil || got.Pane.ID != entity.PaneID("pane-b") { | |
| 170 | - | t.Fatalf("source right leaf = %#v, want pane-b", got) | |
| 171 | - | } | |
| 172 | - | assertPaneTreeParents(t, sourceTab.Workspace.Root, nil) | |
| 173 | - | targetWindow := app.browserWindows["target-window"] | |
| 174 | - | if targetWindow == nil || targetWindow.tabs.Count() != 1 { | |
| 175 | - | t.Fatalf("target window/tabs not created correctly: %#v", targetWindow) | |
| 176 | - | } | |
| 177 | - | newTab := targetWindow.tabs.Tabs[0] | |
| 178 | - | if got := newTab.Workspace.ActivePaneID; got != entity.PaneID("pane-c") { | |
| 179 | - | t.Fatalf("target active pane = %q, want pane-c", got) | |
| 180 | - | } | |
| 181 | - | if got := newTab.Workspace.Root.Parent; got != nil { | |
| 182 | - | t.Fatalf("target root parent = %#v, want nil", got) | |
| 183 | - | } | |
| 184 | - | if got := app.windowForTab[newTab.ID]; got != targetWindow { | |
| 185 | - | t.Fatalf("target owner = %p, want target window %p", got, targetWindow) | |
| 186 | - | } | |
| 142 | + | assertEjectWindowCount(t, app, sourceWindow) | |
| 143 | + | assertEjectedThreePaneSplitSource(t, sourceTab) | |
| 144 | + | assertEjectedThreePaneSplitTarget(t, app, "pane-c") | |
| 187 | 145 | } | |
| 188 | 146 | ||
| 189 | 147 | func TestApp_EjectActivePaneToWindowSnapshotReplacesEmptySourceWindow(t *testing.T) { | |
| @@ -342,6 +300,71 @@ func stackedTab(tabID entity.TabID, workspaceID entity.WorkspaceID, paneIDs ...e | |||
| 342 | 300 | return &entity.Tab{ID: tabID, Workspace: workspace} | |
| 343 | 301 | } | |
| 344 | 302 | ||
| 303 | + | func assertEjectWindowCount(t *testing.T, app *App, sourceWindow *browserWindow) { | |
| 304 | + | t.Helper() | |
| 305 | + | if got := len(app.browserWindows); got != 2 { | |
| 306 | + | t.Fatalf("browserWindows length = %d, want source and target", got) | |
| 307 | + | } | |
| 308 | + | if app.browserWindows[sourceWindow.id] == nil { | |
| 309 | + | t.Fatal("source window should remain registered") | |
| 310 | + | } | |
| 311 | + | } | |
| 312 | + | ||
| 313 | + | func assertEjectedThreePaneSplitSource(t *testing.T, sourceTab *entity.Tab) { | |
| 314 | + | t.Helper() | |
| 315 | + | if got := sourceTab.Workspace.PaneCount(); got != 2 { | |
| 316 | + | t.Fatalf("source pane count = %d, want 2", got) | |
| 317 | + | } | |
| 318 | + | if sourceTab.Workspace.FindPane("pane-a") == nil || sourceTab.Workspace.FindPane("pane-b") == nil { | |
| 319 | + | t.Fatal("source workspace missing remaining split panes") | |
| 320 | + | } | |
| 321 | + | if got := sourceTab.Workspace.FindPane("pane-c"); got != nil { | |
| 322 | + | t.Fatal("source workspace still contains moved split pane") | |
| 323 | + | } | |
| 324 | + | if got := sourceTab.Workspace.ActivePaneID; got != entity.PaneID("pane-b") { | |
| 325 | + | t.Fatalf("source active pane = %q, want pane-b", got) | |
| 326 | + | } | |
| 327 | + | assertPromotedLeftSplitRoot(t, sourceTab.Workspace.Root) | |
| 328 | + | } | |
| 329 | + | ||
| 330 | + | func assertPromotedLeftSplitRoot(t *testing.T, root *entity.PaneNode) { | |
| 331 | + | t.Helper() | |
| 332 | + | if root == nil || root.ID != "left-split" || !root.IsSplit() { | |
| 333 | + | t.Fatalf("source root = %#v, want promoted left split", root) | |
| 334 | + | } | |
| 335 | + | if got := root.Parent; got != nil { | |
| 336 | + | t.Fatalf("source root parent = %#v, want nil", got) | |
| 337 | + | } | |
| 338 | + | assertLeafPaneID(t, root.Left(), "pane-a") | |
| 339 | + | assertLeafPaneID(t, root.Right(), "pane-b") | |
| 340 | + | assertPaneTreeParents(t, root, nil) | |
| 341 | + | } | |
| 342 | + | ||
| 343 | + | func assertEjectedThreePaneSplitTarget(t *testing.T, app *App, paneID entity.PaneID) { | |
| 344 | + | t.Helper() | |
| 345 | + | targetWindow := app.browserWindows["target-window"] | |
| 346 | + | if targetWindow == nil || targetWindow.tabs.Count() != 1 { | |
| 347 | + | t.Fatalf("target window/tabs not created correctly: %#v", targetWindow) | |
| 348 | + | } | |
| 349 | + | newTab := targetWindow.tabs.Tabs[0] | |
| 350 | + | if got := newTab.Workspace.ActivePaneID; got != paneID { | |
| 351 | + | t.Fatalf("target active pane = %q, want %q", got, paneID) | |
| 352 | + | } | |
| 353 | + | if got := newTab.Workspace.Root.Parent; got != nil { | |
| 354 | + | t.Fatalf("target root parent = %#v, want nil", got) | |
| 355 | + | } | |
| 356 | + | if got := app.windowForTab[newTab.ID]; got != targetWindow { | |
| 357 | + | t.Fatalf("target owner = %p, want target window %p", got, targetWindow) | |
| 358 | + | } | |
| 359 | + | } | |
| 360 | + | ||
| 361 | + | func assertLeafPaneID(t *testing.T, node *entity.PaneNode, paneID entity.PaneID) { | |
| 362 | + | t.Helper() | |
| 363 | + | if node == nil || node.Pane == nil || node.Pane.ID != paneID { | |
| 364 | + | t.Fatalf("leaf = %#v, want %s", node, paneID) | |
| 365 | + | } | |
| 366 | + | } | |
| 367 | + | ||
| 345 | 368 | func splitTreeTab(tabID entity.TabID, workspaceID entity.WorkspaceID, paneAID, paneBID, paneCID entity.PaneID) *entity.Tab { | |
| 346 | 369 | paneA := entity.NewPane(paneAID) | |
| 347 | 370 | paneB := entity.NewPane(paneBID) | |
| @@ -139,51 +139,9 @@ func TestApp_EjectActivePaneToWindowHandlesThreePaneSplitTree(t *testing.T) { | |||||
| 139 | t.Fatalf("EjectActivePaneToWindow returned error: %v", err) | 139 | t.Fatalf("EjectActivePaneToWindow returned error: %v", err) | ||
| 140 | } | 140 | } | ||
| 141 | 141 | ||||
| 142 | - | if got := len(app.browserWindows); got != 2 { | 142 | + | assertEjectWindowCount(t, app, sourceWindow) |
| 143 | - | t.Fatalf("browserWindows length = %d, want source and target", got) | 143 | + | assertEjectedThreePaneSplitSource(t, sourceTab) |
| 144 | - | } | 144 | + | assertEjectedThreePaneSplitTarget(t, app, "pane-c") |
| 145 | - | if app.browserWindows[sourceWindow.id] == nil { | |||
| 146 | - | t.Fatal("source window should remain registered") | |||
| 147 | - | } | |||
| 148 | - | if got := sourceTab.Workspace.PaneCount(); got != 2 { | |||
| 149 | - | t.Fatalf("source pane count = %d, want 2", got) | |||
| 150 | - | } | |||
| 151 | - | if sourceTab.Workspace.FindPane("pane-a") == nil || sourceTab.Workspace.FindPane("pane-b") == nil { | |||
| 152 | - | t.Fatal("source workspace missing remaining split panes") | |||
| 153 | - | } | |||
| 154 | - | if got := sourceTab.Workspace.FindPane("pane-c"); got != nil { | |||
| 155 | - | t.Fatal("source workspace still contains moved split pane") | |||
| 156 | - | } | |||
| 157 | - | if got := sourceTab.Workspace.ActivePaneID; got != entity.PaneID("pane-b") { | |||
| 158 | - | t.Fatalf("source active pane = %q, want pane-b", got) | |||
| 159 | - | } | |||
| 160 | - | if sourceTab.Workspace.Root == nil || sourceTab.Workspace.Root.ID != "left-split" || !sourceTab.Workspace.Root.IsSplit() { | |||
| 161 | - | t.Fatalf("source root = %#v, want promoted left split", sourceTab.Workspace.Root) | |||
| 162 | - | } | |||
| 163 | - | if got := sourceTab.Workspace.Root.Parent; got != nil { | |||
| 164 | - | t.Fatalf("source root parent = %#v, want nil", got) | |||
| 165 | - | } | |||
| 166 | - | if got := sourceTab.Workspace.Root.Left(); got == nil || got.Pane == nil || got.Pane.ID != entity.PaneID("pane-a") { | |||
| 167 | - | t.Fatalf("source left leaf = %#v, want pane-a", got) | |||
| 168 | - | } | |||
| 169 | - | if got := sourceTab.Workspace.Root.Right(); got == nil || got.Pane == nil || got.Pane.ID != entity.PaneID("pane-b") { | |||
| 170 | - | t.Fatalf("source right leaf = %#v, want pane-b", got) | |||
| 171 | - | } | |||
| 172 | - | assertPaneTreeParents(t, sourceTab.Workspace.Root, nil) | |||
| 173 | - | targetWindow := app.browserWindows["target-window"] | |||
| 174 | - | if targetWindow == nil || targetWindow.tabs.Count() != 1 { | |||
| 175 | - | t.Fatalf("target window/tabs not created correctly: %#v", targetWindow) | |||
| 176 | - | } | |||
| 177 | - | newTab := targetWindow.tabs.Tabs[0] | |||
| 178 | - | if got := newTab.Workspace.ActivePaneID; got != entity.PaneID("pane-c") { | |||
| 179 | - | t.Fatalf("target active pane = %q, want pane-c", got) | |||
| 180 | - | } | |||
| 181 | - | if got := newTab.Workspace.Root.Parent; got != nil { | |||
| 182 | - | t.Fatalf("target root parent = %#v, want nil", got) | |||
| 183 | - | } | |||
| 184 | - | if got := app.windowForTab[newTab.ID]; got != targetWindow { | |||
| 185 | - | t.Fatalf("target owner = %p, want target window %p", got, targetWindow) | |||
| 186 | - | } | |||
| 187 | } | 145 | } | ||
| 188 | 146 | ||||
| 189 | func TestApp_EjectActivePaneToWindowSnapshotReplacesEmptySourceWindow(t *testing.T) { | 147 | func TestApp_EjectActivePaneToWindowSnapshotReplacesEmptySourceWindow(t *testing.T) { | ||
| @@ -342,6 +300,71 @@ func stackedTab(tabID entity.TabID, workspaceID entity.WorkspaceID, paneIDs ...e | |||||
| 342 | return &entity.Tab{ID: tabID, Workspace: workspace} | 300 | return &entity.Tab{ID: tabID, Workspace: workspace} | ||
| 343 | } | 301 | } | ||
| 344 | 302 | ||||
| 303 | + | func assertEjectWindowCount(t *testing.T, app *App, sourceWindow *browserWindow) { | |||
| 304 | + | t.Helper() | |||
| 305 | + | if got := len(app.browserWindows); got != 2 { | |||
| 306 | + | t.Fatalf("browserWindows length = %d, want source and target", got) | |||
| 307 | + | } | |||
| 308 | + | if app.browserWindows[sourceWindow.id] == nil { | |||
| 309 | + | t.Fatal("source window should remain registered") | |||
| 310 | + | } | |||
| 311 | + | } | |||
| 312 | + | ||||
| 313 | + | func assertEjectedThreePaneSplitSource(t *testing.T, sourceTab *entity.Tab) { | |||
| 314 | + | t.Helper() | |||
| 315 | + | if got := sourceTab.Workspace.PaneCount(); got != 2 { | |||
| 316 | + | t.Fatalf("source pane count = %d, want 2", got) | |||
| 317 | + | } | |||
| 318 | + | if sourceTab.Workspace.FindPane("pane-a") == nil || sourceTab.Workspace.FindPane("pane-b") == nil { | |||
| 319 | + | t.Fatal("source workspace missing remaining split panes") | |||
| 320 | + | } | |||
| 321 | + | if got := sourceTab.Workspace.FindPane("pane-c"); got != nil { | |||
| 322 | + | t.Fatal("source workspace still contains moved split pane") | |||
| 323 | + | } | |||
| 324 | + | if got := sourceTab.Workspace.ActivePaneID; got != entity.PaneID("pane-b") { | |||
| 325 | + | t.Fatalf("source active pane = %q, want pane-b", got) | |||
| 326 | + | } | |||
| 327 | + | assertPromotedLeftSplitRoot(t, sourceTab.Workspace.Root) | |||
| 328 | + | } | |||
| 329 | + | ||||
| 330 | + | func assertPromotedLeftSplitRoot(t *testing.T, root *entity.PaneNode) { | |||
| 331 | + | t.Helper() | |||
| 332 | + | if root == nil || root.ID != "left-split" || !root.IsSplit() { | |||
| 333 | + | t.Fatalf("source root = %#v, want promoted left split", root) | |||
| 334 | + | } | |||
| 335 | + | if got := root.Parent; got != nil { | |||
| 336 | + | t.Fatalf("source root parent = %#v, want nil", got) | |||
| 337 | + | } | |||
| 338 | + | assertLeafPaneID(t, root.Left(), "pane-a") | |||
| 339 | + | assertLeafPaneID(t, root.Right(), "pane-b") | |||
| 340 | + | assertPaneTreeParents(t, root, nil) | |||
| 341 | + | } | |||
| 342 | + | ||||
| 343 | + | func assertEjectedThreePaneSplitTarget(t *testing.T, app *App, paneID entity.PaneID) { | |||
| 344 | + | t.Helper() | |||
| 345 | + | targetWindow := app.browserWindows["target-window"] | |||
| 346 | + | if targetWindow == nil || targetWindow.tabs.Count() != 1 { | |||
| 347 | + | t.Fatalf("target window/tabs not created correctly: %#v", targetWindow) | |||
| 348 | + | } | |||
| 349 | + | newTab := targetWindow.tabs.Tabs[0] | |||
| 350 | + | if got := newTab.Workspace.ActivePaneID; got != paneID { | |||
| 351 | + | t.Fatalf("target active pane = %q, want %q", got, paneID) | |||
| 352 | + | } | |||
| 353 | + | if got := newTab.Workspace.Root.Parent; got != nil { | |||
| 354 | + | t.Fatalf("target root parent = %#v, want nil", got) | |||
| 355 | + | } | |||
| 356 | + | if got := app.windowForTab[newTab.ID]; got != targetWindow { | |||
| 357 | + | t.Fatalf("target owner = %p, want target window %p", got, targetWindow) | |||
| 358 | + | } | |||
| 359 | + | } | |||
| 360 | + | ||||
| 361 | + | func assertLeafPaneID(t *testing.T, node *entity.PaneNode, paneID entity.PaneID) { | |||
| 362 | + | t.Helper() | |||
| 363 | + | if node == nil || node.Pane == nil || node.Pane.ID != paneID { | |||
| 364 | + | t.Fatalf("leaf = %#v, want %s", node, paneID) | |||
| 365 | + | } | |||
| 366 | + | } | |||
| 367 | + | ||||
| 345 | func splitTreeTab(tabID entity.TabID, workspaceID entity.WorkspaceID, paneAID, paneBID, paneCID entity.PaneID) *entity.Tab { | 368 | func splitTreeTab(tabID entity.TabID, workspaceID entity.WorkspaceID, paneAID, paneBID, paneCID entity.PaneID) *entity.Tab { | ||
| 346 | paneA := entity.NewPane(paneAID) | 369 | paneA := entity.NewPane(paneAID) | ||
| 347 | paneB := entity.NewPane(paneBID) | 370 | paneB := entity.NewPane(paneBID) | ||