detached 324a4a6

refactor: remove code unreachable from production and tests

commit
324a4a621f68f27f1b63282d839b6ab6d8408e12
author
brice · · 2026-09-23 18:00 UTC
parent
1f9680c
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
11 files · +0 -318
M cmd/vev-perf-harness/hangup_test.go +0 -39
@@ -3,13 +3,11 @@
33 package main
44
55 import (
6- "encoding/json"
76 "errors"
87 "fmt"
98 "os"
109 "os/exec"
1110 "path/filepath"
12- "strings"
1311 "syscall"
1412 "testing"
1513 "time"
@@ -262,40 +260,3 @@ func waitForProcessGroupGone(pgid int, timeout time.Duration) error {
262260 time.Sleep(10 * time.Millisecond)
263261 }
264262 }
265-
266-// waitForInflightReceive polls a process trace until it holds an unpaired
267-// adapter_receive_start (more starts than ends). It tolerates a partially
268-// written trailing line while the traced process appends concurrently.
269-func waitForInflightReceive(path string, timeout time.Duration) error {
270- deadline := time.Now().Add(timeout)
271- for {
272- starts, ends := 0, 0
273- data, err := os.ReadFile(path)
274- if err != nil {
275- return err
276- }
277- for _, line := range strings.Split(string(data), "\n") {
278- line = strings.TrimSpace(line)
279- if line == "" {
280- continue
281- }
282- var r traceRecord
283- if json.Unmarshal([]byte(line), &r) != nil {
284- continue // a concurrently appended, not-yet-complete final line
285- }
286- switch r.Kind {
287- case "adapter_receive_start":
288- starts++
289- case "adapter_receive_end":
290- ends++
291- }
292- }
293- if starts > ends {
294- return nil
295- }
296- if time.Now().After(deadline) {
297- return fmt.Errorf("adapter_receive starts=%d ends=%d, want an in-flight start", starts, ends)
298- }
299- time.Sleep(10 * time.Millisecond)
300- }
301-}
@@ -3,13 +3,11 @@
3 package main3 package main
4 4
5 import (5 import (
6- "encoding/json"
7 "errors"6 "errors"
8 "fmt"7 "fmt"
9 "os"8 "os"
10 "os/exec"9 "os/exec"
11 "path/filepath"10 "path/filepath"
12- "strings"
13 "syscall"11 "syscall"
14 "testing"12 "testing"
15 "time"13 "time"
@@ -262,40 +260,3 @@ func waitForProcessGroupGone(pgid int, timeout time.Duration) error {
262 time.Sleep(10 * time.Millisecond)260 time.Sleep(10 * time.Millisecond)
263 }261 }
264 }262 }
265-
266-// waitForInflightReceive polls a process trace until it holds an unpaired
267-// adapter_receive_start (more starts than ends). It tolerates a partially
268-// written trailing line while the traced process appends concurrently.
269-func waitForInflightReceive(path string, timeout time.Duration) error {
270- deadline := time.Now().Add(timeout)
271- for {
272- starts, ends := 0, 0
273- data, err := os.ReadFile(path)
274- if err != nil {
275- return err
276- }
277- for _, line := range strings.Split(string(data), "\n") {
278- line = strings.TrimSpace(line)
279- if line == "" {
280- continue
281- }
282- var r traceRecord
283- if json.Unmarshal([]byte(line), &r) != nil {
284- continue // a concurrently appended, not-yet-complete final line
285- }
286- switch r.Kind {
287- case "adapter_receive_start":
288- starts++
289- case "adapter_receive_end":
290- ends++
291- }
292- }
293- if starts > ends {
294- return nil
295- }
296- if time.Now().After(deadline) {
297- return fmt.Errorf("adapter_receive starts=%d ends=%d, want an in-flight start", starts, ends)
298- }
299- time.Sleep(10 * time.Millisecond)
300- }
301-}
M internal/adapters/brokeripc/preview_lifecycle_test.go +0 -13
@@ -41,19 +41,6 @@ func previewRequest(t *testing.T, epoch ports.BrokerEpoch, client ports.BrokerSe
4141 return request
4242 }
4343
44-// awaitPreviewChanged waits for one preview Changed wake under an explicit
45-// bound, so a subscription that never publishes is a bounded test failure.
46-func awaitPreviewChanged(t *testing.T, sub ports.BrokerPreviewSubscription) ports.BrokerPreviewPublication {
47- t.Helper()
48- select {
49- case <-sub.Changed():
50- return sub.Latest()
51- case <-time.After(5 * time.Second):
52- t.Fatal("the preview subscription did not publish within the bound")
53- return ports.BrokerPreviewPublication{}
54- }
55-}
56-
5744 // serverPreviewGeneration returns the server session's current preview
5845 // generation: it observes the same replacement bookkeeping startPreview
5946 // maintains, so a test can prove which generation the server holds current.
@@ -41,19 +41,6 @@ func previewRequest(t *testing.T, epoch ports.BrokerEpoch, client ports.BrokerSe
41 return request41 return request
42 }42 }
43 43
44-// awaitPreviewChanged waits for one preview Changed wake under an explicit
45-// bound, so a subscription that never publishes is a bounded test failure.
46-func awaitPreviewChanged(t *testing.T, sub ports.BrokerPreviewSubscription) ports.BrokerPreviewPublication {
47- t.Helper()
48- select {
49- case <-sub.Changed():
50- return sub.Latest()
51- case <-time.After(5 * time.Second):
52- t.Fatal("the preview subscription did not publish within the bound")
53- return ports.BrokerPreviewPublication{}
54- }
55-}
56-
57 // serverPreviewGeneration returns the server session's current preview44 // serverPreviewGeneration returns the server session's current preview
58 // generation: it observes the same replacement bookkeeping startPreview45 // generation: it observes the same replacement bookkeeping startPreview
59 // maintains, so a test can prove which generation the server holds current.46 // maintains, so a test can prove which generation the server holds current.
M internal/adapters/brokerwire/convert.go +0 -4
@@ -149,10 +149,6 @@ func validateBrokerDisplayText(v string, max int) error {
149149 return mapOptionalBrokerError(protoconv.BrokerDisplayText(v, max))
150150 }
151151
152-func validateBrokerEnvEntry(v string) error {
153- return mapOptionalBrokerError(protoconv.BrokerEnvEntry(v))
154-}
155-
156152 func mapOptionalBrokerError(err error) error {
157153 if err == nil {
158154 return nil
@@ -149,10 +149,6 @@ func validateBrokerDisplayText(v string, max int) error {
149 return mapOptionalBrokerError(protoconv.BrokerDisplayText(v, max))149 return mapOptionalBrokerError(protoconv.BrokerDisplayText(v, max))
150 }150 }
151 151
152-func validateBrokerEnvEntry(v string) error {
153- return mapOptionalBrokerError(protoconv.BrokerEnvEntry(v))
154-}
155-
156 func mapOptionalBrokerError(err error) error {152 func mapOptionalBrokerError(err error) error {
157 if err == nil {153 if err == nil {
158 return nil154 return nil
M internal/adapters/daemonmux/convert.go +0 -11
@@ -31,15 +31,6 @@ func muxEnum8[T ~uint8](value uint32) (T, error) {
3131 return v, nil
3232 }
3333
34-// muxEnum16 maps shared narrowing failures to the local range sentinel.
35-func muxEnum16[T ~uint16](value uint32) (T, error) {
36- v, err := protoconv.Uint16[T](value)
37- if err != nil {
38- return 0, errConvertRange
39- }
40- return v, nil
41-}
42-
4334 func startModeToWire(mode ports.BrokerDaemonStartMode) (uint32, error) {
4435 v, err := protoconv.BrokerStartModeToWire(mode)
4536 if err != nil {
@@ -157,8 +148,6 @@ func validateDisplayText(v string, max int) error {
157148 return mapOptionalBrokerError(protoconv.BrokerDisplayText(v, max))
158149 }
159150
160-func validateEnvEntry(v string) error { return mapOptionalBrokerError(protoconv.BrokerEnvEntry(v)) }
161-
162151 func mapOptionalBrokerError(err error) error {
163152 if err == nil {
164153 return nil
@@ -31,15 +31,6 @@ func muxEnum8[T ~uint8](value uint32) (T, error) {
31 return v, nil31 return v, nil
32 }32 }
33 33
34-// muxEnum16 maps shared narrowing failures to the local range sentinel.
35-func muxEnum16[T ~uint16](value uint32) (T, error) {
36- v, err := protoconv.Uint16[T](value)
37- if err != nil {
38- return 0, errConvertRange
39- }
40- return v, nil
41-}
42-
43 func startModeToWire(mode ports.BrokerDaemonStartMode) (uint32, error) {34 func startModeToWire(mode ports.BrokerDaemonStartMode) (uint32, error) {
44 v, err := protoconv.BrokerStartModeToWire(mode)35 v, err := protoconv.BrokerStartModeToWire(mode)
45 if err != nil {36 if err != nil {
@@ -157,8 +148,6 @@ func validateDisplayText(v string, max int) error {
157 return mapOptionalBrokerError(protoconv.BrokerDisplayText(v, max))148 return mapOptionalBrokerError(protoconv.BrokerDisplayText(v, max))
158 }149 }
159 150
160-func validateEnvEntry(v string) error { return mapOptionalBrokerError(protoconv.BrokerEnvEntry(v)) }
161-
162 func mapOptionalBrokerError(err error) error {151 func mapOptionalBrokerError(err error) error {
163 if err == nil {152 if err == nil {
164 return nil153 return nil
D internal/adapters/ipc/export_test.go +0 -12
@@ -1,12 +0,0 @@
1-package ipc
2-
3-import "path/filepath"
4-
5-// SocketPath returns the daemon socket path inside runtimeDir. It has no
6-// current caller: brokeripc.SocketPath (a distinct, unrelated function) is
7-// the one every production and test call site actually uses for the daemon's
8-// own socket path. This is kept as a test-only convenience the package name
9-// implies is available.
10-func SocketPath(runtimeDir string) string {
11- return filepath.Join(runtimeDir, socketFileName)
12-}
@@ -1,12 +0,0 @@
1-package ipc
2-
3-import "path/filepath"
4-
5-// SocketPath returns the daemon socket path inside runtimeDir. It has no
6-// current caller: brokeripc.SocketPath (a distinct, unrelated function) is
7-// the one every production and test call site actually uses for the daemon's
8-// own socket path. This is kept as a test-only convenience the package name
9-// implies is available.
10-func SocketPath(runtimeDir string) string {
11- return filepath.Join(runtimeDir, socketFileName)
12-}
M internal/app/broker_daemon_start_test.go +0 -13
@@ -79,19 +79,6 @@ func (s *scriptedDaemonStarter) starter(backoff backoffConfig) brokerDaemonStart
7979 }
8080 }
8181
82-// releaseDaemonOwnership drops the lifecycle ownership the scripted daemon held,
83-// as stopping it would.
84-func (s *scriptedDaemonStarter) releaseDaemonOwnership(t *testing.T) {
85- t.Helper()
86- s.mu.Lock()
87- owner := s.daemonOwner
88- s.daemonOwner = nil
89- s.mu.Unlock()
90- if owner != nil {
91- require.NoError(t, owner.Release())
92- }
93-}
94-
9582 func (s *scriptedDaemonStarter) dial(_ context.Context, carriage string) (daemonmux.RawFramedTransport, error) {
9683 s.mu.Lock()
9784 defer s.mu.Unlock()
@@ -79,19 +79,6 @@ func (s *scriptedDaemonStarter) starter(backoff backoffConfig) brokerDaemonStart
79 }79 }
80 }80 }
81 81
82-// releaseDaemonOwnership drops the lifecycle ownership the scripted daemon held,
83-// as stopping it would.
84-func (s *scriptedDaemonStarter) releaseDaemonOwnership(t *testing.T) {
85- t.Helper()
86- s.mu.Lock()
87- owner := s.daemonOwner
88- s.daemonOwner = nil
89- s.mu.Unlock()
90- if owner != nil {
91- require.NoError(t, owner.Release())
92- }
93-}
94-
95 func (s *scriptedDaemonStarter) dial(_ context.Context, carriage string) (daemonmux.RawFramedTransport, error) {82 func (s *scriptedDaemonStarter) dial(_ context.Context, carriage string) (daemonmux.RawFramedTransport, error) {
96 s.mu.Lock()83 s.mu.Lock()
97 defer s.mu.Unlock()84 defer s.mu.Unlock()
M internal/app/cmd_test.go +0 -9
@@ -41,15 +41,6 @@ func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {
4141 return wire.Envelope{Payload: raw}
4242 }
4343
44-// decodeServerEnvelope unwraps a received envelope into its semantic server
45-// message, failing the test on a malformed payload.
46-func decodeServerEnvelope(t *testing.T, envelope wire.Envelope) protocol.ServerMessage {
47- t.Helper()
48- message, err := sessionwire.DecodeServerEnvelope(envelope.Payload)
49- require.NoError(t, err)
50- return message
51-}
52-
5344 // mustPreambleResponse builds the canned server preamble acceptance the
5445 // typed client connection expects before application traffic.
5546 func mustPreambleResponse() wire.Envelope {
@@ -41,15 +41,6 @@ func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {
41 return wire.Envelope{Payload: raw}41 return wire.Envelope{Payload: raw}
42 }42 }
43 43
44-// decodeServerEnvelope unwraps a received envelope into its semantic server
45-// message, failing the test on a malformed payload.
46-func decodeServerEnvelope(t *testing.T, envelope wire.Envelope) protocol.ServerMessage {
47- t.Helper()
48- message, err := sessionwire.DecodeServerEnvelope(envelope.Payload)
49- require.NoError(t, err)
50- return message
51-}
52-
53 // mustPreambleResponse builds the canned server preamble acceptance the44 // mustPreambleResponse builds the canned server preamble acceptance the
54 // typed client connection expects before application traffic.45 // typed client connection expects before application traffic.
55 func mustPreambleResponse() wire.Envelope {46 func mustPreambleResponse() wire.Envelope {
M internal/app/ui_driver_fixture_test.go +0 -12
@@ -76,9 +76,6 @@ func (f *uiDriverBrokerFixture) Connector() ports.BrokerConnector {
7676 return brokeripc.NewConnector(f.broker.socket, brokeripc.Config{})
7777 }
7878
79-// Socket is the fixture broker's private IPC socket path.
80-func (f *uiDriverBrokerFixture) Socket() string { return f.broker.socket }
81-
8279 // Streams reports one event per logical stream the fixture broker admitted.
8380 func (f *uiDriverBrokerFixture) Streams() <-chan struct{} { return f.broker.streams }
8481
@@ -265,15 +262,6 @@ func (r *uiDriverFixtureRun) awaitAttachedSnapshot(t *testing.T, attachment, ses
265262 return snapshot
266263 }
267264
268-// sessionName returns the session name of the run's committed publication, or ""
269-// while no session is presented.
270-func (r *uiDriverFixtureRun) sessionName(t *testing.T, attachment string) string {
271- t.Helper()
272- snapshot, err := r.ui.Capture(attachment)
273- require.NoError(t, err)
274- return snapshot.Context.Route.Target.SessionName
275-}
276-
277265 // keys sends one key batch at the given generation and returns its action status.
278266 // An accepted batch whose boundary was lost is reported as outcome_unknown, which
279267 // is an honest terminal status and not a refusal.
@@ -76,9 +76,6 @@ func (f *uiDriverBrokerFixture) Connector() ports.BrokerConnector {
76 return brokeripc.NewConnector(f.broker.socket, brokeripc.Config{})76 return brokeripc.NewConnector(f.broker.socket, brokeripc.Config{})
77 }77 }
78 78
79-// Socket is the fixture broker's private IPC socket path.
80-func (f *uiDriverBrokerFixture) Socket() string { return f.broker.socket }
81-
82 // Streams reports one event per logical stream the fixture broker admitted.79 // Streams reports one event per logical stream the fixture broker admitted.
83 func (f *uiDriverBrokerFixture) Streams() <-chan struct{} { return f.broker.streams }80 func (f *uiDriverBrokerFixture) Streams() <-chan struct{} { return f.broker.streams }
84 81
@@ -265,15 +262,6 @@ func (r *uiDriverFixtureRun) awaitAttachedSnapshot(t *testing.T, attachment, ses
265 return snapshot262 return snapshot
266 }263 }
267 264
268-// sessionName returns the session name of the run's committed publication, or ""
269-// while no session is presented.
270-func (r *uiDriverFixtureRun) sessionName(t *testing.T, attachment string) string {
271- t.Helper()
272- snapshot, err := r.ui.Capture(attachment)
273- require.NoError(t, err)
274- return snapshot.Context.Route.Target.SessionName
275-}
276-
277 // keys sends one key batch at the given generation and returns its action status.265 // keys sends one key batch at the given generation and returns its action status.
278 // An accepted batch whose boundary was lost is reported as outcome_unknown, which266 // An accepted batch whose boundary was lost is reported as outcome_unknown, which
279 // is an honest terminal status and not a refusal.267 // is an honest terminal status and not a refusal.
M internal/usecase/broker/pool_test.go +0 -6
@@ -23,12 +23,6 @@ func (f poolResolver) ResolveDialTarget(c context.Context, r ports.BrokerOpenStr
2323 return f(c, r)
2424 }
2525
26-type poolBinder func(context.Context, ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error)
27-
28-func (f poolBinder) BindAuthenticatedIdentity(c context.Context, r ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
29- return f(c, r)
30-}
31-
3226 type poolConnector func(context.Context, ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error)
3327
3428 func (f poolConnector) Connect(c context.Context, r ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error) {
@@ -23,12 +23,6 @@ func (f poolResolver) ResolveDialTarget(c context.Context, r ports.BrokerOpenStr
23 return f(c, r)23 return f(c, r)
24 }24 }
25 25
26-type poolBinder func(context.Context, ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error)
27-
28-func (f poolBinder) BindAuthenticatedIdentity(c context.Context, r ports.BrokerIdentityBindingRequest) (ports.BrokerDaemonIdentity, error) {
29- return f(c, r)
30-}
31-
32 type poolConnector func(context.Context, ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error)26 type poolConnector func(context.Context, ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error)
33 27
34 func (f poolConnector) Connect(c context.Context, r ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error) {28 func (f poolConnector) Connect(c context.Context, r ports.BrokerDialTarget) (ports.BrokerPhysicalConnection, error) {
M internal/usecase/client/wire_external_test_helpers_test.go +0 -170
@@ -1,36 +1,11 @@
11 package client_test
22
33 import (
4- "testing"
5-
6- "github.com/stretchr/testify/require"
7-
84 "github.com/bnema/vev/internal/adapters/sessionwire"
9- "github.com/bnema/vev/internal/domain"
105 "github.com/bnema/vev/internal/protocol"
116 "github.com/bnema/vev/internal/protocol/wire"
127 )
138
14-// mustServerEnvelope wraps one semantic server message in the envelope the
15-// wire.Transport exchanges. Replay-only output fixtures that predate the
16-// publication context still model valid v41 semantic publications, so the
17-// context is filled in before encoding.
18-func mustServerEnvelope(message protocol.ServerMessage) wire.Envelope {
19- if output, ok := message.(protocol.Output); ok && output.New != 0 && output.Context == nil {
20- output.Context = &protocol.ViewContext{
21- Publication: output.Epoch<<32 | output.New,
22- Route: protocol.CommittedRouteIdentity{Target: protocol.ExactSessionTarget{LifecycleID: domain.SessionLifecycleID{1}, SessionName: "work"}},
23- TabID: "tab-1", FocusedPaneID: "pane-1",
24- }
25- message = output
26- }
27- raw, err := sessionwire.EncodeServerMessage(message)
28- if err != nil {
29- panic(err)
30- }
31- return wire.Envelope{Payload: raw}
32-}
33-
349 // mustClientEnvelope wraps one semantic client message in the envelope the
3510 // wire.Transport exchanges.
3611 func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {
@@ -40,148 +15,3 @@ func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {
4015 }
4116 return wire.Envelope{Payload: raw}
4217 }
43-
44-// decodeClientMessageForTest unwraps one client envelope for assertions.
45-func decodeClientMessageForTest(t *testing.T, envelope wire.Envelope) protocol.ClientMessage {
46- t.Helper()
47- message, err := sessionwire.DecodeClientEnvelope(envelope.Payload)
48- require.NoError(t, err)
49- return message
50-}
51-
52-// clientMessageName mirrors the internal package's naming table so external
53-// transport expectations can match typed client messages by kind.
54-func clientMessageName(t *testing.T, envelope wire.Envelope) string {
55- if t != nil {
56- t.Helper()
57- }
58- message, err := sessionwire.DecodeClientEnvelope(envelope.Payload)
59- if err != nil {
60- return ""
61- }
62- switch message.(type) {
63- case protocol.SuspendAttachment:
64- return "SuspendAttachment"
65- case protocol.ActivateAttachment:
66- return "ActivateAttachment"
67- case protocol.Hello:
68- return "Hello"
69- case protocol.Input:
70- return "Input"
71- case protocol.Resize:
72- return "Resize"
73- case protocol.Detach:
74- return "Detach"
75- case protocol.Ping:
76- return "Ping"
77- case protocol.List:
78- return "List"
79- case protocol.Kill:
80- return "Kill"
81- case protocol.Theme:
82- return "Theme"
83- case protocol.Ack:
84- return "Ack"
85- case protocol.ImagePush:
86- return "ImagePush"
87- case protocol.ClientNotice:
88- return "ClientNotice"
89- case protocol.CommandRequest:
90- return "CommandRequest"
91- case protocol.OutputResetRequest:
92- return "OutputResetRequest"
93- case protocol.UIFence:
94- return "UIFence"
95- case protocol.RemotePreviewWatch:
96- return "RemotePreviewWatch"
97- case protocol.RouteAttentionSubscription:
98- return "RouteAttentionSubscription"
99- case protocol.SamePeerSwitchRequest:
100- return "SamePeerSwitchRequest"
101- case protocol.RecentRouteSnapshot:
102- return "RecentRouteSnapshot"
103- case protocol.RouteNavigationFailure:
104- return "RouteNavigationFailure"
105- case protocol.SessionCreationFailure:
106- return "SessionCreationFailure"
107- case protocol.NavigationInventoryRequest:
108- return "NavigationInventoryRequest"
109- case protocol.NavigationInventoryPublication:
110- return "NavigationInventoryPublication"
111- case protocol.NavigationInventoryFailure:
112- return "NavigationInventoryFailure"
113- case protocol.PickerClose:
114- return "PickerClose"
115- case protocol.PickerSelection:
116- return "PickerSelection"
117- default:
118- return ""
119- }
120-}
121-
122-// serverMessageNameForTest mirrors the internal package's naming table for
123-// server envelope payloads.
124-func serverMessageNameForTest(payload []byte) string {
125- message, err := sessionwire.DecodeServerEnvelope(payload)
126- if err != nil {
127- return ""
128- }
129- switch message.(type) {
130- case protocol.Welcome:
131- return "Welcome"
132- case protocol.ErrorMsg:
133- return "Error"
134- case protocol.Output:
135- return "Output"
136- case protocol.Detached:
137- return "Detached"
138- case protocol.Pong:
139- return "Pong"
140- case protocol.Sessions:
141- return "Sessions"
142- case protocol.CommandResult:
143- return "CommandResult"
144- case protocol.KillResult:
145- return "KillResult"
146- case protocol.AttachTarget:
147- return "AttachTarget"
148- case protocol.RemotePreview:
149- return "RemotePreview"
150- case protocol.CommittedRouteIdentity:
151- return "CommittedRouteIdentity"
152- case protocol.RouteNavigationAction:
153- return "RouteNavigationAction"
154- case protocol.RouteCreateSessionAction:
155- return "RouteCreateSessionAction"
156- case protocol.RouteNavigationFailure:
157- return "RouteNavigationFailure"
158- case protocol.RoutePosition:
159- return "RoutePosition"
160- case protocol.RouteRetired:
161- return "RouteRetired"
162- case protocol.SamePeerSwitchFailure:
163- return "SamePeerSwitchFailure"
164- case protocol.UIReceipt:
165- return "UIReceipt"
166- case protocol.UIViewUpdate:
167- return "UIViewUpdate"
168- case protocol.NavigationInventoryResponse:
169- return "NavigationInventoryResponse"
170- case protocol.NavigationInventoryDemand:
171- return "NavigationInventoryDemand"
172- case protocol.NavigationInventorySelection:
173- return "NavigationInventorySelection"
174- case protocol.PickerOffer:
175- return "PickerOffer"
176- case protocol.PickerSnapshot:
177- return "PickerSnapshot"
178- case protocol.PickerClosed:
179- return "PickerClosed"
180- case protocol.PickerResult:
181- return "PickerResult"
182- case protocol.PickerFailure:
183- return "PickerFailure"
184- default:
185- return ""
186- }
187-}
@@ -1,36 +1,11 @@
1 package client_test1 package client_test
2 2
3 import (3 import (
4- "testing"
5-
6- "github.com/stretchr/testify/require"
7-
8 "github.com/bnema/vev/internal/adapters/sessionwire"4 "github.com/bnema/vev/internal/adapters/sessionwire"
9- "github.com/bnema/vev/internal/domain"
10 "github.com/bnema/vev/internal/protocol"5 "github.com/bnema/vev/internal/protocol"
11 "github.com/bnema/vev/internal/protocol/wire"6 "github.com/bnema/vev/internal/protocol/wire"
12 )7 )
13 8
14-// mustServerEnvelope wraps one semantic server message in the envelope the
15-// wire.Transport exchanges. Replay-only output fixtures that predate the
16-// publication context still model valid v41 semantic publications, so the
17-// context is filled in before encoding.
18-func mustServerEnvelope(message protocol.ServerMessage) wire.Envelope {
19- if output, ok := message.(protocol.Output); ok && output.New != 0 && output.Context == nil {
20- output.Context = &protocol.ViewContext{
21- Publication: output.Epoch<<32 | output.New,
22- Route: protocol.CommittedRouteIdentity{Target: protocol.ExactSessionTarget{LifecycleID: domain.SessionLifecycleID{1}, SessionName: "work"}},
23- TabID: "tab-1", FocusedPaneID: "pane-1",
24- }
25- message = output
26- }
27- raw, err := sessionwire.EncodeServerMessage(message)
28- if err != nil {
29- panic(err)
30- }
31- return wire.Envelope{Payload: raw}
32-}
33-
34 // mustClientEnvelope wraps one semantic client message in the envelope the9 // mustClientEnvelope wraps one semantic client message in the envelope the
35 // wire.Transport exchanges.10 // wire.Transport exchanges.
36 func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {11 func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {
@@ -40,148 +15,3 @@ func mustClientEnvelope(message protocol.ClientMessage) wire.Envelope {
40 }15 }
41 return wire.Envelope{Payload: raw}16 return wire.Envelope{Payload: raw}
42 }17 }
43-
44-// decodeClientMessageForTest unwraps one client envelope for assertions.
45-func decodeClientMessageForTest(t *testing.T, envelope wire.Envelope) protocol.ClientMessage {
46- t.Helper()
47- message, err := sessionwire.DecodeClientEnvelope(envelope.Payload)
48- require.NoError(t, err)
49- return message
50-}
51-
52-// clientMessageName mirrors the internal package's naming table so external
53-// transport expectations can match typed client messages by kind.
54-func clientMessageName(t *testing.T, envelope wire.Envelope) string {
55- if t != nil {
56- t.Helper()
57- }
58- message, err := sessionwire.DecodeClientEnvelope(envelope.Payload)
59- if err != nil {
60- return ""
61- }
62- switch message.(type) {
63- case protocol.SuspendAttachment:
64- return "SuspendAttachment"
65- case protocol.ActivateAttachment:
66- return "ActivateAttachment"
67- case protocol.Hello:
68- return "Hello"
69- case protocol.Input:
70- return "Input"
71- case protocol.Resize:
72- return "Resize"
73- case protocol.Detach:
74- return "Detach"
75- case protocol.Ping:
76- return "Ping"
77- case protocol.List:
78- return "List"
79- case protocol.Kill:
80- return "Kill"
81- case protocol.Theme:
82- return "Theme"
83- case protocol.Ack:
84- return "Ack"
85- case protocol.ImagePush:
86- return "ImagePush"
87- case protocol.ClientNotice:
88- return "ClientNotice"
89- case protocol.CommandRequest:
90- return "CommandRequest"
91- case protocol.OutputResetRequest:
92- return "OutputResetRequest"
93- case protocol.UIFence:
94- return "UIFence"
95- case protocol.RemotePreviewWatch:
96- return "RemotePreviewWatch"
97- case protocol.RouteAttentionSubscription:
98- return "RouteAttentionSubscription"
99- case protocol.SamePeerSwitchRequest:
100- return "SamePeerSwitchRequest"
101- case protocol.RecentRouteSnapshot:
102- return "RecentRouteSnapshot"
103- case protocol.RouteNavigationFailure:
104- return "RouteNavigationFailure"
105- case protocol.SessionCreationFailure:
106- return "SessionCreationFailure"
107- case protocol.NavigationInventoryRequest:
108- return "NavigationInventoryRequest"
109- case protocol.NavigationInventoryPublication:
110- return "NavigationInventoryPublication"
111- case protocol.NavigationInventoryFailure:
112- return "NavigationInventoryFailure"
113- case protocol.PickerClose:
114- return "PickerClose"
115- case protocol.PickerSelection:
116- return "PickerSelection"
117- default:
118- return ""
119- }
120-}
121-
122-// serverMessageNameForTest mirrors the internal package's naming table for
123-// server envelope payloads.
124-func serverMessageNameForTest(payload []byte) string {
125- message, err := sessionwire.DecodeServerEnvelope(payload)
126- if err != nil {
127- return ""
128- }
129- switch message.(type) {
130- case protocol.Welcome:
131- return "Welcome"
132- case protocol.ErrorMsg:
133- return "Error"
134- case protocol.Output:
135- return "Output"
136- case protocol.Detached:
137- return "Detached"
138- case protocol.Pong:
139- return "Pong"
140- case protocol.Sessions:
141- return "Sessions"
142- case protocol.CommandResult:
143- return "CommandResult"
144- case protocol.KillResult:
145- return "KillResult"
146- case protocol.AttachTarget:
147- return "AttachTarget"
148- case protocol.RemotePreview:
149- return "RemotePreview"
150- case protocol.CommittedRouteIdentity:
151- return "CommittedRouteIdentity"
152- case protocol.RouteNavigationAction:
153- return "RouteNavigationAction"
154- case protocol.RouteCreateSessionAction:
155- return "RouteCreateSessionAction"
156- case protocol.RouteNavigationFailure:
157- return "RouteNavigationFailure"
158- case protocol.RoutePosition:
159- return "RoutePosition"
160- case protocol.RouteRetired:
161- return "RouteRetired"
162- case protocol.SamePeerSwitchFailure:
163- return "SamePeerSwitchFailure"
164- case protocol.UIReceipt:
165- return "UIReceipt"
166- case protocol.UIViewUpdate:
167- return "UIViewUpdate"
168- case protocol.NavigationInventoryResponse:
169- return "NavigationInventoryResponse"
170- case protocol.NavigationInventoryDemand:
171- return "NavigationInventoryDemand"
172- case protocol.NavigationInventorySelection:
173- return "NavigationInventorySelection"
174- case protocol.PickerOffer:
175- return "PickerOffer"
176- case protocol.PickerSnapshot:
177- return "PickerSnapshot"
178- case protocol.PickerClosed:
179- return "PickerClosed"
180- case protocol.PickerResult:
181- return "PickerResult"
182- case protocol.PickerFailure:
183- return "PickerFailure"
184- default:
185- return ""
186- }
187-}
M internal/usecase/daemon/picker.go +0 -29
@@ -6,7 +6,6 @@ import (
66 "sort"
77 "time"
88
9- renderer "github.com/bnema/vev-vt"
109 "github.com/bnema/vev/internal/domain"
1110 "github.com/bnema/vev/internal/protocol"
1211 "github.com/bnema/vev/internal/usecase/picker"
@@ -20,16 +19,6 @@ var pickerModal = picker.Modal
2019
2120 const remotePickerPreviewDebounce = 80 * time.Millisecond
2221
23-// pickerViews projects the shared daemon inventory for the picker. It keeps
24-// current/ephemeral rows, tabs, grouping, and move eligibility; lifecycle and
25-// remote facts come from the common capture. Section lines are published
26-// whenever the source has more than one origin group, so the presenting
27-// client can order each run locally without inventing group labels.
28-func (d *Daemon) pickerViews(cur *session, ac *attachedClient) ([]pickerSessionView, pickerSourceFilter) {
29- _, grouped, current := d.pickerViewProjections(cur, ac)
30- return grouped, current
31-}
32-
3322 // pickerLocalViews is the remote-free picker projection. The hybrid
3423 // projection interleaves foreign rows between the live and stopped rows, so
3524 // the two groups are returned separately and the stopped rows are returned
@@ -168,24 +157,6 @@ func remotePickerPreviewSize(size domain.Size) (uint16, uint16) {
168157 return uint16(min(width, protocol.RemotePreviewMaxWidth)), uint16(min(height, protocol.RemotePreviewMaxHeight))
169158 }
170159
171-func staticRemotePickerPreview(width, height uint16, message string) picker.Preview {
172- if width == 0 || height == 0 {
173- return picker.Preview{}
174- }
175- rows := [][]renderer.Cell{make([]renderer.Cell, int(width))}
176- style := renderer.DefaultStyle()
177- for x := range rows[0] {
178- rows[0][x] = renderer.Cell{Rune: ' ', Style: style}
179- }
180- for x, r := range []rune(message) {
181- if x >= int(width) {
182- break
183- }
184- rows[0][x] = renderer.Cell{Rune: r, Style: style}
185- }
186- return picker.Preview{Rows: rows, Width: int(width), Height: len(rows)}
187-}
188-
189160 // pickerRouteTargetsEqual compares the exact route identity of two picker
190161 // targets, ignoring presentation fields such as UnavailableReason that
191162 // render around the route on every observation.
@@ -6,7 +6,6 @@ import (
6 "sort"6 "sort"
7 "time"7 "time"
8 8
9- renderer "github.com/bnema/vev-vt"
10 "github.com/bnema/vev/internal/domain"9 "github.com/bnema/vev/internal/domain"
11 "github.com/bnema/vev/internal/protocol"10 "github.com/bnema/vev/internal/protocol"
12 "github.com/bnema/vev/internal/usecase/picker"11 "github.com/bnema/vev/internal/usecase/picker"
@@ -20,16 +19,6 @@ var pickerModal = picker.Modal
20 19
21 const remotePickerPreviewDebounce = 80 * time.Millisecond20 const remotePickerPreviewDebounce = 80 * time.Millisecond
22 21
23-// pickerViews projects the shared daemon inventory for the picker. It keeps
24-// current/ephemeral rows, tabs, grouping, and move eligibility; lifecycle and
25-// remote facts come from the common capture. Section lines are published
26-// whenever the source has more than one origin group, so the presenting
27-// client can order each run locally without inventing group labels.
28-func (d *Daemon) pickerViews(cur *session, ac *attachedClient) ([]pickerSessionView, pickerSourceFilter) {
29- _, grouped, current := d.pickerViewProjections(cur, ac)
30- return grouped, current
31-}
32-
33 // pickerLocalViews is the remote-free picker projection. The hybrid22 // pickerLocalViews is the remote-free picker projection. The hybrid
34 // projection interleaves foreign rows between the live and stopped rows, so23 // projection interleaves foreign rows between the live and stopped rows, so
35 // the two groups are returned separately and the stopped rows are returned24 // the two groups are returned separately and the stopped rows are returned
@@ -168,24 +157,6 @@ func remotePickerPreviewSize(size domain.Size) (uint16, uint16) {
168 return uint16(min(width, protocol.RemotePreviewMaxWidth)), uint16(min(height, protocol.RemotePreviewMaxHeight))157 return uint16(min(width, protocol.RemotePreviewMaxWidth)), uint16(min(height, protocol.RemotePreviewMaxHeight))
169 }158 }
170 159
171-func staticRemotePickerPreview(width, height uint16, message string) picker.Preview {
172- if width == 0 || height == 0 {
173- return picker.Preview{}
174- }
175- rows := [][]renderer.Cell{make([]renderer.Cell, int(width))}
176- style := renderer.DefaultStyle()
177- for x := range rows[0] {
178- rows[0][x] = renderer.Cell{Rune: ' ', Style: style}
179- }
180- for x, r := range []rune(message) {
181- if x >= int(width) {
182- break
183- }
184- rows[0][x] = renderer.Cell{Rune: r, Style: style}
185- }
186- return picker.Preview{Rows: rows, Width: int(width), Height: len(rows)}
187-}
188-
189 // pickerRouteTargetsEqual compares the exact route identity of two picker160 // pickerRouteTargetsEqual compares the exact route identity of two picker
190 // targets, ignoring presentation fields such as UnavailableReason that161 // targets, ignoring presentation fields such as UnavailableReason that
191 // render around the route on every observation.162 // render around the route on every observation.

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 12

Tags 11

↑↓ moveenter openesc close