diff options
| author | Paul Buetow <paul@buetow.org> | 2026-03-16 03:10:55 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-03-16 03:10:55 +0200 |
| commit | 1fc1611fa99993cab5dc8bf0844183285296e3b2 (patch) | |
| tree | c5c9b8b5abac5b5d4c0d56ed90b0580184cc4383 /cmd/hexai-tmux-action | |
| parent | 12090f25a3677291863dbb80277bdad3eaec0324 (diff) | |
Release v0.24.0v0.24.0
Bring unit test coverage from ~75% to 85.1% project-wide. All internal
packages now exceed 80% coverage. Refactored cmd entrypoints to extract
testable run() functions with injectable seams.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'cmd/hexai-tmux-action')
| -rw-r--r-- | cmd/hexai-tmux-action/main.go | 43 | ||||
| -rw-r--r-- | cmd/hexai-tmux-action/main_test.go | 63 |
2 files changed, 98 insertions, 8 deletions
diff --git a/cmd/hexai-tmux-action/main.go b/cmd/hexai-tmux-action/main.go index 6249de3..715c41f 100644 --- a/cmd/hexai-tmux-action/main.go +++ b/cmd/hexai-tmux-action/main.go @@ -4,6 +4,7 @@ import ( "context" "flag" "fmt" + "io" "os" "strings" @@ -11,6 +12,10 @@ import ( "codeberg.org/snonux/hexai/internal/hexaiaction" ) +// runCommand is the seam for testing: override in tests to avoid launching +// the real tmux action. +var runCommand = hexaiaction.RunCommand + func main() { infile := flag.String("infile", "", "Read input from this file instead of stdin") outfile := flag.String("outfile", "", "Write output to this file instead of stdout") @@ -22,16 +27,38 @@ func main() { tmuxPercent := flag.Int("tmux-percent", 33, "tmux split size percentage (1-100)") flag.Parse() - opts := hexaiaction.Options{ - Infile: *infile, Outfile: *outfile, - UIChild: *uiChild, TmuxTarget: *tmuxTarget, TmuxSplit: *tmuxSplit, TmuxPercent: *tmuxPercent, - } - ctx := context.Background() - if path := strings.TrimSpace(*configPath); path != "" { - ctx = hexaiaction.WithConfigPath(ctx, path) + opts := actionOptions{ + infile: *infile, outfile: *outfile, + uiChild: *uiChild, configPath: *configPath, + tmuxTarget: *tmuxTarget, tmuxSplit: *tmuxSplit, tmuxPercent: *tmuxPercent, } - if err := hexaiaction.RunCommand(ctx, opts, os.Stdin, os.Stdout, os.Stderr); err != nil { + if err := run(opts, os.Stdin, os.Stdout, os.Stderr); err != nil { fmt.Fprintln(os.Stderr, err) os.Exit(1) } } + +// actionOptions holds the parsed command-line flags for hexai-tmux-action. +type actionOptions struct { + infile string + outfile string + uiChild bool + configPath string + tmuxTarget string + tmuxSplit string + tmuxPercent int +} + +// run builds the hexaiaction.Options and context, then delegates to runCommand. +func run(opts actionOptions, stdin io.Reader, stdout, stderr io.Writer) error { + haOpts := hexaiaction.Options{ + Infile: opts.infile, Outfile: opts.outfile, + UIChild: opts.uiChild, TmuxTarget: opts.tmuxTarget, + TmuxSplit: opts.tmuxSplit, TmuxPercent: opts.tmuxPercent, + } + ctx := context.Background() + if path := strings.TrimSpace(opts.configPath); path != "" { + ctx = hexaiaction.WithConfigPath(ctx, path) + } + return runCommand(ctx, haOpts, stdin, stdout, stderr) +} diff --git a/cmd/hexai-tmux-action/main_test.go b/cmd/hexai-tmux-action/main_test.go new file mode 100644 index 0000000..8abd420 --- /dev/null +++ b/cmd/hexai-tmux-action/main_test.go @@ -0,0 +1,63 @@ +package main + +import ( + "context" + "errors" + "io" + "testing" + + "codeberg.org/snonux/hexai/internal/hexaiaction" +) + +func TestRun_DelegatesToRunCommand(t *testing.T) { + old := runCommand + t.Cleanup(func() { runCommand = old }) + + var gotOpts hexaiaction.Options + runCommand = func(_ context.Context, opts hexaiaction.Options, _ io.Reader, _, _ io.Writer) error { + gotOpts = opts + return nil + } + + opts := actionOptions{ + infile: "in.txt", outfile: "out.txt", + tmuxSplit: "h", tmuxPercent: 50, + } + if err := run(opts, nil, nil, nil); err != nil { + t.Fatalf("run: %v", err) + } + if gotOpts.Infile != "in.txt" || gotOpts.Outfile != "out.txt" { + t.Fatalf("unexpected opts: %+v", gotOpts) + } + if gotOpts.TmuxSplit != "h" || gotOpts.TmuxPercent != 50 { + t.Fatalf("unexpected tmux opts: %+v", gotOpts) + } +} + +func TestRun_WithConfigPath(t *testing.T) { + old := runCommand + t.Cleanup(func() { runCommand = old }) + + runCommand = func(_ context.Context, _ hexaiaction.Options, _ io.Reader, _, _ io.Writer) error { + return nil + } + + opts := actionOptions{configPath: " /tmp/test.toml ", tmuxSplit: "v", tmuxPercent: 33} + if err := run(opts, nil, nil, nil); err != nil { + t.Fatalf("run: %v", err) + } +} + +func TestRun_Error(t *testing.T) { + old := runCommand + t.Cleanup(func() { runCommand = old }) + + wantErr := errors.New("action failed") + runCommand = func(_ context.Context, _ hexaiaction.Options, _ io.Reader, _, _ io.Writer) error { + return wantErr + } + + if err := run(actionOptions{}, nil, nil, nil); !errors.Is(err, wantErr) { + t.Fatalf("expected error, got: %v", err) + } +} |
