main ece7682

picker_failsafe_test.go RawHistoryFolder

1package daemon
2
3import (
4	"sync"
5	"testing"
6	"time"
7
8	"github.com/stretchr/testify/require"
9
10	"github.com/bnema/vev/internal/ports"
11	"github.com/bnema/vev/internal/protocol"
12)
13
14// pickerGraceClock is a settable daemon clock. A hand-written fake is used
15// because render and attention workers read Now concurrently with the test's
16// Advance, which a mock expectation cannot express without obscuring the race
17// the mutex exists to prevent.
18type pickerGraceClock struct {
19	mu  sync.Mutex
20	now time.Time
21}
22
23func (c *pickerGraceClock) Now() time.Time {
24	c.mu.Lock()
25	defer c.mu.Unlock()
26	return c.now
27}
28
29func (c *pickerGraceClock) Advance(d time.Duration) {
30	c.mu.Lock()
31	c.now = c.now.Add(d)
32	c.mu.Unlock()
33}
34
35func (*pickerGraceClock) NewTimer(time.Duration) ports.Timer { return stubTimer{} }
36
37// TestMovePickerInputFailSafe pins that raw input is never swallowed without a
38// live offer: bytes that arrive inside the acquisition grace were in flight
39// before the client saw the offer and are dropped, while raw input after the
40// grace proves the client never took the interaction and releases it.
41func TestMovePickerInputFailSafe(t *testing.T) {
42	tests := []struct {
43		name         string
44		elapsed      time.Duration
45		wantOpen     bool
46		wantReleased bool
47	}{
48		{name: "in-flight input inside the grace is dropped", elapsed: 0, wantOpen: true},
49		{name: "input just before the grace is still dropped", elapsed: pickerAcquisitionGrace - time.Millisecond, wantOpen: true},
50		{name: "input after the grace releases the interaction", elapsed: pickerAcquisitionGrace, wantReleased: true},
51	}
52	for _, tt := range tests {
53		t.Run(tt.name, func(t *testing.T) {
54			clock := &pickerGraceClock{now: time.Unix(100, 0)}
55			d, source, ac, _, _, releases, sends := setupMovePickerSessionsCore(t, clock, 0)
56			defer releaseAll(releases)
57
58			openMovePickerForTest(t, d, ac, source, protocol.PickerIntentMovePane, moveSourceForSession(source, ac, "source-tab", "source-pane"))
59			ac.overlays.pickerMu.Lock()
60			interaction := ac.overlays.pickerInteraction
61			ac.overlays.pickerMu.Unlock()
62			clock.Advance(tt.elapsed)
63
64			effect := pickActionEffectForTest(t, source, ac)
65			d.handleInputForAttachment(effect, []byte("a"))
66			effect.End()
67
68			require.Equal(t, tt.wantOpen, ac.overlays.pickerClientActive())
69			if !tt.wantReleased {
70				return
71			}
72			closed := awaitSentServerMessage(t, sends, "PickerClosed", func(message protocol.ServerMessage) bool {
73				_, ok := message.(protocol.PickerClosed)
74				return ok
75			}).(protocol.PickerClosed)
76			require.Equal(t, interaction, closed.InteractionID)
77		})
78	}
79}

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