open-code-review/cmd/opencodereview/flags_test.go
kite 9a11fc1302 test: improve coverage for cmd/opencodereview package from 42% to 70%
Add comprehensive unit tests covering config dispatch, emit run result,
git helpers, provider commands, provider TUI pure functions and View
rendering, shared utilities, flags parsing, scan command flags, and
small file entry points (version, viewer, llm, rules commands).
2026-06-27 01:47:48 +08:00

194 lines
5 KiB
Go

package main
import (
"testing"
"time"
)
func TestParseReviewFlagsModelOverride(t *testing.T) {
opts, err := parseReviewFlags([]string{"--model", "claude-opus-4-6"})
if err != nil {
t.Fatalf("parseReviewFlags: %v", err)
}
if opts.model != "claude-opus-4-6" {
t.Errorf("model = %q, want %q", opts.model, "claude-opus-4-6")
}
if opts.outputFormat != "text" {
t.Errorf("outputFormat = %q, want %q", opts.outputFormat, "text")
}
if opts.audience != "human" {
t.Errorf("audience = %q, want %q", opts.audience, "human")
}
}
func TestParseReviewFlags_InvalidAudience(t *testing.T) {
_, err := parseReviewFlags([]string{"--audience", "robot"})
if err == nil {
t.Fatal("expected error for invalid audience")
}
}
func TestParseReviewFlags_NegativeMaxTools(t *testing.T) {
_, err := parseReviewFlags([]string{"--max-tools", "-1"})
if err == nil {
t.Fatal("expected error for negative max-tools")
}
}
func TestParseReviewFlags_MaxToolsBelowMin(t *testing.T) {
opts, err := parseReviewFlags([]string{"--max-tools", "5"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if opts.maxTools != 10 {
t.Errorf("maxTools = %d, want 10 (clamped to min)", opts.maxTools)
}
}
func TestParseReviewFlags_NegativeMaxGitProcs(t *testing.T) {
_, err := parseReviewFlags([]string{"--max-git-procs", "-1"})
if err == nil {
t.Fatal("expected error for negative max-git-procs")
}
}
func TestParseReviewFlags_ConflictingModes(t *testing.T) {
_, err := parseReviewFlags([]string{"--from", "main", "--to", "dev", "--commit", "abc"})
if err == nil {
t.Fatal("expected error for conflicting modes")
}
}
func TestParseReviewFlags_FromWithoutTo(t *testing.T) {
_, err := parseReviewFlags([]string{"--from", "main"})
if err == nil {
t.Fatal("expected error for --from without --to")
}
}
func TestParseReviewFlags_ToWithoutFrom(t *testing.T) {
_, err := parseReviewFlags([]string{"--to", "dev"})
if err == nil {
t.Fatal("expected error for --to without --from")
}
}
func TestParseReviewFlags_Help(t *testing.T) {
opts, err := parseReviewFlags([]string{"-h"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !opts.showHelp {
t.Error("expected showHelp=true")
}
}
func TestParseReviewFlags_ShortFlags(t *testing.T) {
opts, err := parseReviewFlags([]string{"-c", "abc123", "-f", "json", "-p"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if opts.commit != "abc123" {
t.Errorf("commit = %q, want abc123", opts.commit)
}
if opts.outputFormat != "json" {
t.Errorf("outputFormat = %q, want json", opts.outputFormat)
}
if !opts.preview {
t.Error("expected preview=true")
}
}
func TestParseConfigArgs_Empty(t *testing.T) {
_, err := parseConfigArgs(nil)
if err == nil {
t.Fatal("expected error for empty args")
}
}
func TestParseConfigArgs_Set(t *testing.T) {
act, err := parseConfigArgs([]string{"set", "llm.model", "gpt-4"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if act.subCmd != "set" || act.key != "llm.model" || act.value != "gpt-4" {
t.Errorf("got %+v", act)
}
}
func TestParseConfigArgs_SetMissingValue(t *testing.T) {
_, err := parseConfigArgs([]string{"set", "llm.model"})
if err == nil {
t.Fatal("expected error for missing value")
}
}
func TestParseConfigArgs_Unset(t *testing.T) {
act, err := parseConfigArgs([]string{"unset", "custom_providers.foo"})
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if act.subCmd != "unset" || act.key != "custom_providers.foo" {
t.Errorf("got %+v", act)
}
}
func TestParseConfigArgs_UnsetMissingKey(t *testing.T) {
_, err := parseConfigArgs([]string{"unset"})
if err == nil {
t.Fatal("expected error for missing key")
}
}
func TestParseConfigArgs_UnknownSubCmd(t *testing.T) {
_, err := parseConfigArgs([]string{"delete", "foo"})
if err == nil {
t.Fatal("expected error for unknown subcommand")
}
}
func TestDurationVar(t *testing.T) {
fs := newOcrFlagSet("test")
var d time.Duration
fs.DurationVar(&d, "timeout", 5*time.Second, "max duration")
if err := fs.Parse([]string{"--timeout", "10s"}); err != nil {
t.Fatalf("parse: %v", err)
}
if d != 10*time.Second {
t.Errorf("d = %v, want 10s", d)
}
}
func TestPrintDefaults(t *testing.T) {
fs := newOcrFlagSet("test")
var s string
fs.StringVar(&s, "name", "default", "a name")
fs.PrintDefaults()
}
func TestExpandShortFlags(t *testing.T) {
m := map[string]string{"c": "commit", "f": "format"}
tests := []struct {
name string
args []string
want []string
}{
{"expands short", []string{"-c", "abc"}, []string{"--commit", "abc"}},
{"keeps long", []string{"--format", "json"}, []string{"--format", "json"}},
{"unknown short kept", []string{"-x", "val"}, []string{"-x", "val"}},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got := expandShortFlags(tc.args, m)
if len(got) != len(tc.want) {
t.Fatalf("got %v, want %v", got, tc.want)
}
for i := range tc.want {
if got[i] != tc.want[i] {
t.Errorf("[%d] = %q, want %q", i, got[i], tc.want[i])
}
}
})
}
}