1package dispatcher
2
3import (
4 "context"
5 "testing"
6
7 "github.com/bnema/dumber/internal/application/usecase"
8 "github.com/bnema/dumber/internal/domain/entity"
9 "github.com/bnema/dumber/internal/ui/component"
10 "github.com/bnema/dumber/internal/ui/coordinator"
11 "github.com/bnema/dumber/internal/ui/input"
12 "github.com/stretchr/testify/assert"
13 "github.com/stretchr/testify/require"
14)
15
16func TestKeyboardDispatcher_TabActionsUseInjectedKeyboardActions(t *testing.T) {
17 ctx := context.Background()
18 called := make([]string, 0)
19 var switchedIndex int
20 d := NewKeyboardDispatcher(
21 ctx,
22 &coordinator.WorkspaceCoordinator{},
23 &coordinator.NavigationCoordinator{},
24 nil,
25 nil,
26 KeyboardActions{
27 NewTab: func(context.Context) error {
28 called = append(called, "new")
29 return nil
30 },
31 CloseTab: func(context.Context) error {
32 called = append(called, "close")
33 return nil
34 },
35 NextTab: func(context.Context) error {
36 called = append(called, "next")
37 return nil
38 },
39 PreviousTab: func(context.Context) error {
40 called = append(called, "previous")
41 return nil
42 },
43 SwitchLastTab: func(context.Context) error {
44 called = append(called, "last")
45 return nil
46 },
47 SwitchTabIndex: func(_ context.Context, index int) error {
48 called = append(called, "index")
49 switchedIndex = index
50 return nil
51 },
52 },
53 func(context.Context) entity.PaneID { return "" },
54 )
55
56 require.NoError(t, d.Dispatch(ctx, input.ActionNewTab))
57 require.NoError(t, d.Dispatch(ctx, input.ActionCloseTab))
58 require.NoError(t, d.Dispatch(ctx, input.ActionNextTab))
59 require.NoError(t, d.Dispatch(ctx, input.ActionPreviousTab))
60 require.NoError(t, d.Dispatch(ctx, input.ActionSwitchLastTab))
61 require.NoError(t, d.Dispatch(ctx, input.ActionSwitchTabIndex5))
62
63 assert.Equal(t, []string{"new", "close", "next", "previous", "last", "index"}, called)
64 assert.Equal(t, 4, switchedIndex)
65}
66
67func TestKeyboardDispatcher_ToggleHistorySystemViewOpensRightSplit(t *testing.T) {
68 ctx := context.Background()
69 ids := []string{"pane-2", "split-1"}
70 idx := 0
71 panesUC := usecase.NewManagePanesUseCase(func() string {
72 id := ids[idx]
73 idx++
74 return id
75 })
76
77 initialPane := entity.NewPane("pane-1")
78 initialPane.URI = "https://example.com"
79 ws := entity.NewWorkspace("ws-1", initialPane)
80 wsCoord := coordinator.NewWorkspaceCoordinator(ctx, coordinator.WorkspaceCoordinatorConfig{
81 PanesUC: panesUC,
82 GetActiveWS: func() (*entity.Workspace, *component.WorkspaceView) {
83 return ws, nil
84 },
85 })
86
87 d := NewKeyboardDispatcher(ctx, wsCoord, &coordinator.NavigationCoordinator{}, nil, nil, KeyboardActions{}, func(context.Context) entity.PaneID { return "" })
88
89 err := d.Dispatch(ctx, input.ActionToggleHistorySystemView)
90 require.NoError(t, err)
91
92 require.Equal(t, 2, ws.PaneCount())
93 active := ws.ActivePane()
94 require.NotNil(t, active)
95 require.NotNil(t, active.Pane)
96 assert.Equal(t, entity.PaneID("pane-2"), active.Pane.ID)
97 assert.Equal(t, "dumb://history", active.Pane.URI)
98}
99
100func TestKeyboardDispatcher_PassesActivePaneIDToShellCallbacks(t *testing.T) {
101 ctx := context.Background()
102 activePaneID := entity.PaneID("pane-1")
103 d := NewKeyboardDispatcher(ctx, &coordinator.WorkspaceCoordinator{}, &coordinator.NavigationCoordinator{}, nil, nil, KeyboardActions{}, func(context.Context) entity.PaneID {
104 return activePaneID
105 })
106
107 tests := []struct {
108 name string
109 set func(func(context.Context, entity.PaneID) error)
110 invoke func(context.Context) error
111 }{
112 {
113 name: "session open",
114 set: d.SetOnSessionOpen,
115 invoke: d.handleSessionOpen,
116 },
117 {
118 name: "move pane to tab",
119 set: d.SetOnMovePaneToTab,
120 invoke: d.handleMovePaneToTab,
121 },
122 {
123 name: "move pane to next tab",
124 set: d.SetOnMovePaneToNextTab,
125 invoke: d.handleMovePaneToNextTab,
126 },
127 }
128
129 for _, tc := range tests {
130 t.Run(tc.name, func(t *testing.T) {
131 var gotPaneID entity.PaneID
132 tc.set(func(_ context.Context, paneID entity.PaneID) error {
133 gotPaneID = paneID
134 return nil
135 })
136
137 require.NoError(t, tc.invoke(ctx))
138 assert.Equal(t, activePaneID, gotPaneID)
139 })
140 }
141}