recent_route_presentation_test.go RawHistoryFolder
1package daemon
2
3import (
4 "testing"
5
6 "github.com/bnema/vev/internal/ports"
7 "github.com/bnema/vev/internal/usecase/command"
8 "github.com/bnema/vev/internal/usecase/palette"
9 "github.com/stretchr/testify/require"
10)
11
12func TestFormatRecentRoutePresentations(t *testing.T) {
13 tests := []struct {
14 name string
15 input []recentRoutePresentation
16 want []recentRouteDisplay
17 }{
18 {
19 name: "unique local name stays compact",
20 input: []recentRoutePresentation{{
21 name: "editor", kind: recentRouteLocal,
22 }},
23 want: []recentRouteDisplay{{
24 name: "editor", kind: recentRouteLocal,
25 }},
26 },
27 {
28 name: "remote name is host qualified",
29 input: []recentRoutePresentation{{
30 name: "logs", hostLabel: "edge", kind: recentRouteRemote,
31 }},
32 want: []recentRouteDisplay{{
33 name: "logs@edge", kind: recentRouteRemote,
34 }},
35 },
36 {
37 name: "duplicate local and remote names qualify every entry",
38 input: []recentRoutePresentation{
39 {name: "logs", kind: recentRouteLocal},
40 {name: "logs", hostLabel: "edge", kind: recentRouteRemote},
41 },
42 want: []recentRouteDisplay{
43 {name: "logs@local", kind: recentRouteLocal},
44 {name: "logs@edge", kind: recentRouteRemote},
45 },
46 },
47 {
48 name: "missing host uses kind fallback",
49 input: []recentRoutePresentation{{
50 name: "logs", kind: recentRouteRemote,
51 }},
52 want: []recentRouteDisplay{{
53 name: "logs@remote", kind: recentRouteRemote,
54 }},
55 },
56 {
57 name: "authoritative markers survive formatting",
58 input: []recentRoutePresentation{{
59 name: "scratch", kind: recentRouteLocal, ephemeral: true, attention: true,
60 }},
61 want: []recentRouteDisplay{{
62 name: "scratch*", kind: recentRouteLocal, ephemeral: true, attention: true,
63 }},
64 },
65 }
66
67 for _, tt := range tests {
68 t.Run(tt.name, func(t *testing.T) {
69 input := append([]recentRoutePresentation(nil), tt.input...)
70 got := formatRecentRoutePresentations(input)
71
72 require.Equal(t, tt.want, got)
73 require.Equal(t, input, tt.input, "formatting must not mutate the source snapshot")
74 })
75 }
76}
77
78func TestRecentSessionHintsAndRankedRenderingShareCanonicalLabels(t *testing.T) {
79 snapshot := ports.RecentRouteSnapshot{
80 Generation: 1,
81 Entries: []ports.RecentRouteEntry{
82 {Key: 1, Generation: 1, Name: "logs", Kind: ports.RouteKindLocal, Attention: true},
83 {Key: 2, Generation: 1, Name: "logs", Kind: ports.RouteKindLocal},
84 },
85 }
86
87 hints := recentRouteHints(snapshot, nil)
88 require.Equal(t, []palette.RecentSessionHint{
89 {Rank: 1, Name: "logs@local", SnapshotGeneration: 1, Key: 1, Generation: 1},
90 {Rank: 2, Name: "logs@local", SnapshotGeneration: 1, Key: 2, Generation: 1},
91 }, hints.Recent)
92
93 hints = palette.ContextualHints{
94 Kind: command.ContextHintRecentSessions,
95 SelectedRank: 9,
96 Recent: []palette.RecentSessionHint{
97 {Rank: 4, Name: "stale-label"},
98 {Rank: 9, Name: "stale-label"},
99 },
100 }
101 ranked := rankedRecentForHintsWithSnapshot(&hints, snapshot)
102
103 require.Equal(t, []rankedRecent{
104 {rank: 4, name: "logs@local", kind: recentRouteLocal, attention: true},
105 {rank: 9, name: "logs@local", kind: recentRouteLocal, selected: true},
106 }, ranked)
107}
108
109func TestFitRecentRouteEntriesKeepsWholeWideAndAttentionEntries(t *testing.T) {
110 tests := []struct {
111 name string
112 entries []recentRouteDisplay
113 width int
114 want []string
115 }{
116 {
117 name: "wide rune consumes its full cell width",
118 entries: []recentRouteDisplay{
119 {name: "界"},
120 {name: "b"},
121 },
122 width: 12,
123 want: []string{"界"},
124 },
125 {
126 name: "attention bell is part of the entry width",
127 entries: []recentRouteDisplay{
128 {name: "a", attention: true},
129 {name: "b"},
130 },
131 width: 12,
132 want: []string{"a"},
133 },
134 }
135
136 for _, tt := range tests {
137 t.Run(tt.name, func(t *testing.T) {
138 got := fitMRU(tt.entries, tt.width, 0, "copy")
139 names := make([]string, len(got))
140 for i, entry := range got {
141 names[i] = entry.name
142 }
143 require.Equal(t, tt.want, names)
144 })
145 }
146}
147
148func TestRankedRecentKeepsCapturedRanksWhenFitting(t *testing.T) {
149 entries := []rankedRecent{
150 {rank: 3, name: "wide界"},
151 {rank: 7, name: "next"},
152 }
153
154 got := fitRankedRecent(entries, 17, 0, "")
155
156 require.Equal(t, []rankedRecent{{rank: 3, name: "wide界"}}, got)
157}