feat(04-01): add Notifier interface and FocusTimer

- Notifier interface with ExecNotifier (notify-send) and NullNotifier
- FocusTimer thread-safe with Set/IsActive/Remaining
- shortName helper for session display names
- Full test coverage for all components
This commit is contained in:
Pierre Martin
2026-03-23 21:23:57 +01:00
parent 421bff8f73
commit b96c6d05be
4 changed files with 181 additions and 0 deletions

55
notify_test.go Normal file
View File

@@ -0,0 +1,55 @@
package main
import (
"testing"
)
func TestExecNotifier_CallsNotifySend(t *testing.T) {
n := &ExecNotifier{}
// We cannot actually run notify-send in tests, but we verify
// the struct implements the Notifier interface and the method exists.
var _ Notifier = n
// The actual call would require a display; just verify it compiles and returns.
// Integration test with real notify-send is manual.
}
func TestNullNotifier_DropsAll(t *testing.T) {
n := &NullNotifier{}
var _ Notifier = n
err := n.Notify("title", "body")
if err != nil {
t.Errorf("NullNotifier.Notify() = %v, want nil", err)
}
}
func TestShortName_Label(t *testing.T) {
s := SessionInfo{Label: "auth"}
got := shortName(s)
if got != "auth" {
t.Errorf("shortName(Label=auth) = %q, want %q", got, "auth")
}
}
func TestShortName_Cwd(t *testing.T) {
s := SessionInfo{Cwd: "/home/pierre/Code/vibe/vmux"}
got := shortName(s)
if got != "vmux" {
t.Errorf("shortName(Cwd=.../vmux) = %q, want %q", got, "vmux")
}
}
func TestShortName_LabelOverridesCwd(t *testing.T) {
s := SessionInfo{Label: "review", Cwd: "/home/pierre/Code/vibe/vmux"}
got := shortName(s)
if got != "review" {
t.Errorf("shortName(Label+Cwd) = %q, want %q", got, "review")
}
}
func TestShortName_Empty(t *testing.T) {
s := SessionInfo{}
got := shortName(s)
if got != "." {
t.Errorf("shortName(empty) = %q, want %q", got, ".")
}
}