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