返回 DeepSeek-Reasonix
flag_parse_test.go
根目录 / internal / cli / flag_parse_test.go
1 package cli
2
3 import (
4 "flag"
5 "strings"
6 "testing"
7
8 "github.com/spf13/pflag"
9 )
10
11 func TestParseCommandFlagsReportsErrors(t *testing.T) {
12 tests := []struct {
13 name string
14 newFlagSet func() commandFlagSet
15 args []string
16 want string
17 }{
18 {
19 name: "unknown pflag",
20 newFlagSet: func() commandFlagSet {
21 return pflag.NewFlagSet("test", pflag.ContinueOnError)
22 },
23 args: []string{"--unknown"},
24 want: "unknown flag: --unknown",
25 },
26 {
27 name: "invalid pflag value",
28 newFlagSet: func() commandFlagSet {
29 fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
30 fs.Int("count", 0, "item count")
31 return fs
32 },
33 args: []string{"--count=invalid"},
34 want: "invalid argument \"invalid\" for \"--count\" flag",
35 },
36 {
37 name: "missing pflag value",
38 newFlagSet: func() commandFlagSet {
39 fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
40 fs.String("model", "", "model name")
41 return fs
42 },
43 args: []string{"--model"},
44 want: "flag needs an argument: --model",
45 },
46 {
47 name: "unknown standard flag",
48 newFlagSet: func() commandFlagSet {
49 return flag.NewFlagSet("test", flag.ContinueOnError)
50 },
51 args: []string{"--unknown"},
52 want: "flag provided but not defined: -unknown",
53 },
54 }
55
56 for _, tt := range tests {
57 t.Run(tt.name, func(t *testing.T) {
58 var code int
59 var proceed bool
60 stderr := captureStderr(t, func() {
61 code, proceed = parseCommandFlags(tt.newFlagSet(), tt.args)
62 })
63 if code != 2 || proceed {
64 t.Fatalf("parseCommandFlags(%q) = (%d, %v), want (2, false)", tt.args, code, proceed)
65 }
66 if !strings.Contains(stderr, tt.want) {
67 t.Fatalf("stderr = %q, want %q", stderr, tt.want)
68 }
69 if strings.Contains(stderr, "Usage of") {
70 t.Fatalf("parse error should be concise, got usage in stderr:\n%s", stderr)
71 }
72 })
73 }
74 }
75
76 func TestParseCommandFlagsTreatsHelpAsSuccess(t *testing.T) {
77 tests := []struct {
78 name string
79 newFlagSet func() commandFlagSet
80 }{
81 {
82 name: "pflag",
83 newFlagSet: func() commandFlagSet {
84 fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
85 fs.String("model", "", "model name")
86 return fs
87 },
88 },
89 {
90 name: "standard flag",
91 newFlagSet: func() commandFlagSet {
92 fs := flag.NewFlagSet("test", flag.ContinueOnError)
93 fs.String("model", "", "model name")
94 return fs
95 },
96 },
97 }
98
99 for _, tt := range tests {
100 t.Run(tt.name, func(t *testing.T) {
101 var code int
102 var proceed bool
103 stdout, stderr := captureCLIOutput(t, func() {
104 code, proceed = parseCommandFlags(tt.newFlagSet(), []string{"--help"})
105 })
106 if code != 0 || proceed {
107 t.Fatalf("parseCommandFlags(--help) = (%d, %v), want (0, false)", code, proceed)
108 }
109 if !strings.Contains(stdout, "Usage of test:") || !strings.Contains(stdout, "model name") {
110 t.Fatalf("help output missing usage:\n%s", stdout)
111 }
112 if stderr != "" {
113 t.Fatalf("help wrote stderr: %q", stderr)
114 }
115 if strings.Contains(stdout, "Error:") || strings.Contains(stdout, "flag: help requested") {
116 t.Fatalf("help should not be reported as an error:\n%s", stdout)
117 }
118 })
119 }
120 }
121
122 func TestParseCommandFlagsSuccessProceedsSilently(t *testing.T) {
123 fs := pflag.NewFlagSet("test", pflag.ContinueOnError)
124 name := fs.String("name", "", "name")
125 var code int
126 var proceed bool
127 stderr := captureStderr(t, func() {
128 code, proceed = parseCommandFlags(fs, []string{"--name", "reasonix"})
129 })
130 if code != 0 || !proceed || *name != "reasonix" {
131 t.Fatalf("parseCommandFlags success = (%d, %v, %q), want (0, true, reasonix)", code, proceed, *name)
132 }
133 if stderr != "" {
134 t.Fatalf("successful parse wrote stderr: %q", stderr)
135 }
136 }
137
137 lines GO