summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-03-02 11:00:39 +0200
committerPaul Buetow <paul@buetow.org>2026-03-02 11:00:39 +0200
commitd7a20676e0f6f243b9ad15ccf2bc82ec641bc97b (patch)
treea09f8e966808a39fb2eeed031dde1f630641cf8d /internal
parent99bb2e39263dd477c8e438ff38ac1c158e4097a9 (diff)
cli: add isolated dispatch routing tests (task 401)
Diffstat (limited to 'internal')
-rw-r--r--internal/cli/cli_test.go114
1 files changed, 114 insertions, 0 deletions
diff --git a/internal/cli/cli_test.go b/internal/cli/cli_test.go
index 9ff0510..cae7f43 100644
--- a/internal/cli/cli_test.go
+++ b/internal/cli/cli_test.go
@@ -8,6 +8,7 @@ import (
"context"
"io"
"os"
+ "os/exec"
"path/filepath"
"strings"
"testing"
@@ -70,6 +71,21 @@ func testCLI(t *testing.T) (*CLI, *config.Config) {
}, cfg
}
+func initGitRepo(t *testing.T, dir string) {
+ t.Helper()
+ cmds := [][]string{
+ {"git", "init", dir},
+ {"git", "-C", dir, "config", "user.email", "test@example.com"},
+ {"git", "-C", dir, "config", "user.name", "Test"},
+ }
+ for _, args := range cmds {
+ cmd := exec.Command(args[0], args[1:]...)
+ if out, err := cmd.CombinedOutput(); err != nil {
+ t.Fatalf("%v: %v\n%s", args, err, out)
+ }
+ }
+}
+
// captureStdout redirects os.Stdout to a pipe, calls fn, then returns what was
// written and restores the original Stdout.
func captureStdout(fn func()) string {
@@ -313,6 +329,104 @@ func TestDispatch_unknownCommand(t *testing.T) {
}
}
+func TestDispatch_gitSimpleCommands(t *testing.T) {
+ c, cfg := testCLI(t)
+ initGitRepo(t, cfg.DataDir)
+
+ ctx := context.Background()
+ for _, cmd := range []string{"status", "reset", "sync"} {
+ t.Run(cmd, func(t *testing.T) {
+ _ = captureStdout(func() {
+ _ = captureStderr(func() {
+ ec := c.dispatch(ctx, []string{cmd})
+ if ec != 0 {
+ t.Errorf("dispatch(%q) = %d; want 0", cmd, ec)
+ }
+ })
+ })
+ })
+ }
+}
+
+func TestDispatch_commitNoChanges(t *testing.T) {
+ c, cfg := testCLI(t)
+ initGitRepo(t, cfg.DataDir)
+
+ ec := c.dispatch(context.Background(), []string{"commit"})
+ if ec != 1 {
+ t.Errorf("dispatch(commit) = %d; want 1 when nothing to commit", ec)
+ }
+}
+
+func TestDispatch_fullCommitNoChanges(t *testing.T) {
+ c, cfg := testCLI(t)
+ initGitRepo(t, cfg.DataDir)
+
+ ec := c.dispatch(context.Background(), []string{"fullcommit"})
+ if ec != 1 {
+ t.Errorf("dispatch(fullcommit) = %d; want 1 when commit step fails", ec)
+ }
+}
+
+func TestDispatchSearch_usesLastResultFallback(t *testing.T) {
+ c, cfg := testCLI(t)
+ initGitRepo(t, cfg.DataDir)
+
+ ctx := context.Background()
+ if err := c.st.Add(ctx, "fallback/entry", "secret"); err != nil {
+ t.Fatalf("Add: %v", err)
+ }
+ c.lastResult = "fallback/entry"
+
+ out := captureStdout(func() {
+ ec := c.dispatch(ctx, []string{"search"})
+ if ec != 0 {
+ t.Fatalf("dispatch(search with fallback) = %d; want 0", ec)
+ }
+ })
+ if !strings.Contains(out, "fallback/entry") {
+ t.Fatalf("expected fallback search output to contain entry, got %q", out)
+ }
+ if c.lastResult != "fallback/entry" {
+ t.Fatalf("lastResult = %q; want fallback/entry", c.lastResult)
+ }
+}
+
+func TestDispatchPickerAction(t *testing.T) {
+ c, cfg := testCLI(t)
+ initGitRepo(t, cfg.DataDir)
+
+ ctx := context.Background()
+ if err := c.st.Add(ctx, "picker/entry.txt", "picker content"); err != nil {
+ t.Fatalf("Add: %v", err)
+ }
+
+ t.Run("select is no-op", func(t *testing.T) {
+ ec := c.dispatchPickerAction(ctx, store.PickerResult{
+ Description: "picker/entry.txt",
+ Action: store.PickerSelect,
+ })
+ if ec != 0 {
+ t.Fatalf("dispatchPickerAction(select) = %d; want 0", ec)
+ }
+ })
+
+ t.Run("cat routes through dispatch", func(t *testing.T) {
+ out := captureStdout(func() {
+ ec := c.dispatchPickerAction(ctx, store.PickerResult{
+ Description: "picker/entry.txt",
+ Action: store.PickerCat,
+ })
+ if ec != 0 {
+ t.Fatalf("dispatchPickerAction(cat) = %d; want 0", ec)
+ }
+ })
+ if !strings.Contains(out, "picker/entry.txt") {
+ t.Fatalf("picker cat output missing description, got %q", out)
+ }
+ })
+}
+
// ---- readPIN ----------------------------------------------------------------
// TestReadPIN_envVar verifies that readPIN returns the $PIN value immediately