detached 9ad3737

fix: address CodeRabbit review comments for tests and CEF infra

- navigate_test.go: increase sleep multiplier to 3× with comment explaining
  why deterministic sync isn't feasible for the history worker flush
- navigate_test.go: add comment on historyWorkerRegressionRepo explaining
  why mockery can't express the re-enqueue-during-Save callback pattern
- context_menu.go: document that clickCb capturing popover by reference is
  safe because button is not clickable until after Popup()
- engine_init.go: document CWD-based log path as intentional dev-mode default
commit
9ad373788ffb55b4cf4f2141045d214d2e3c6321
author
brice · · 2026-03-21 20:19 UTC
committer
brice · · 2026-03-28 04:38 UTC
parent
c5aba1b
signature
GPG VerifiedCD88F9E564E0102646FB6077A1A07C7C7C3E349D · arch-gpg Verified for the committer email
3 files · +13 -2
M internal/application/usecase/navigate_test.go +8 -2
@@ -107,8 +107,10 @@ func TestHistoryWorker_ReenqueueDuringFlushIsPersistedOnShutdown(t *testing.T) {
107107 uc = NewNavigateUseCase(repo, nil, entity.ZoomDefault)
108108 uc.RecordHistory(ctx, "pane-1", "https://example.com/article")
109109
110- // Give the worker enough time to hit the periodic flush before shutdown.
111- time.Sleep(historyWorkerFlushInterval * 2)
110+ // The history worker flushes on a timer; there is no exported sync/flush
111+ // mechanism we can hook into, so we sleep for 3× the flush interval to
112+ // give it a comfortable margin before shutting down.
113+ time.Sleep(historyWorkerFlushInterval * 3)
112114 uc.Close()
113115
114116 entry, err := repo.FindByURL(ctx, "https://example.com/article")
@@ -118,6 +120,10 @@ func TestHistoryWorker_ReenqueueDuringFlushIsPersistedOnShutdown(t *testing.T) {
118120 require.Equal(t, "Queued title", entry.Title)
119121 }
120122
123+// historyWorkerRegressionRepo is a hand-rolled fake instead of a mockery
124+// mock because mockery cannot express the re-enqueue-during-Save callback
125+// pattern needed for this regression test (onSave fires a second write
126+// back into the use-case while the first Save is still in progress).
121127 type historyWorkerRegressionRepo struct {
122128 mu sync.Mutex
123129 byURL map[string]*entity.HistoryEntry
@@ -107,8 +107,10 @@ func TestHistoryWorker_ReenqueueDuringFlushIsPersistedOnShutdown(t *testing.T) {
107 uc = NewNavigateUseCase(repo, nil, entity.ZoomDefault)107 uc = NewNavigateUseCase(repo, nil, entity.ZoomDefault)
108 uc.RecordHistory(ctx, "pane-1", "https://example.com/article")108 uc.RecordHistory(ctx, "pane-1", "https://example.com/article")
109 109
110- // Give the worker enough time to hit the periodic flush before shutdown.110+ // The history worker flushes on a timer; there is no exported sync/flush
111- time.Sleep(historyWorkerFlushInterval * 2)111+ // mechanism we can hook into, so we sleep for 3× the flush interval to
112+ // give it a comfortable margin before shutting down.
113+ time.Sleep(historyWorkerFlushInterval * 3)
112 uc.Close()114 uc.Close()
113 115
114 entry, err := repo.FindByURL(ctx, "https://example.com/article")116 entry, err := repo.FindByURL(ctx, "https://example.com/article")
@@ -118,6 +120,10 @@ func TestHistoryWorker_ReenqueueDuringFlushIsPersistedOnShutdown(t *testing.T) {
118 require.Equal(t, "Queued title", entry.Title)120 require.Equal(t, "Queued title", entry.Title)
119 }121 }
120 122
123+// historyWorkerRegressionRepo is a hand-rolled fake instead of a mockery
124+// mock because mockery cannot express the re-enqueue-during-Save callback
125+// pattern needed for this regression test (onSave fires a second write
126+// back into the use-case while the first Save is still in progress).
121 type historyWorkerRegressionRepo struct {127 type historyWorkerRegressionRepo struct {
122 mu sync.Mutex128 mu sync.Mutex
123 byURL map[string]*entity.HistoryEntry129 byURL map[string]*entity.HistoryEntry
M internal/infrastructure/cef/context_menu.go +3 -0
@@ -85,6 +85,9 @@ func showContextMenu(wv *WebView, items []menuEntry, x, y int32, callback purece
8585 btn.AddCssClass("flat")
8686
8787 cmdID := item.commandID
88+ // clickCb captures popover by reference; this is safe because the
89+ // button cannot be clicked until after Popup() is called below,
90+ // at which point popover is fully initialised.
8891 clickCb := func(_ gtk.Button) {
8992 selected = true
9093 callback.Cont(cmdID, 0)
@@ -85,6 +85,9 @@ func showContextMenu(wv *WebView, items []menuEntry, x, y int32, callback purece
85 btn.AddCssClass("flat")85 btn.AddCssClass("flat")
86 86
87 cmdID := item.commandID87 cmdID := item.commandID
88+ // clickCb captures popover by reference; this is safe because the
89+ // button cannot be clicked until after Popup() is called below,
90+ // at which point popover is fully initialised.
88 clickCb := func(_ gtk.Button) {91 clickCb := func(_ gtk.Button) {
89 selected = true92 selected = true
90 callback.Cont(cmdID, 0)93 callback.Cont(cmdID, 0)
M internal/infrastructure/cef/engine_init.go +2 -0
@@ -257,6 +257,8 @@ func prepareCEFLogFile(cfg config.CEFEngineConfig) (string, error) {
257257 return runtimeLogFile, nil
258258 }
259259
260+ // Dev-mode default: logs go into .dev/dumber/logs/ relative to CWD.
261+ // Production deployments should set cfg.LogFile explicitly.
260262 cwd, cwdErr := os.Getwd()
261263 if cwdErr != nil {
262264 return "", fmt.Errorf("getwd: %w", cwdErr)
@@ -257,6 +257,8 @@ func prepareCEFLogFile(cfg config.CEFEngineConfig) (string, error) {
257 return runtimeLogFile, nil257 return runtimeLogFile, nil
258 }258 }
259 259
260+ // Dev-mode default: logs go into .dev/dumber/logs/ relative to CWD.
261+ // Production deployments should set cfg.LogFile explicitly.
260 cwd, cwdErr := os.Getwd()262 cwd, cwdErr := os.Getwd()
261 if cwdErr != nil {263 if cwdErr != nil {
262 return "", fmt.Errorf("getwd: %w", cwdErr)264 return "", fmt.Errorf("getwd: %w", cwdErr)

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 8

Tags 42

↑↓ moveenter openesc close