11import {
22 assertActiveTab ,
3- assertGroupStructure ,
43 assertPanelLayout ,
54 assertTabCount ,
65 findPanelById ,
76 type GroupNode ,
87 getLayout ,
9- getNestedPanel ,
108 getPanelTree ,
119 openMultipleFiles ,
1210 withRootGroup ,
@@ -31,28 +29,17 @@ describe("panelLayoutStore", () => {
3129 const layout = usePanelLayoutStore . getState ( ) . getLayout ( "task-1" ) ;
3230
3331 expect ( layout ) . not . toBeNull ( ) ;
34- expect ( layout ?. panelTree . type ) . toBe ( "group " ) ;
32+ expect ( layout ?. panelTree . type ) . toBe ( "leaf " ) ;
3533 } ) ;
3634
3735 it ( "creates default layout with correct structure" , ( ) => {
3836 usePanelLayoutStore . getState ( ) . initializeTask ( "task-1" ) ;
3937
40- withRootGroup ( "task-1" , ( root : GroupNode ) => {
41- assertGroupStructure ( root , {
42- direction : "vertical" ,
43- childCount : 2 ,
44- sizes : [ 70 , 30 ] ,
45- } ) ;
46-
47- assertPanelLayout ( root , [
48- { panelId : "main-panel" , expectedTabs : [ "logs" ] , activeTab : "logs" } ,
49- {
50- panelId : "terminal-panel" ,
51- expectedTabs : [ "shell" ] ,
52- activeTab : "shell" ,
53- } ,
54- ] ) ;
55- } ) ;
38+ const tree = getPanelTree ( "task-1" ) ;
39+ expect ( tree . type ) . toBe ( "leaf" ) ;
40+ assertPanelLayout ( tree , [
41+ { panelId : "main-panel" , expectedTabs : [ "logs" ] , activeTab : "logs" } ,
42+ ] ) ;
5643 } ) ;
5744 } ) ;
5845
@@ -74,22 +61,26 @@ describe("panelLayoutStore", () => {
7461 } ) ;
7562
7663 it ( "opens file in the focused panel" , ( ) => {
77- // Focus the terminal panel
7864 usePanelLayoutStore
7965 . getState ( )
80- . setFocusedPanel ( "task-1" , "terminal-panel" ) ;
66+ . splitPanel ( "task-1" , "logs" , "main-panel" , "main-panel" , "right" ) ;
67+
68+ const tree = getPanelTree ( "task-1" ) ;
69+ expect ( tree . type ) . toBe ( "group" ) ;
70+ if ( tree . type !== "group" ) return ;
8171
72+ const newPanelId = tree . children [ 1 ] . id ;
73+ usePanelLayoutStore . getState ( ) . setFocusedPanel ( "task-1" , newPanelId ) ;
8274 usePanelLayoutStore . getState ( ) . openFile ( "task-1" , "src/App.tsx" ) ;
8375
84- // File should open in terminal-panel (the focused panel), not main-panel
8576 assertPanelLayout ( getPanelTree ( "task-1" ) , [
8677 {
87- panelId : "terminal-panel" ,
88- expectedTabs : [ "shell" , " file-src/App.tsx"] ,
78+ panelId : newPanelId ,
79+ expectedTabs : [ "file-src/App.tsx" ] ,
8980 activeTab : "file-src/App.tsx" ,
9081 } ,
9182 ] ) ;
92- assertTabCount ( getPanelTree ( "task-1" ) , "main-panel" , 1 ) ; // Only logs
83+ assertTabCount ( getPanelTree ( "task-1" ) , "main-panel" , 1 ) ;
9384 } ) ;
9485
9586 it ( "falls back to main panel if focused panel does not exist" , ( ) => {
@@ -229,39 +220,47 @@ describe("panelLayoutStore", () => {
229220 describe ( "panel size persistence" , ( ) => {
230221 beforeEach ( ( ) => {
231222 usePanelLayoutStore . getState ( ) . initializeTask ( "task-1" ) ;
223+ openMultipleFiles ( "task-1" , [ "src/App.tsx" , "src/Other.tsx" ] ) ;
224+ usePanelLayoutStore
225+ . getState ( )
226+ . splitPanel (
227+ "task-1" ,
228+ "file-src/App.tsx" ,
229+ "main-panel" ,
230+ "main-panel" ,
231+ "right" ,
232+ ) ;
232233 } ) ;
233234
234235 it ( "preserves custom panel sizes when opening a file" , ( ) => {
235- usePanelLayoutStore
236- . getState ( )
237- . updateSizes ( "task-1" , "left-group" , [ 60 , 40 ] ) ;
236+ const tree = getPanelTree ( "task-1" ) ;
237+ if ( tree . type !== "group" ) throw new Error ( "Expected group" ) ;
238+ usePanelLayoutStore . getState ( ) . updateSizes ( "task-1" , tree . id , [ 60 , 40 ] ) ;
238239
239- openMultipleFiles ( "task-1" , [ "src/App .tsx" ] ) ;
240+ openMultipleFiles ( "task-1" , [ "src/Third .tsx" ] ) ;
240241
241242 withRootGroup ( "task-1" , ( root ) => {
242243 expect ( root . sizes ) . toEqual ( [ 60 , 40 ] ) ;
243244 } ) ;
244245 } ) ;
245246
246247 it ( "preserves custom panel sizes when switching tabs" , ( ) => {
248+ const tree = getPanelTree ( "task-1" ) ;
249+ if ( tree . type !== "group" ) throw new Error ( "Expected group" ) ;
250+ usePanelLayoutStore . getState ( ) . updateSizes ( "task-1" , tree . id , [ 55 , 45 ] ) ;
247251 usePanelLayoutStore
248252 . getState ( )
249- . updateSizes ( "task-1" , "left-group" , [ 55 , 45 ] ) ;
250- openMultipleFiles ( "task-1" , [ "src/App.tsx" , "src/Other.tsx" ] ) ;
251- usePanelLayoutStore
252- . getState ( )
253- . setActiveTab ( "task-1" , "main-panel" , "file-src/App.tsx" ) ;
253+ . setActiveTab ( "task-1" , "main-panel" , "logs" ) ;
254254
255255 withRootGroup ( "task-1" , ( root ) => {
256256 expect ( root . sizes ) . toEqual ( [ 55 , 45 ] ) ;
257257 } ) ;
258258 } ) ;
259259
260260 it ( "preserves custom panel sizes when closing tabs" , ( ) => {
261- usePanelLayoutStore
262- . getState ( )
263- . updateSizes ( "task-1" , "left-group" , [ 80 , 20 ] ) ;
264- openMultipleFiles ( "task-1" , [ "src/App.tsx" , "src/Other.tsx" ] ) ;
261+ const tree = getPanelTree ( "task-1" ) ;
262+ if ( tree . type !== "group" ) throw new Error ( "Expected group" ) ;
263+ usePanelLayoutStore . getState ( ) . updateSizes ( "task-1" , tree . id , [ 80 , 20 ] ) ;
265264 usePanelLayoutStore
266265 . getState ( )
267266 . closeTab ( "task-1" , "main-panel" , "file-src/Other.tsx" ) ;
@@ -379,38 +378,49 @@ describe("panelLayoutStore", () => {
379378 } ) ;
380379
381380 describe ( "moveTab" , ( ) => {
381+ let secondPanelId : string ;
382+
382383 beforeEach ( ( ) => {
383384 usePanelLayoutStore . getState ( ) . initializeTask ( "task-1" ) ;
384- usePanelLayoutStore . getState ( ) . openFile ( "task-1" , "src/App.tsx" ) ;
385+ openMultipleFiles ( "task-1" , [ "src/App.tsx" , "src/Other.tsx" ] ) ;
386+ usePanelLayoutStore
387+ . getState ( )
388+ . splitPanel (
389+ "task-1" ,
390+ "file-src/Other.tsx" ,
391+ "main-panel" ,
392+ "main-panel" ,
393+ "right" ,
394+ ) ;
395+ const tree = getPanelTree ( "task-1" ) ;
396+ if ( tree . type !== "group" ) throw new Error ( "Expected group" ) ;
397+ secondPanelId = tree . children [ 1 ] . id ;
385398 } ) ;
386399
387400 it ( "moves tab between panels" , ( ) => {
388401 usePanelLayoutStore
389402 . getState ( )
390- . moveTab ( "task-1" , "file-src/App.tsx" , "main-panel" , "terminal-panel" ) ;
403+ . moveTab ( "task-1" , "file-src/App.tsx" , "main-panel" , secondPanelId ) ;
391404
392405 const mainPanel = findPanelById ( getPanelTree ( "task-1" ) , "main-panel" ) ;
393- const terminalPanel = findPanelById (
394- getPanelTree ( "task-1" ) ,
395- "terminal-panel" ,
396- ) ;
406+ const secondPanel = findPanelById ( getPanelTree ( "task-1" ) , secondPanelId ) ;
397407
398408 expect (
399409 mainPanel ?. content . tabs . find ( ( t ) => t . id === "file-src/App.tsx" ) ,
400410 ) . toBeUndefined ( ) ;
401411 expect (
402- terminalPanel ?. content . tabs . find ( ( t ) => t . id === "file-src/App.tsx" ) ,
412+ secondPanel ?. content . tabs . find ( ( t ) => t . id === "file-src/App.tsx" ) ,
403413 ) . toBeDefined ( ) ;
404414 } ) ;
405415
406416 it ( "sets moved tab as active in target panel" , ( ) => {
407417 usePanelLayoutStore
408418 . getState ( )
409- . moveTab ( "task-1" , "file-src/App.tsx" , "main-panel" , "terminal-panel" ) ;
419+ . moveTab ( "task-1" , "file-src/App.tsx" , "main-panel" , secondPanelId ) ;
410420
411421 assertActiveTab (
412422 getPanelTree ( "task-1" ) ,
413- "terminal-panel" ,
423+ secondPanelId ,
414424 "file-src/App.tsx" ,
415425 ) ;
416426 } ) ;
@@ -440,12 +450,11 @@ describe("panelLayoutStore", () => {
440450 direction ,
441451 ) ;
442452
443- // After split, main-panel becomes a group
444- const mainPanelNode = getNestedPanel ( "task-1" , 0 ) ;
445- expect ( mainPanelNode . type ) . toBe ( "group" ) ;
446- if ( mainPanelNode . type === "group" ) {
447- expect ( mainPanelNode . direction ) . toBe ( expectedDirection ) ;
448- expect ( mainPanelNode . children ) . toHaveLength ( 2 ) ;
453+ const tree = getPanelTree ( "task-1" ) ;
454+ expect ( tree . type ) . toBe ( "group" ) ;
455+ if ( tree . type === "group" ) {
456+ expect ( tree . direction ) . toBe ( expectedDirection ) ;
457+ expect ( tree . children ) . toHaveLength ( 2 ) ;
449458 }
450459 } ,
451460 ) ;
@@ -461,11 +470,10 @@ describe("panelLayoutStore", () => {
461470 "right" ,
462471 ) ;
463472
464- // After right split: main-panel becomes a group with [original, new]
465- const mainPanelNode = getNestedPanel ( "task-1" , 0 ) ;
466- expect ( mainPanelNode . type ) . toBe ( "group" ) ;
467- if ( mainPanelNode . type === "group" ) {
468- const newPanel = mainPanelNode . children [ 1 ] ;
473+ const tree = getPanelTree ( "task-1" ) ;
474+ expect ( tree . type ) . toBe ( "group" ) ;
475+ if ( tree . type === "group" ) {
476+ const newPanel = tree . children [ 1 ] ;
469477 expect ( newPanel . type ) . toBe ( "leaf" ) ;
470478 if ( newPanel . type === "leaf" ) {
471479 expect (
@@ -480,12 +488,22 @@ describe("panelLayoutStore", () => {
480488 describe ( "updateSizes" , ( ) => {
481489 beforeEach ( ( ) => {
482490 usePanelLayoutStore . getState ( ) . initializeTask ( "task-1" ) ;
491+ openMultipleFiles ( "task-1" , [ "src/App.tsx" , "src/Other.tsx" ] ) ;
492+ usePanelLayoutStore
493+ . getState ( )
494+ . splitPanel (
495+ "task-1" ,
496+ "file-src/App.tsx" ,
497+ "main-panel" ,
498+ "main-panel" ,
499+ "right" ,
500+ ) ;
483501 } ) ;
484502
485503 it ( "updates panel group sizes" , ( ) => {
486- usePanelLayoutStore
487- . getState ( )
488- . updateSizes ( "task-1" , "left-group" , [ 60 , 40 ] ) ;
504+ const tree = getPanelTree ( "task-1" ) ;
505+ if ( tree . type !== "group" ) throw new Error ( "Expected group" ) ;
506+ usePanelLayoutStore . getState ( ) . updateSizes ( "task-1" , tree . id , [ 60 , 40 ] ) ;
489507
490508 withRootGroup ( "task-1" , ( root : GroupNode ) => {
491509 expect ( root . sizes ) . toEqual ( [ 60 , 40 ] ) ;
@@ -510,18 +528,17 @@ describe("panelLayoutStore", () => {
510528 "right" ,
511529 ) ;
512530
513- // Find the new panel and close its tab
514- const mainPanelNode = getNestedPanel ( "task-1" , 0 ) ;
515- if ( mainPanelNode . type === "group" ) {
516- const newPanel = mainPanelNode . children [ 1 ] ;
517- usePanelLayoutStore
518- . getState ( )
519- . closeTab ( "task-1" , newPanel . id , "file-src/App.tsx" ) ;
520- }
531+ const tree = getPanelTree ( "task-1" ) ;
532+ expect ( tree . type ) . toBe ( "group" ) ;
533+ if ( tree . type !== "group" ) return ;
534+
535+ const newPanel = tree . children [ 1 ] ;
536+ usePanelLayoutStore
537+ . getState ( )
538+ . closeTab ( "task-1" , newPanel . id , "file-src/App.tsx" ) ;
521539
522- // After closing, the group should simplify back to a leaf
523- const updatedMainPanel = getNestedPanel ( "task-1" , 0 ) ;
524- expect ( updatedMainPanel . type ) . toBe ( "leaf" ) ;
540+ const updatedTree = getPanelTree ( "task-1" ) ;
541+ expect ( updatedTree . type ) . toBe ( "leaf" ) ;
525542 } ) ;
526543 } ) ;
527544
0 commit comments