1package cli 2 3import ( 4 "flag" 5 "os" 6 "testing" 7 "time" 8) 9 10func TestNewContext(t *testing.T) { 11 set := flag.NewFlagSet("test", 0) 12 set.Int("myflag", 12, "doc") 13 set.Int64("myflagInt64", int64(12), "doc") 14 set.Uint("myflagUint", uint(93), "doc") 15 set.Uint64("myflagUint64", uint64(93), "doc") 16 set.Float64("myflag64", float64(17), "doc") 17 globalSet := flag.NewFlagSet("test", 0) 18 globalSet.Int("myflag", 42, "doc") 19 globalSet.Int64("myflagInt64", int64(42), "doc") 20 globalSet.Uint("myflagUint", uint(33), "doc") 21 globalSet.Uint64("myflagUint64", uint64(33), "doc") 22 globalSet.Float64("myflag64", float64(47), "doc") 23 globalCtx := NewContext(nil, globalSet, nil) 24 command := Command{Name: "mycommand"} 25 c := NewContext(nil, set, globalCtx) 26 c.Command = command 27 expect(t, c.Int("myflag"), 12) 28 expect(t, c.Int64("myflagInt64"), int64(12)) 29 expect(t, c.Uint("myflagUint"), uint(93)) 30 expect(t, c.Uint64("myflagUint64"), uint64(93)) 31 expect(t, c.Float64("myflag64"), float64(17)) 32 expect(t, c.GlobalInt("myflag"), 42) 33 expect(t, c.GlobalInt64("myflagInt64"), int64(42)) 34 expect(t, c.GlobalUint("myflagUint"), uint(33)) 35 expect(t, c.GlobalUint64("myflagUint64"), uint64(33)) 36 expect(t, c.GlobalFloat64("myflag64"), float64(47)) 37 expect(t, c.Command.Name, "mycommand") 38} 39 40func TestContext_Int(t *testing.T) { 41 set := flag.NewFlagSet("test", 0) 42 set.Int("myflag", 12, "doc") 43 c := NewContext(nil, set, nil) 44 expect(t, c.Int("myflag"), 12) 45} 46 47func TestContext_Int64(t *testing.T) { 48 set := flag.NewFlagSet("test", 0) 49 set.Int64("myflagInt64", 12, "doc") 50 c := NewContext(nil, set, nil) 51 expect(t, c.Int64("myflagInt64"), int64(12)) 52} 53 54func TestContext_Uint(t *testing.T) { 55 set := flag.NewFlagSet("test", 0) 56 set.Uint("myflagUint", uint(13), "doc") 57 c := NewContext(nil, set, nil) 58 expect(t, c.Uint("myflagUint"), uint(13)) 59} 60 61func TestContext_Uint64(t *testing.T) { 62 set := flag.NewFlagSet("test", 0) 63 set.Uint64("myflagUint64", uint64(9), "doc") 64 c := NewContext(nil, set, nil) 65 expect(t, c.Uint64("myflagUint64"), uint64(9)) 66} 67 68func TestContext_GlobalInt(t *testing.T) { 69 set := flag.NewFlagSet("test", 0) 70 set.Int("myflag", 12, "doc") 71 c := NewContext(nil, set, nil) 72 expect(t, c.GlobalInt("myflag"), 12) 73 expect(t, c.GlobalInt("nope"), 0) 74} 75 76func TestContext_GlobalInt64(t *testing.T) { 77 set := flag.NewFlagSet("test", 0) 78 set.Int64("myflagInt64", 12, "doc") 79 c := NewContext(nil, set, nil) 80 expect(t, c.GlobalInt64("myflagInt64"), int64(12)) 81 expect(t, c.GlobalInt64("nope"), int64(0)) 82} 83 84func TestContext_Float64(t *testing.T) { 85 set := flag.NewFlagSet("test", 0) 86 set.Float64("myflag", float64(17), "doc") 87 c := NewContext(nil, set, nil) 88 expect(t, c.Float64("myflag"), float64(17)) 89} 90 91func TestContext_GlobalFloat64(t *testing.T) { 92 set := flag.NewFlagSet("test", 0) 93 set.Float64("myflag", float64(17), "doc") 94 c := NewContext(nil, set, nil) 95 expect(t, c.GlobalFloat64("myflag"), float64(17)) 96 expect(t, c.GlobalFloat64("nope"), float64(0)) 97} 98 99func TestContext_Duration(t *testing.T) { 100 set := flag.NewFlagSet("test", 0) 101 set.Duration("myflag", time.Duration(12*time.Second), "doc") 102 c := NewContext(nil, set, nil) 103 expect(t, c.Duration("myflag"), time.Duration(12*time.Second)) 104} 105 106func TestContext_String(t *testing.T) { 107 set := flag.NewFlagSet("test", 0) 108 set.String("myflag", "hello world", "doc") 109 c := NewContext(nil, set, nil) 110 expect(t, c.String("myflag"), "hello world") 111} 112 113func TestContext_Bool(t *testing.T) { 114 set := flag.NewFlagSet("test", 0) 115 set.Bool("myflag", false, "doc") 116 c := NewContext(nil, set, nil) 117 expect(t, c.Bool("myflag"), false) 118} 119 120func TestContext_BoolT(t *testing.T) { 121 set := flag.NewFlagSet("test", 0) 122 set.Bool("myflag", true, "doc") 123 c := NewContext(nil, set, nil) 124 expect(t, c.BoolT("myflag"), true) 125} 126 127func TestContext_GlobalBool(t *testing.T) { 128 set := flag.NewFlagSet("test", 0) 129 130 globalSet := flag.NewFlagSet("test-global", 0) 131 globalSet.Bool("myflag", false, "doc") 132 globalCtx := NewContext(nil, globalSet, nil) 133 134 c := NewContext(nil, set, globalCtx) 135 expect(t, c.GlobalBool("myflag"), false) 136 expect(t, c.GlobalBool("nope"), false) 137} 138 139func TestContext_GlobalBoolT(t *testing.T) { 140 set := flag.NewFlagSet("test", 0) 141 142 globalSet := flag.NewFlagSet("test-global", 0) 143 globalSet.Bool("myflag", true, "doc") 144 globalCtx := NewContext(nil, globalSet, nil) 145 146 c := NewContext(nil, set, globalCtx) 147 expect(t, c.GlobalBoolT("myflag"), true) 148 expect(t, c.GlobalBoolT("nope"), false) 149} 150 151func TestContext_Args(t *testing.T) { 152 set := flag.NewFlagSet("test", 0) 153 set.Bool("myflag", false, "doc") 154 c := NewContext(nil, set, nil) 155 set.Parse([]string{"--myflag", "bat", "baz"}) 156 expect(t, len(c.Args()), 2) 157 expect(t, c.Bool("myflag"), true) 158} 159 160func TestContext_NArg(t *testing.T) { 161 set := flag.NewFlagSet("test", 0) 162 set.Bool("myflag", false, "doc") 163 c := NewContext(nil, set, nil) 164 set.Parse([]string{"--myflag", "bat", "baz"}) 165 expect(t, c.NArg(), 2) 166} 167 168func TestContext_IsSet(t *testing.T) { 169 set := flag.NewFlagSet("test", 0) 170 set.Bool("myflag", false, "doc") 171 set.String("otherflag", "hello world", "doc") 172 globalSet := flag.NewFlagSet("test", 0) 173 globalSet.Bool("myflagGlobal", true, "doc") 174 globalCtx := NewContext(nil, globalSet, nil) 175 c := NewContext(nil, set, globalCtx) 176 set.Parse([]string{"--myflag", "bat", "baz"}) 177 globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"}) 178 expect(t, c.IsSet("myflag"), true) 179 expect(t, c.IsSet("otherflag"), false) 180 expect(t, c.IsSet("bogusflag"), false) 181 expect(t, c.IsSet("myflagGlobal"), false) 182} 183 184// XXX Corresponds to hack in context.IsSet for flags with EnvVar field 185// Should be moved to `flag_test` in v2 186func TestContext_IsSet_fromEnv(t *testing.T) { 187 var ( 188 timeoutIsSet, tIsSet bool 189 noEnvVarIsSet, nIsSet bool 190 passwordIsSet, pIsSet bool 191 unparsableIsSet, uIsSet bool 192 ) 193 194 clearenv() 195 os.Setenv("APP_TIMEOUT_SECONDS", "15.5") 196 os.Setenv("APP_PASSWORD", "") 197 a := App{ 198 Flags: []Flag{ 199 Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, 200 StringFlag{Name: "password, p", EnvVar: "APP_PASSWORD"}, 201 Float64Flag{Name: "unparsable, u", EnvVar: "APP_UNPARSABLE"}, 202 Float64Flag{Name: "no-env-var, n"}, 203 }, 204 Action: func(ctx *Context) error { 205 timeoutIsSet = ctx.IsSet("timeout") 206 tIsSet = ctx.IsSet("t") 207 passwordIsSet = ctx.IsSet("password") 208 pIsSet = ctx.IsSet("p") 209 unparsableIsSet = ctx.IsSet("unparsable") 210 uIsSet = ctx.IsSet("u") 211 noEnvVarIsSet = ctx.IsSet("no-env-var") 212 nIsSet = ctx.IsSet("n") 213 return nil 214 }, 215 } 216 a.Run([]string{"run"}) 217 expect(t, timeoutIsSet, true) 218 expect(t, tIsSet, true) 219 expect(t, passwordIsSet, true) 220 expect(t, pIsSet, true) 221 expect(t, noEnvVarIsSet, false) 222 expect(t, nIsSet, false) 223 224 os.Setenv("APP_UNPARSABLE", "foobar") 225 a.Run([]string{"run"}) 226 expect(t, unparsableIsSet, false) 227 expect(t, uIsSet, false) 228} 229 230func TestContext_GlobalIsSet(t *testing.T) { 231 set := flag.NewFlagSet("test", 0) 232 set.Bool("myflag", false, "doc") 233 set.String("otherflag", "hello world", "doc") 234 globalSet := flag.NewFlagSet("test", 0) 235 globalSet.Bool("myflagGlobal", true, "doc") 236 globalSet.Bool("myflagGlobalUnset", true, "doc") 237 globalCtx := NewContext(nil, globalSet, nil) 238 c := NewContext(nil, set, globalCtx) 239 set.Parse([]string{"--myflag", "bat", "baz"}) 240 globalSet.Parse([]string{"--myflagGlobal", "bat", "baz"}) 241 expect(t, c.GlobalIsSet("myflag"), false) 242 expect(t, c.GlobalIsSet("otherflag"), false) 243 expect(t, c.GlobalIsSet("bogusflag"), false) 244 expect(t, c.GlobalIsSet("myflagGlobal"), true) 245 expect(t, c.GlobalIsSet("myflagGlobalUnset"), false) 246 expect(t, c.GlobalIsSet("bogusGlobal"), false) 247} 248 249// XXX Corresponds to hack in context.IsSet for flags with EnvVar field 250// Should be moved to `flag_test` in v2 251func TestContext_GlobalIsSet_fromEnv(t *testing.T) { 252 var ( 253 timeoutIsSet, tIsSet bool 254 noEnvVarIsSet, nIsSet bool 255 passwordIsSet, pIsSet bool 256 unparsableIsSet, uIsSet bool 257 ) 258 259 clearenv() 260 os.Setenv("APP_TIMEOUT_SECONDS", "15.5") 261 os.Setenv("APP_PASSWORD", "") 262 a := App{ 263 Flags: []Flag{ 264 Float64Flag{Name: "timeout, t", EnvVar: "APP_TIMEOUT_SECONDS"}, 265 StringFlag{Name: "password, p", EnvVar: "APP_PASSWORD"}, 266 Float64Flag{Name: "no-env-var, n"}, 267 Float64Flag{Name: "unparsable, u", EnvVar: "APP_UNPARSABLE"}, 268 }, 269 Commands: []Command{ 270 { 271 Name: "hello", 272 Action: func(ctx *Context) error { 273 timeoutIsSet = ctx.GlobalIsSet("timeout") 274 tIsSet = ctx.GlobalIsSet("t") 275 passwordIsSet = ctx.GlobalIsSet("password") 276 pIsSet = ctx.GlobalIsSet("p") 277 unparsableIsSet = ctx.GlobalIsSet("unparsable") 278 uIsSet = ctx.GlobalIsSet("u") 279 noEnvVarIsSet = ctx.GlobalIsSet("no-env-var") 280 nIsSet = ctx.GlobalIsSet("n") 281 return nil 282 }, 283 }, 284 }, 285 } 286 if err := a.Run([]string{"run", "hello"}); err != nil { 287 t.Logf("error running Run(): %+v", err) 288 } 289 expect(t, timeoutIsSet, true) 290 expect(t, tIsSet, true) 291 expect(t, passwordIsSet, true) 292 expect(t, pIsSet, true) 293 expect(t, noEnvVarIsSet, false) 294 expect(t, nIsSet, false) 295 296 os.Setenv("APP_UNPARSABLE", "foobar") 297 if err := a.Run([]string{"run"}); err != nil { 298 t.Logf("error running Run(): %+v", err) 299 } 300 expect(t, unparsableIsSet, false) 301 expect(t, uIsSet, false) 302} 303 304func TestContext_NumFlags(t *testing.T) { 305 set := flag.NewFlagSet("test", 0) 306 set.Bool("myflag", false, "doc") 307 set.String("otherflag", "hello world", "doc") 308 globalSet := flag.NewFlagSet("test", 0) 309 globalSet.Bool("myflagGlobal", true, "doc") 310 globalCtx := NewContext(nil, globalSet, nil) 311 c := NewContext(nil, set, globalCtx) 312 set.Parse([]string{"--myflag", "--otherflag=foo"}) 313 globalSet.Parse([]string{"--myflagGlobal"}) 314 expect(t, c.NumFlags(), 2) 315} 316 317func TestContext_GlobalFlag(t *testing.T) { 318 var globalFlag string 319 var globalFlagSet bool 320 app := NewApp() 321 app.Flags = []Flag{ 322 StringFlag{Name: "global, g", Usage: "global"}, 323 } 324 app.Action = func(c *Context) error { 325 globalFlag = c.GlobalString("global") 326 globalFlagSet = c.GlobalIsSet("global") 327 return nil 328 } 329 app.Run([]string{"command", "-g", "foo"}) 330 expect(t, globalFlag, "foo") 331 expect(t, globalFlagSet, true) 332 333} 334 335func TestContext_GlobalFlagsInSubcommands(t *testing.T) { 336 subcommandRun := false 337 parentFlag := false 338 app := NewApp() 339 340 app.Flags = []Flag{ 341 BoolFlag{Name: "debug, d", Usage: "Enable debugging"}, 342 } 343 344 app.Commands = []Command{ 345 { 346 Name: "foo", 347 Flags: []Flag{ 348 BoolFlag{Name: "parent, p", Usage: "Parent flag"}, 349 }, 350 Subcommands: []Command{ 351 { 352 Name: "bar", 353 Action: func(c *Context) error { 354 if c.GlobalBool("debug") { 355 subcommandRun = true 356 } 357 if c.GlobalBool("parent") { 358 parentFlag = true 359 } 360 return nil 361 }, 362 }, 363 }, 364 }, 365 } 366 367 app.Run([]string{"command", "-d", "foo", "-p", "bar"}) 368 369 expect(t, subcommandRun, true) 370 expect(t, parentFlag, true) 371} 372 373func TestContext_Set(t *testing.T) { 374 set := flag.NewFlagSet("test", 0) 375 set.Int("int", 5, "an int") 376 c := NewContext(nil, set, nil) 377 378 expect(t, c.IsSet("int"), false) 379 c.Set("int", "1") 380 expect(t, c.Int("int"), 1) 381 expect(t, c.IsSet("int"), true) 382} 383 384func TestContext_GlobalSet(t *testing.T) { 385 gSet := flag.NewFlagSet("test", 0) 386 gSet.Int("int", 5, "an int") 387 388 set := flag.NewFlagSet("sub", 0) 389 set.Int("int", 3, "an int") 390 391 pc := NewContext(nil, gSet, nil) 392 c := NewContext(nil, set, pc) 393 394 c.Set("int", "1") 395 expect(t, c.Int("int"), 1) 396 expect(t, c.GlobalInt("int"), 5) 397 398 expect(t, c.GlobalIsSet("int"), false) 399 c.GlobalSet("int", "1") 400 expect(t, c.Int("int"), 1) 401 expect(t, c.GlobalInt("int"), 1) 402 expect(t, c.GlobalIsSet("int"), true) 403} 404