blob: abde1e0db7ee4ad416b6b35fab5830c21f24928b [file] [log] [blame]
Rob Pikebbc190b2009-02-16 19:43:15 -08001// 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.
4
Russ Cox3b864e42009-08-12 13:18:37 -07005package flag_test
Rob Pikebbc190b2009-02-16 19:43:15 -08006
7import (
Robert Griesemer1c729592009-12-15 15:27:16 -08008 . "flag"
Rob Pike6431b982010-04-06 16:46:52 -07009 "fmt"
Russ Coxed7c3f32010-12-07 13:19:01 -050010 "os"
Robert Griesemer1c729592009-12-15 15:27:16 -080011 "testing"
Rob Pikebbc190b2009-02-16 19:43:15 -080012)
13
14var (
Robert Griesemer1c729592009-12-15 15:27:16 -080015 test_bool = Bool("test_bool", false, "bool value")
16 test_int = Int("test_int", 0, "int value")
17 test_int64 = Int64("test_int64", 0, "int64 value")
18 test_uint = Uint("test_uint", 0, "uint value")
19 test_uint64 = Uint64("test_uint64", 0, "uint64 value")
20 test_string = String("test_string", "0", "string value")
21 test_float = Float("test_float", 0, "float value")
22 test_float64 = Float("test_float64", 0, "float64 value")
Rob Pikebbc190b2009-02-16 19:43:15 -080023)
24
Rob Pike575257d2009-02-16 21:55:37 -080025func boolString(s string) string {
26 if s == "0" {
Robert Griesemer40621d52009-11-09 12:07:39 -080027 return "false"
Rob Pike575257d2009-02-16 21:55:37 -080028 }
Robert Griesemer1c729592009-12-15 15:27:16 -080029 return "true"
Rob Pike575257d2009-02-16 21:55:37 -080030}
31
Rob Pikebbc190b2009-02-16 19:43:15 -080032func TestEverything(t *testing.T) {
Robert Griesemer1c729592009-12-15 15:27:16 -080033 m := make(map[string]*Flag)
34 desired := "0"
Russ Cox3b864e42009-08-12 13:18:37 -070035 visitor := func(f *Flag) {
Rob Pikebbc190b2009-02-16 19:43:15 -080036 if len(f.Name) > 5 && f.Name[0:5] == "test_" {
Robert Griesemer1c729592009-12-15 15:27:16 -080037 m[f.Name] = f
38 ok := false
Rob Pike575257d2009-02-16 21:55:37 -080039 switch {
40 case f.Value.String() == desired:
Robert Griesemer40621d52009-11-09 12:07:39 -080041 ok = true
Rob Pike575257d2009-02-16 21:55:37 -080042 case f.Name == "test_bool" && f.Value.String() == boolString(desired):
Robert Griesemer40621d52009-11-09 12:07:39 -080043 ok = true
Rob Pike575257d2009-02-16 21:55:37 -080044 }
45 if !ok {
Robert Griesemer40621d52009-11-09 12:07:39 -080046 t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
Rob Pike575257d2009-02-16 21:55:37 -080047 }
Rob Pikebbc190b2009-02-16 19:43:15 -080048 }
Robert Griesemer1c729592009-12-15 15:27:16 -080049 }
50 VisitAll(visitor)
Vish Subramanian379150c2009-11-07 15:52:27 -080051 if len(m) != 8 {
Robert Griesemer1c729592009-12-15 15:27:16 -080052 t.Error("VisitAll misses some flags")
Rob Pikebbc190b2009-02-16 19:43:15 -080053 for k, v := range m {
Robert Griesemer40621d52009-11-09 12:07:39 -080054 t.Log(k, *v)
Rob Pikebbc190b2009-02-16 19:43:15 -080055 }
56 }
Robert Griesemer1c729592009-12-15 15:27:16 -080057 m = make(map[string]*Flag)
58 Visit(visitor)
Rob Pikebbc190b2009-02-16 19:43:15 -080059 if len(m) != 0 {
Robert Griesemer1c729592009-12-15 15:27:16 -080060 t.Errorf("Visit sees unset flags")
Rob Pikebbc190b2009-02-16 19:43:15 -080061 for k, v := range m {
Robert Griesemer40621d52009-11-09 12:07:39 -080062 t.Log(k, *v)
Rob Pikebbc190b2009-02-16 19:43:15 -080063 }
64 }
Rob Pike575257d2009-02-16 21:55:37 -080065 // Now set all flags
Robert Griesemer1c729592009-12-15 15:27:16 -080066 Set("test_bool", "true")
67 Set("test_int", "1")
68 Set("test_int64", "1")
69 Set("test_uint", "1")
70 Set("test_uint64", "1")
71 Set("test_string", "1")
72 Set("test_float", "1")
73 Set("test_float64", "1")
74 desired = "1"
75 Visit(visitor)
Vish Subramanian379150c2009-11-07 15:52:27 -080076 if len(m) != 8 {
Robert Griesemer1c729592009-12-15 15:27:16 -080077 t.Error("Visit fails after set")
Rob Pikebbc190b2009-02-16 19:43:15 -080078 for k, v := range m {
Robert Griesemer40621d52009-11-09 12:07:39 -080079 t.Log(k, *v)
Rob Pikebbc190b2009-02-16 19:43:15 -080080 }
81 }
82}
Rob Pike570af812010-03-29 17:37:22 -070083
Rob Pike6431b982010-04-06 16:46:52 -070084func TestUsage(t *testing.T) {
85 called := false
86 ResetForTesting(func() { called = true })
87 if ParseForTesting([]string{"a.out", "-x"}) {
88 t.Error("parse did not fail for unknown flag")
89 }
90 if !called {
91 t.Error("did not call Usage for unknown flag")
92 }
93}
94
95func TestParse(t *testing.T) {
96 ResetForTesting(func() { t.Error("bad parse") })
97 boolFlag := Bool("bool", false, "bool value")
98 bool2Flag := Bool("bool2", false, "bool2 value")
99 intFlag := Int("int", 0, "int value")
100 int64Flag := Int64("int64", 0, "int64 value")
101 uintFlag := Uint("uint", 0, "uint value")
102 uint64Flag := Uint64("uint64", 0, "uint64 value")
103 stringFlag := String("string", "0", "string value")
104 floatFlag := Float("float", 0, "float value")
105 float64Flag := Float("float64", 0, "float64 value")
106 extra := "one-extra-argument"
107 args := []string{
108 "a.out",
109 "-bool",
110 "-bool2=true",
111 "--int", "22",
112 "--int64", "23",
113 "-uint", "24",
114 "--uint64", "25",
115 "-string", "hello",
116 "--float", "3141.5",
117 "-float64", "2718e28",
118 extra,
119 }
120 if !ParseForTesting(args) {
121 t.Fatal("parse failed")
122 }
123 if *boolFlag != true {
124 t.Error("bool flag should be true, is ", *boolFlag)
125 }
126 if *bool2Flag != true {
127 t.Error("bool2 flag should be true, is ", *bool2Flag)
128 }
129 if *intFlag != 22 {
130 t.Error("int flag should be 22, is ", *intFlag)
131 }
132 if *int64Flag != 23 {
133 t.Error("int64 flag should be 23, is ", *int64Flag)
134 }
135 if *uintFlag != 24 {
136 t.Error("uint flag should be 24, is ", *uintFlag)
137 }
138 if *uint64Flag != 25 {
139 t.Error("uint64 flag should be 25, is ", *uint64Flag)
140 }
141 if *stringFlag != "hello" {
142 t.Error("string flag should be `hello`, is ", *stringFlag)
143 }
144 if *floatFlag != 3141.5 {
145 t.Error("float flag should be 3141.5, is ", *floatFlag)
146 }
147 if *float64Flag != 2718e28 {
148 t.Error("float64 flag should be 2718e28, is ", *float64Flag)
149 }
150 if len(Args()) != 1 {
151 t.Error("expected one argument, got", len(Args()))
152 } else if Args()[0] != extra {
153 t.Errorf("expected argument %q got %q", extra, Args()[0])
154 }
155}
156
Rob Pike570af812010-03-29 17:37:22 -0700157// Declare a user-defined flag.
Rob Pike570af812010-03-29 17:37:22 -0700158type flagVar []string
159
160func (f *flagVar) String() string {
Rob Pike6431b982010-04-06 16:46:52 -0700161 return fmt.Sprint([]string(*f))
Rob Pike570af812010-03-29 17:37:22 -0700162}
163
164func (f *flagVar) Set(value string) bool {
Russ Cox69c4e932010-10-27 19:47:23 -0700165 *f = append(*f, value)
Rob Pike570af812010-03-29 17:37:22 -0700166 return true
167}
168
Rob Pike6431b982010-04-06 16:46:52 -0700169func TestUserDefined(t *testing.T) {
170 ResetForTesting(func() { t.Fatal("bad parse") })
171 var v flagVar
172 Var(&v, "v", "usage")
173 if !ParseForTesting([]string{"a.out", "-v", "1", "-v", "2", "-v=3"}) {
174 t.Error("parse failed")
175 }
176 if len(v) != 3 {
177 t.Fatal("expected 3 args; got ", len(v))
178 }
179 expect := "[1 2 3]"
180 if v.String() != expect {
181 t.Errorf("expected value %q got %q", expect, v.String())
182 }
Rob Pike570af812010-03-29 17:37:22 -0700183}
Russ Coxed7c3f32010-12-07 13:19:01 -0500184
185func TestChangingArgs(t *testing.T) {
186 ResetForTesting(func() { t.Fatal("bad parse") })
187 oldArgs := os.Args
188 defer func() { os.Args = oldArgs }()
189 os.Args = []string{"cmd", "-before", "subcmd", "-after", "args"}
190 before := Bool("before", false, "")
191 Parse()
192 cmd := Arg(0)
193 os.Args = Args()
194 after := Bool("after", false, "")
195 Parse()
196 args := Args()
197
198 if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
199 t.Fatal("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
200 }
201}