1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
18 func boolString(s
string) string {
25 func TestEverything(t
*testing
.T
) {
27 Bool("test_bool", false, "bool value")
28 Int("test_int", 0, "int value")
29 Int64("test_int64", 0, "int64 value")
30 Uint("test_uint", 0, "uint value")
31 Uint64("test_uint64", 0, "uint64 value")
32 String("test_string", "0", "string value")
33 Float64("test_float64", 0, "float64 value")
34 Duration("test_duration", 0, "time.Duration value")
36 m
:= make(map[string]*Flag
)
38 visitor
:= func(f
*Flag
) {
39 if len(f
.Name
) > 5 && f
.Name
[0:5] == "test_" {
43 case f
.Value
.String() == desired
:
45 case f
.Name
== "test_bool" && f
.Value
.String() == boolString(desired
):
47 case f
.Name
== "test_duration" && f
.Value
.String() == desired
+"s":
51 t
.Error("Visit: bad value", f
.Value
.String(), "for", f
.Name
)
57 t
.Error("VisitAll misses some flags")
62 m
= make(map[string]*Flag
)
65 t
.Errorf("Visit sees unset flags")
71 Set("test_bool", "true")
73 Set("test_int64", "1")
75 Set("test_uint64", "1")
76 Set("test_string", "1")
77 Set("test_float64", "1")
78 Set("test_duration", "1s")
82 t
.Error("Visit fails after set")
87 // Now test they're visited in sort order.
88 var flagNames
[]string
89 Visit(func(f
*Flag
) { flagNames
= append(flagNames
, f
.Name
) })
90 if !sort
.StringsAreSorted(flagNames
) {
91 t
.Errorf("flag names not sorted: %v", flagNames
)
95 func TestGet(t
*testing
.T
) {
97 Bool("test_bool", true, "bool value")
98 Int("test_int", 1, "int value")
99 Int64("test_int64", 2, "int64 value")
100 Uint("test_uint", 3, "uint value")
101 Uint64("test_uint64", 4, "uint64 value")
102 String("test_string", "5", "string value")
103 Float64("test_float64", 6, "float64 value")
104 Duration("test_duration", 7, "time.Duration value")
106 visitor
:= func(f
*Flag
) {
107 if len(f
.Name
) > 5 && f
.Name
[0:5] == "test_" {
108 g
, ok
:= f
.Value
.(Getter
)
110 t
.Errorf("Visit: value does not satisfy Getter: %T", f
.Value
)
117 ok
= g
.Get() == int(1)
119 ok
= g
.Get() == int64(2)
121 ok
= g
.Get() == uint(3)
123 ok
= g
.Get() == uint64(4)
127 ok
= g
.Get() == float64(6)
128 case "test_duration":
129 ok
= g
.Get() == time
.Duration(7)
132 t
.Errorf("Visit: bad value %T(%v) for %s", g
.Get(), g
.Get(), f
.Name
)
139 func TestUsage(t
*testing
.T
) {
141 ResetForTesting(func() { called
= true })
142 if CommandLine
.Parse([]string{"-x"}) == nil {
143 t
.Error("parse did not fail for unknown flag")
146 t
.Error("did not call Usage for unknown flag")
150 func testParse(f
*FlagSet
, t
*testing
.T
) {
152 t
.Error("f.Parse() = true before Parse")
154 boolFlag
:= f
.Bool("bool", false, "bool value")
155 bool2Flag
:= f
.Bool("bool2", false, "bool2 value")
156 intFlag
:= f
.Int("int", 0, "int value")
157 int64Flag
:= f
.Int64("int64", 0, "int64 value")
158 uintFlag
:= f
.Uint("uint", 0, "uint value")
159 uint64Flag
:= f
.Uint64("uint64", 0, "uint64 value")
160 stringFlag
:= f
.String("string", "0", "string value")
161 float64Flag
:= f
.Float64("float64", 0, "float64 value")
162 durationFlag
:= f
.Duration("duration", 5*time
.Second
, "time.Duration value")
163 extra
:= "one-extra-argument"
172 "-float64", "2718e28",
176 if err
:= f
.Parse(args
); err
!= nil {
180 t
.Error("f.Parse() = false after Parse")
182 if *boolFlag
!= true {
183 t
.Error("bool flag should be true, is ", *boolFlag
)
185 if *bool2Flag
!= true {
186 t
.Error("bool2 flag should be true, is ", *bool2Flag
)
189 t
.Error("int flag should be 22, is ", *intFlag
)
191 if *int64Flag
!= 0x23 {
192 t
.Error("int64 flag should be 0x23, is ", *int64Flag
)
195 t
.Error("uint flag should be 24, is ", *uintFlag
)
197 if *uint64Flag
!= 25 {
198 t
.Error("uint64 flag should be 25, is ", *uint64Flag
)
200 if *stringFlag
!= "hello" {
201 t
.Error("string flag should be `hello`, is ", *stringFlag
)
203 if *float64Flag
!= 2718e28
{
204 t
.Error("float64 flag should be 2718e28, is ", *float64Flag
)
206 if *durationFlag
!= 2*time
.Minute
{
207 t
.Error("duration flag should be 2m, is ", *durationFlag
)
209 if len(f
.Args()) != 1 {
210 t
.Error("expected one argument, got", len(f
.Args()))
211 } else if f
.Args()[0] != extra
{
212 t
.Errorf("expected argument %q got %q", extra
, f
.Args()[0])
216 func TestParse(t
*testing
.T
) {
217 ResetForTesting(func() { t
.Error("bad parse") })
218 testParse(CommandLine
, t
)
221 func TestFlagSetParse(t
*testing
.T
) {
222 testParse(NewFlagSet("test", ContinueOnError
), t
)
225 // Declare a user-defined flag type.
226 type flagVar
[]string
228 func (f
*flagVar
) String() string {
229 return fmt
.Sprint([]string(*f
))
232 func (f
*flagVar
) Set(value
string) error
{
233 *f
= append(*f
, value
)
237 func TestUserDefined(t
*testing
.T
) {
239 flags
.Init("test", ContinueOnError
)
241 flags
.Var(&v
, "v", "usage")
242 if err
:= flags
.Parse([]string{"-v", "1", "-v", "2", "-v=3"}); err
!= nil {
246 t
.Fatal("expected 3 args; got ", len(v
))
249 if v
.String() != expect
{
250 t
.Errorf("expected value %q got %q", expect
, v
.String())
254 // Declare a user-defined boolean flag type.
255 type boolFlagVar
struct {
259 func (b
*boolFlagVar
) String() string {
260 return fmt
.Sprintf("%d", b
.count
)
263 func (b
*boolFlagVar
) Set(value
string) error
{
270 func (b
*boolFlagVar
) IsBoolFlag() bool {
274 func TestUserDefinedBool(t
*testing
.T
) {
276 flags
.Init("test", ContinueOnError
)
279 flags
.Var(&b
, "b", "usage")
280 if err
= flags
.Parse([]string{"-b", "-b", "-b", "-b=true", "-b=false", "-b", "barg", "-b"}); err
!= nil {
287 t
.Errorf("want: %d; got: %d", 4, b
.count
)
291 t
.Error("expected error; got none")
295 func TestSetOutput(t
*testing
.T
) {
298 flags
.SetOutput(&buf
)
299 flags
.Init("test", ContinueOnError
)
300 flags
.Parse([]string{"-unknown"})
301 if out
:= buf
.String(); !strings
.Contains(out
, "-unknown") {
302 t
.Logf("expected output mentioning unknown; got %q", out
)
306 // This tests that one can reset the flags. This still works but not well, and is
307 // superseded by FlagSet.
308 func TestChangingArgs(t
*testing
.T
) {
309 ResetForTesting(func() { t
.Fatal("bad parse") })
311 defer func() { os
.Args
= oldArgs
}()
312 os
.Args
= []string{"cmd", "-before", "subcmd", "-after", "args"}
313 before
:= Bool("before", false, "")
314 if err
:= CommandLine
.Parse(os
.Args
[1:]); err
!= nil {
319 after
:= Bool("after", false, "")
323 if !*before || cmd
!= "subcmd" ||
!*after ||
len(args
) != 1 || args
[0] != "args" {
324 t
.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before
, cmd
, *after
, args
)
328 // Test that -help invokes the usage message and returns ErrHelp.
329 func TestHelp(t
*testing
.T
) {
330 var helpCalled
= false
331 fs
:= NewFlagSet("help test", ContinueOnError
)
332 fs
.Usage
= func() { helpCalled
= true }
334 fs
.BoolVar(&flag
, "flag", false, "regular flag")
335 // Regular flag invocation should work
336 err
:= fs
.Parse([]string{"-flag=true"})
338 t
.Fatal("expected no error; got ", err
)
341 t
.Error("flag was not set by -flag")
344 t
.Error("help called for regular flag")
345 helpCalled
= false // reset for next test
347 // Help flag should work as expected.
348 err
= fs
.Parse([]string{"-help"})
350 t
.Fatal("error expected")
353 t
.Fatal("expected ErrHelp; got ", err
)
356 t
.Fatal("help was not called")
358 // If we define a help flag, that should override.
360 fs
.BoolVar(&help
, "help", false, "help flag")
362 err
= fs
.Parse([]string{"-help"})
364 t
.Fatal("expected no error for defined -help; got ", err
)
367 t
.Fatal("help was called; should not have been for defined help flag")