Files
weatherreporter/internal/cli/run_test.go

96 lines
3.3 KiB
Go

package cli
import (
"bytes"
"context"
"os"
"path/filepath"
"strings"
"testing"
"time"
"gitea.maximumdirect.net/eric/weatherreporter/internal/promptexec"
"gitea.maximumdirect.net/eric/weatherreporter/internal/timeutil"
)
func TestParseRunFlagsAcceptsPromptDebugDirectory(t *testing.T) {
opts, err := parseRunFlags([]string{"--llm-debug-dir", "/tmp/prompt-debug"})
if err != nil || opts.LLMDebugDir != "/tmp/prompt-debug" {
t.Fatalf("parseRunFlags() = %#v, %v", opts, err)
}
}
func TestResolveRunActionConstructsOneExecutor(t *testing.T) {
for _, command := range []string{"morning", "evening"} {
t.Run(command, func(t *testing.T) {
configPath := filepath.Join(t.TempDir(), "config.yml")
if err := os.WriteFile(configPath, []byte("weather_api:\n base_url: https://weather.api.example.com/\n"), 0o600); err != nil {
t.Fatal(err)
}
calls := 0
executor := &factoryExecutor{}
runner := Runner{
Clock: timeutil.FixedClock{Time: time.Date(2026, 5, 29, 8, 0, 0, 0, time.UTC)},
ExecutorFactory: func(PromptExecutorConfig) (promptexec.Executor, error) {
calls++
return executor, nil
},
}
req, _, err := runner.resolveRunAction([]string{command, "--config", configPath, "--llm-debug-dir", "/tmp/debug"})
if err != nil || calls != 1 || req.Executor != executor || req.LLMDebugDir != "/tmp/debug" {
t.Fatalf("resolveRunAction() request/error/calls = %#v/%v/%d", req, err, calls)
}
})
}
}
func TestResolveGenerateActionUsesInjectedWorkingDirectoryForOutputOverrides(t *testing.T) {
workingDir := t.TempDir()
configPath := filepath.Join(t.TempDir(), "config.yml")
if err := os.WriteFile(configPath, []byte("weather_api:\n base_url: https://weather.api.example.com/\n"), 0o600); err != nil {
t.Fatal(err)
}
absoluteOutput := filepath.Join(t.TempDir(), "daily.md")
for _, scenario := range []struct {
name string
out string
want string
}{
{name: "default", want: ""},
{name: "relative", out: "reports/daily.md", want: filepath.Join(workingDir, "reports", "daily.md")},
{name: "absolute", out: absoluteOutput, want: absoluteOutput},
} {
t.Run(scenario.name, func(t *testing.T) {
runner := Runner{
Clock: timeutil.FixedClock{Time: time.Date(2026, 5, 29, 8, 0, 0, 0, time.UTC)},
WorkingDir: workingDir,
ExecutorFactory: func(PromptExecutorConfig) (promptexec.Executor, error) {
return &factoryExecutor{}, nil
},
}
args := []string{"daily", "--date", "2026-05-29", "--config", configPath}
if scenario.out != "" {
args = append(args, "--out", scenario.out)
}
req, _, err := runner.resolveGenerateAction(args)
if err != nil || req.WorkingDir != workingDir || req.OutputPath != scenario.want {
t.Fatalf("resolveGenerateAction() request/error = %#v/%v", req, err)
}
})
}
}
func TestInspectCommandIsUnknownAndAbsentFromHelp(t *testing.T) {
var stdout, stderr bytes.Buffer
err := (Runner{}).Run(context.Background(), []string{"inspect", "reports"}, &stdout, &stderr)
if err == nil || err.Error() != `unknown command "inspect"` {
t.Fatalf("Run(inspect) error = %v", err)
}
if err := (Runner{}).Run(context.Background(), []string{"--help"}, &stdout, &stderr); err != nil {
t.Fatalf("Run(--help) error = %v", err)
}
if strings.Contains(stdout.String(), "inspect") {
t.Fatalf("help contains removed inspect command:\n%s", stdout.String())
}
}