You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

400 lines
11 KiB

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