flag_test.go 36 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259
  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.
  4. package pflag
  5. import (
  6. "bytes"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "net"
  11. "os"
  12. "reflect"
  13. "sort"
  14. "strconv"
  15. "strings"
  16. "testing"
  17. "time"
  18. )
  19. var (
  20. testBool = Bool("test_bool", false, "bool value")
  21. testInt = Int("test_int", 0, "int value")
  22. testInt64 = Int64("test_int64", 0, "int64 value")
  23. testUint = Uint("test_uint", 0, "uint value")
  24. testUint64 = Uint64("test_uint64", 0, "uint64 value")
  25. testString = String("test_string", "0", "string value")
  26. testFloat = Float64("test_float64", 0, "float64 value")
  27. testDuration = Duration("test_duration", 0, "time.Duration value")
  28. testOptionalInt = Int("test_optional_int", 0, "optional int value")
  29. normalizeFlagNameInvocations = 0
  30. )
  31. func boolString(s string) string {
  32. if s == "0" {
  33. return "false"
  34. }
  35. return "true"
  36. }
  37. func TestEverything(t *testing.T) {
  38. m := make(map[string]*Flag)
  39. desired := "0"
  40. visitor := func(f *Flag) {
  41. if len(f.Name) > 5 && f.Name[0:5] == "test_" {
  42. m[f.Name] = f
  43. ok := false
  44. switch {
  45. case f.Value.String() == desired:
  46. ok = true
  47. case f.Name == "test_bool" && f.Value.String() == boolString(desired):
  48. ok = true
  49. case f.Name == "test_duration" && f.Value.String() == desired+"s":
  50. ok = true
  51. }
  52. if !ok {
  53. t.Error("Visit: bad value", f.Value.String(), "for", f.Name)
  54. }
  55. }
  56. }
  57. VisitAll(visitor)
  58. if len(m) != 9 {
  59. t.Error("VisitAll misses some flags")
  60. for k, v := range m {
  61. t.Log(k, *v)
  62. }
  63. }
  64. m = make(map[string]*Flag)
  65. Visit(visitor)
  66. if len(m) != 0 {
  67. t.Errorf("Visit sees unset flags")
  68. for k, v := range m {
  69. t.Log(k, *v)
  70. }
  71. }
  72. // Now set all flags
  73. Set("test_bool", "true")
  74. Set("test_int", "1")
  75. Set("test_int64", "1")
  76. Set("test_uint", "1")
  77. Set("test_uint64", "1")
  78. Set("test_string", "1")
  79. Set("test_float64", "1")
  80. Set("test_duration", "1s")
  81. Set("test_optional_int", "1")
  82. desired = "1"
  83. Visit(visitor)
  84. if len(m) != 9 {
  85. t.Error("Visit fails after set")
  86. for k, v := range m {
  87. t.Log(k, *v)
  88. }
  89. }
  90. // Now test they're visited in sort order.
  91. var flagNames []string
  92. Visit(func(f *Flag) { flagNames = append(flagNames, f.Name) })
  93. if !sort.StringsAreSorted(flagNames) {
  94. t.Errorf("flag names not sorted: %v", flagNames)
  95. }
  96. }
  97. func TestUsage(t *testing.T) {
  98. called := false
  99. ResetForTesting(func() { called = true })
  100. if GetCommandLine().Parse([]string{"--x"}) == nil {
  101. t.Error("parse did not fail for unknown flag")
  102. }
  103. if called {
  104. t.Error("did call Usage while using ContinueOnError")
  105. }
  106. }
  107. func TestAddFlagSet(t *testing.T) {
  108. oldSet := NewFlagSet("old", ContinueOnError)
  109. newSet := NewFlagSet("new", ContinueOnError)
  110. oldSet.String("flag1", "flag1", "flag1")
  111. oldSet.String("flag2", "flag2", "flag2")
  112. newSet.String("flag2", "flag2", "flag2")
  113. newSet.String("flag3", "flag3", "flag3")
  114. oldSet.AddFlagSet(newSet)
  115. if len(oldSet.formal) != 3 {
  116. t.Errorf("Unexpected result adding a FlagSet to a FlagSet %v", oldSet)
  117. }
  118. }
  119. func TestAnnotation(t *testing.T) {
  120. f := NewFlagSet("shorthand", ContinueOnError)
  121. if err := f.SetAnnotation("missing-flag", "key", nil); err == nil {
  122. t.Errorf("Expected error setting annotation on non-existent flag")
  123. }
  124. f.StringP("stringa", "a", "", "string value")
  125. if err := f.SetAnnotation("stringa", "key", nil); err != nil {
  126. t.Errorf("Unexpected error setting new nil annotation: %v", err)
  127. }
  128. if annotation := f.Lookup("stringa").Annotations["key"]; annotation != nil {
  129. t.Errorf("Unexpected annotation: %v", annotation)
  130. }
  131. f.StringP("stringb", "b", "", "string2 value")
  132. if err := f.SetAnnotation("stringb", "key", []string{"value1"}); err != nil {
  133. t.Errorf("Unexpected error setting new annotation: %v", err)
  134. }
  135. if annotation := f.Lookup("stringb").Annotations["key"]; !reflect.DeepEqual(annotation, []string{"value1"}) {
  136. t.Errorf("Unexpected annotation: %v", annotation)
  137. }
  138. if err := f.SetAnnotation("stringb", "key", []string{"value2"}); err != nil {
  139. t.Errorf("Unexpected error updating annotation: %v", err)
  140. }
  141. if annotation := f.Lookup("stringb").Annotations["key"]; !reflect.DeepEqual(annotation, []string{"value2"}) {
  142. t.Errorf("Unexpected annotation: %v", annotation)
  143. }
  144. }
  145. func testParse(f *FlagSet, t *testing.T) {
  146. if f.Parsed() {
  147. t.Error("f.Parse() = true before Parse")
  148. }
  149. boolFlag := f.Bool("bool", false, "bool value")
  150. bool2Flag := f.Bool("bool2", false, "bool2 value")
  151. bool3Flag := f.Bool("bool3", false, "bool3 value")
  152. intFlag := f.Int("int", 0, "int value")
  153. int8Flag := f.Int8("int8", 0, "int value")
  154. int16Flag := f.Int16("int16", 0, "int value")
  155. int32Flag := f.Int32("int32", 0, "int value")
  156. int64Flag := f.Int64("int64", 0, "int64 value")
  157. uintFlag := f.Uint("uint", 0, "uint value")
  158. uint8Flag := f.Uint8("uint8", 0, "uint value")
  159. uint16Flag := f.Uint16("uint16", 0, "uint value")
  160. uint32Flag := f.Uint32("uint32", 0, "uint value")
  161. uint64Flag := f.Uint64("uint64", 0, "uint64 value")
  162. stringFlag := f.String("string", "0", "string value")
  163. float32Flag := f.Float32("float32", 0, "float32 value")
  164. float64Flag := f.Float64("float64", 0, "float64 value")
  165. ipFlag := f.IP("ip", net.ParseIP("127.0.0.1"), "ip value")
  166. maskFlag := f.IPMask("mask", ParseIPv4Mask("0.0.0.0"), "mask value")
  167. durationFlag := f.Duration("duration", 5*time.Second, "time.Duration value")
  168. optionalIntNoValueFlag := f.Int("optional-int-no-value", 0, "int value")
  169. f.Lookup("optional-int-no-value").NoOptDefVal = "9"
  170. optionalIntWithValueFlag := f.Int("optional-int-with-value", 0, "int value")
  171. f.Lookup("optional-int-no-value").NoOptDefVal = "9"
  172. extra := "one-extra-argument"
  173. args := []string{
  174. "--bool",
  175. "--bool2=true",
  176. "--bool3=false",
  177. "--int=22",
  178. "--int8=-8",
  179. "--int16=-16",
  180. "--int32=-32",
  181. "--int64=0x23",
  182. "--uint", "24",
  183. "--uint8=8",
  184. "--uint16=16",
  185. "--uint32=32",
  186. "--uint64=25",
  187. "--string=hello",
  188. "--float32=-172e12",
  189. "--float64=2718e28",
  190. "--ip=10.11.12.13",
  191. "--mask=255.255.255.0",
  192. "--duration=2m",
  193. "--optional-int-no-value",
  194. "--optional-int-with-value=42",
  195. extra,
  196. }
  197. if err := f.Parse(args); err != nil {
  198. t.Fatal(err)
  199. }
  200. if !f.Parsed() {
  201. t.Error("f.Parse() = false after Parse")
  202. }
  203. if *boolFlag != true {
  204. t.Error("bool flag should be true, is ", *boolFlag)
  205. }
  206. if v, err := f.GetBool("bool"); err != nil || v != *boolFlag {
  207. t.Error("GetBool does not work.")
  208. }
  209. if *bool2Flag != true {
  210. t.Error("bool2 flag should be true, is ", *bool2Flag)
  211. }
  212. if *bool3Flag != false {
  213. t.Error("bool3 flag should be false, is ", *bool2Flag)
  214. }
  215. if *intFlag != 22 {
  216. t.Error("int flag should be 22, is ", *intFlag)
  217. }
  218. if v, err := f.GetInt("int"); err != nil || v != *intFlag {
  219. t.Error("GetInt does not work.")
  220. }
  221. if *int8Flag != -8 {
  222. t.Error("int8 flag should be 0x23, is ", *int8Flag)
  223. }
  224. if *int16Flag != -16 {
  225. t.Error("int16 flag should be -16, is ", *int16Flag)
  226. }
  227. if v, err := f.GetInt8("int8"); err != nil || v != *int8Flag {
  228. t.Error("GetInt8 does not work.")
  229. }
  230. if v, err := f.GetInt16("int16"); err != nil || v != *int16Flag {
  231. t.Error("GetInt16 does not work.")
  232. }
  233. if *int32Flag != -32 {
  234. t.Error("int32 flag should be 0x23, is ", *int32Flag)
  235. }
  236. if v, err := f.GetInt32("int32"); err != nil || v != *int32Flag {
  237. t.Error("GetInt32 does not work.")
  238. }
  239. if *int64Flag != 0x23 {
  240. t.Error("int64 flag should be 0x23, is ", *int64Flag)
  241. }
  242. if v, err := f.GetInt64("int64"); err != nil || v != *int64Flag {
  243. t.Error("GetInt64 does not work.")
  244. }
  245. if *uintFlag != 24 {
  246. t.Error("uint flag should be 24, is ", *uintFlag)
  247. }
  248. if v, err := f.GetUint("uint"); err != nil || v != *uintFlag {
  249. t.Error("GetUint does not work.")
  250. }
  251. if *uint8Flag != 8 {
  252. t.Error("uint8 flag should be 8, is ", *uint8Flag)
  253. }
  254. if v, err := f.GetUint8("uint8"); err != nil || v != *uint8Flag {
  255. t.Error("GetUint8 does not work.")
  256. }
  257. if *uint16Flag != 16 {
  258. t.Error("uint16 flag should be 16, is ", *uint16Flag)
  259. }
  260. if v, err := f.GetUint16("uint16"); err != nil || v != *uint16Flag {
  261. t.Error("GetUint16 does not work.")
  262. }
  263. if *uint32Flag != 32 {
  264. t.Error("uint32 flag should be 32, is ", *uint32Flag)
  265. }
  266. if v, err := f.GetUint32("uint32"); err != nil || v != *uint32Flag {
  267. t.Error("GetUint32 does not work.")
  268. }
  269. if *uint64Flag != 25 {
  270. t.Error("uint64 flag should be 25, is ", *uint64Flag)
  271. }
  272. if v, err := f.GetUint64("uint64"); err != nil || v != *uint64Flag {
  273. t.Error("GetUint64 does not work.")
  274. }
  275. if *stringFlag != "hello" {
  276. t.Error("string flag should be `hello`, is ", *stringFlag)
  277. }
  278. if v, err := f.GetString("string"); err != nil || v != *stringFlag {
  279. t.Error("GetString does not work.")
  280. }
  281. if *float32Flag != -172e12 {
  282. t.Error("float32 flag should be -172e12, is ", *float32Flag)
  283. }
  284. if v, err := f.GetFloat32("float32"); err != nil || v != *float32Flag {
  285. t.Errorf("GetFloat32 returned %v but float32Flag was %v", v, *float32Flag)
  286. }
  287. if *float64Flag != 2718e28 {
  288. t.Error("float64 flag should be 2718e28, is ", *float64Flag)
  289. }
  290. if v, err := f.GetFloat64("float64"); err != nil || v != *float64Flag {
  291. t.Errorf("GetFloat64 returned %v but float64Flag was %v", v, *float64Flag)
  292. }
  293. if !(*ipFlag).Equal(net.ParseIP("10.11.12.13")) {
  294. t.Error("ip flag should be 10.11.12.13, is ", *ipFlag)
  295. }
  296. if v, err := f.GetIP("ip"); err != nil || !v.Equal(*ipFlag) {
  297. t.Errorf("GetIP returned %v but ipFlag was %v", v, *ipFlag)
  298. }
  299. if (*maskFlag).String() != ParseIPv4Mask("255.255.255.0").String() {
  300. t.Error("mask flag should be 255.255.255.0, is ", (*maskFlag).String())
  301. }
  302. if v, err := f.GetIPv4Mask("mask"); err != nil || v.String() != (*maskFlag).String() {
  303. t.Errorf("GetIP returned %v maskFlag was %v error was %v", v, *maskFlag, err)
  304. }
  305. if *durationFlag != 2*time.Minute {
  306. t.Error("duration flag should be 2m, is ", *durationFlag)
  307. }
  308. if v, err := f.GetDuration("duration"); err != nil || v != *durationFlag {
  309. t.Error("GetDuration does not work.")
  310. }
  311. if _, err := f.GetInt("duration"); err == nil {
  312. t.Error("GetInt parsed a time.Duration?!?!")
  313. }
  314. if *optionalIntNoValueFlag != 9 {
  315. t.Error("optional int flag should be the default value, is ", *optionalIntNoValueFlag)
  316. }
  317. if *optionalIntWithValueFlag != 42 {
  318. t.Error("optional int flag should be 42, is ", *optionalIntWithValueFlag)
  319. }
  320. if len(f.Args()) != 1 {
  321. t.Error("expected one argument, got", len(f.Args()))
  322. } else if f.Args()[0] != extra {
  323. t.Errorf("expected argument %q got %q", extra, f.Args()[0])
  324. }
  325. }
  326. func testParseAll(f *FlagSet, t *testing.T) {
  327. if f.Parsed() {
  328. t.Error("f.Parse() = true before Parse")
  329. }
  330. f.BoolP("boola", "a", false, "bool value")
  331. f.BoolP("boolb", "b", false, "bool2 value")
  332. f.BoolP("boolc", "c", false, "bool3 value")
  333. f.BoolP("boold", "d", false, "bool4 value")
  334. f.StringP("stringa", "s", "0", "string value")
  335. f.StringP("stringz", "z", "0", "string value")
  336. f.StringP("stringx", "x", "0", "string value")
  337. f.StringP("stringy", "y", "0", "string value")
  338. f.Lookup("stringx").NoOptDefVal = "1"
  339. args := []string{
  340. "-ab",
  341. "-cs=xx",
  342. "--stringz=something",
  343. "-d=true",
  344. "-x",
  345. "-y",
  346. "ee",
  347. }
  348. want := []string{
  349. "boola", "true",
  350. "boolb", "true",
  351. "boolc", "true",
  352. "stringa", "xx",
  353. "stringz", "something",
  354. "boold", "true",
  355. "stringx", "1",
  356. "stringy", "ee",
  357. }
  358. got := []string{}
  359. store := func(flag *Flag, value string) error {
  360. got = append(got, flag.Name)
  361. if len(value) > 0 {
  362. got = append(got, value)
  363. }
  364. return nil
  365. }
  366. if err := f.ParseAll(args, store); err != nil {
  367. t.Errorf("expected no error, got %s", err)
  368. }
  369. if !f.Parsed() {
  370. t.Errorf("f.Parse() = false after Parse")
  371. }
  372. if !reflect.DeepEqual(got, want) {
  373. t.Errorf("f.ParseAll() fail to restore the args")
  374. t.Errorf("Got: %v", got)
  375. t.Errorf("Want: %v", want)
  376. }
  377. }
  378. func testParseWithUnknownFlags(f *FlagSet, t *testing.T) {
  379. if f.Parsed() {
  380. t.Error("f.Parse() = true before Parse")
  381. }
  382. f.ParseErrorsWhitelist.UnknownFlags = true
  383. f.BoolP("boola", "a", false, "bool value")
  384. f.BoolP("boolb", "b", false, "bool2 value")
  385. f.BoolP("boolc", "c", false, "bool3 value")
  386. f.BoolP("boold", "d", false, "bool4 value")
  387. f.BoolP("boole", "e", false, "bool4 value")
  388. f.StringP("stringa", "s", "0", "string value")
  389. f.StringP("stringz", "z", "0", "string value")
  390. f.StringP("stringx", "x", "0", "string value")
  391. f.StringP("stringy", "y", "0", "string value")
  392. f.StringP("stringo", "o", "0", "string value")
  393. f.Lookup("stringx").NoOptDefVal = "1"
  394. args := []string{
  395. "-ab",
  396. "-cs=xx",
  397. "--stringz=something",
  398. "--unknown1",
  399. "unknown1Value",
  400. "-d=true",
  401. "-x",
  402. "--unknown2=unknown2Value",
  403. "-u=unknown3Value",
  404. "-p",
  405. "unknown4Value",
  406. "-q", //another unknown with bool value
  407. "-y",
  408. "ee",
  409. "--unknown7=unknown7value",
  410. "--stringo=ovalue",
  411. "--unknown8=unknown8value",
  412. "--boole",
  413. "--unknown6",
  414. }
  415. want := []string{
  416. "boola", "true",
  417. "boolb", "true",
  418. "boolc", "true",
  419. "stringa", "xx",
  420. "stringz", "something",
  421. "boold", "true",
  422. "stringx", "1",
  423. "stringy", "ee",
  424. "stringo", "ovalue",
  425. "boole", "true",
  426. }
  427. got := []string{}
  428. store := func(flag *Flag, value string) error {
  429. got = append(got, flag.Name)
  430. if len(value) > 0 {
  431. got = append(got, value)
  432. }
  433. return nil
  434. }
  435. if err := f.ParseAll(args, store); err != nil {
  436. t.Errorf("expected no error, got %s", err)
  437. }
  438. if !f.Parsed() {
  439. t.Errorf("f.Parse() = false after Parse")
  440. }
  441. if !reflect.DeepEqual(got, want) {
  442. t.Errorf("f.ParseAll() fail to restore the args")
  443. t.Errorf("Got: %v", got)
  444. t.Errorf("Want: %v", want)
  445. }
  446. }
  447. func TestShorthand(t *testing.T) {
  448. f := NewFlagSet("shorthand", ContinueOnError)
  449. if f.Parsed() {
  450. t.Error("f.Parse() = true before Parse")
  451. }
  452. boolaFlag := f.BoolP("boola", "a", false, "bool value")
  453. boolbFlag := f.BoolP("boolb", "b", false, "bool2 value")
  454. boolcFlag := f.BoolP("boolc", "c", false, "bool3 value")
  455. booldFlag := f.BoolP("boold", "d", false, "bool4 value")
  456. stringaFlag := f.StringP("stringa", "s", "0", "string value")
  457. stringzFlag := f.StringP("stringz", "z", "0", "string value")
  458. extra := "interspersed-argument"
  459. notaflag := "--i-look-like-a-flag"
  460. args := []string{
  461. "-ab",
  462. extra,
  463. "-cs",
  464. "hello",
  465. "-z=something",
  466. "-d=true",
  467. "--",
  468. notaflag,
  469. }
  470. f.SetOutput(ioutil.Discard)
  471. if err := f.Parse(args); err != nil {
  472. t.Error("expected no error, got ", err)
  473. }
  474. if !f.Parsed() {
  475. t.Error("f.Parse() = false after Parse")
  476. }
  477. if *boolaFlag != true {
  478. t.Error("boola flag should be true, is ", *boolaFlag)
  479. }
  480. if *boolbFlag != true {
  481. t.Error("boolb flag should be true, is ", *boolbFlag)
  482. }
  483. if *boolcFlag != true {
  484. t.Error("boolc flag should be true, is ", *boolcFlag)
  485. }
  486. if *booldFlag != true {
  487. t.Error("boold flag should be true, is ", *booldFlag)
  488. }
  489. if *stringaFlag != "hello" {
  490. t.Error("stringa flag should be `hello`, is ", *stringaFlag)
  491. }
  492. if *stringzFlag != "something" {
  493. t.Error("stringz flag should be `something`, is ", *stringzFlag)
  494. }
  495. if len(f.Args()) != 2 {
  496. t.Error("expected one argument, got", len(f.Args()))
  497. } else if f.Args()[0] != extra {
  498. t.Errorf("expected argument %q got %q", extra, f.Args()[0])
  499. } else if f.Args()[1] != notaflag {
  500. t.Errorf("expected argument %q got %q", notaflag, f.Args()[1])
  501. }
  502. if f.ArgsLenAtDash() != 1 {
  503. t.Errorf("expected argsLenAtDash %d got %d", f.ArgsLenAtDash(), 1)
  504. }
  505. }
  506. func TestShorthandLookup(t *testing.T) {
  507. f := NewFlagSet("shorthand", ContinueOnError)
  508. if f.Parsed() {
  509. t.Error("f.Parse() = true before Parse")
  510. }
  511. f.BoolP("boola", "a", false, "bool value")
  512. f.BoolP("boolb", "b", false, "bool2 value")
  513. args := []string{
  514. "-ab",
  515. }
  516. f.SetOutput(ioutil.Discard)
  517. if err := f.Parse(args); err != nil {
  518. t.Error("expected no error, got ", err)
  519. }
  520. if !f.Parsed() {
  521. t.Error("f.Parse() = false after Parse")
  522. }
  523. flag := f.ShorthandLookup("a")
  524. if flag == nil {
  525. t.Errorf("f.ShorthandLookup(\"a\") returned nil")
  526. }
  527. if flag.Name != "boola" {
  528. t.Errorf("f.ShorthandLookup(\"a\") found %q instead of \"boola\"", flag.Name)
  529. }
  530. flag = f.ShorthandLookup("")
  531. if flag != nil {
  532. t.Errorf("f.ShorthandLookup(\"\") did not return nil")
  533. }
  534. defer func() {
  535. recover()
  536. }()
  537. flag = f.ShorthandLookup("ab")
  538. // should NEVER get here. lookup should panic. defer'd func should recover it.
  539. t.Errorf("f.ShorthandLookup(\"ab\") did not panic")
  540. }
  541. func TestParse(t *testing.T) {
  542. ResetForTesting(func() { t.Error("bad parse") })
  543. testParse(GetCommandLine(), t)
  544. }
  545. func TestParseAll(t *testing.T) {
  546. ResetForTesting(func() { t.Error("bad parse") })
  547. testParseAll(GetCommandLine(), t)
  548. }
  549. func TestIgnoreUnknownFlags(t *testing.T) {
  550. ResetForTesting(func() { t.Error("bad parse") })
  551. testParseWithUnknownFlags(GetCommandLine(), t)
  552. }
  553. func TestFlagSetParse(t *testing.T) {
  554. testParse(NewFlagSet("test", ContinueOnError), t)
  555. }
  556. func TestChangedHelper(t *testing.T) {
  557. f := NewFlagSet("changedtest", ContinueOnError)
  558. f.Bool("changed", false, "changed bool")
  559. f.Bool("settrue", true, "true to true")
  560. f.Bool("setfalse", false, "false to false")
  561. f.Bool("unchanged", false, "unchanged bool")
  562. args := []string{"--changed", "--settrue", "--setfalse=false"}
  563. if err := f.Parse(args); err != nil {
  564. t.Error("f.Parse() = false after Parse")
  565. }
  566. if !f.Changed("changed") {
  567. t.Errorf("--changed wasn't changed!")
  568. }
  569. if !f.Changed("settrue") {
  570. t.Errorf("--settrue wasn't changed!")
  571. }
  572. if !f.Changed("setfalse") {
  573. t.Errorf("--setfalse wasn't changed!")
  574. }
  575. if f.Changed("unchanged") {
  576. t.Errorf("--unchanged was changed!")
  577. }
  578. if f.Changed("invalid") {
  579. t.Errorf("--invalid was changed!")
  580. }
  581. if f.ArgsLenAtDash() != -1 {
  582. t.Errorf("Expected argsLenAtDash: %d but got %d", -1, f.ArgsLenAtDash())
  583. }
  584. }
  585. func replaceSeparators(name string, from []string, to string) string {
  586. result := name
  587. for _, sep := range from {
  588. result = strings.Replace(result, sep, to, -1)
  589. }
  590. // Type convert to indicate normalization has been done.
  591. return result
  592. }
  593. func wordSepNormalizeFunc(f *FlagSet, name string) NormalizedName {
  594. seps := []string{"-", "_"}
  595. name = replaceSeparators(name, seps, ".")
  596. normalizeFlagNameInvocations++
  597. return NormalizedName(name)
  598. }
  599. func testWordSepNormalizedNames(args []string, t *testing.T) {
  600. f := NewFlagSet("normalized", ContinueOnError)
  601. if f.Parsed() {
  602. t.Error("f.Parse() = true before Parse")
  603. }
  604. withDashFlag := f.Bool("with-dash-flag", false, "bool value")
  605. // Set this after some flags have been added and before others.
  606. f.SetNormalizeFunc(wordSepNormalizeFunc)
  607. withUnderFlag := f.Bool("with_under_flag", false, "bool value")
  608. withBothFlag := f.Bool("with-both_flag", false, "bool value")
  609. if err := f.Parse(args); err != nil {
  610. t.Fatal(err)
  611. }
  612. if !f.Parsed() {
  613. t.Error("f.Parse() = false after Parse")
  614. }
  615. if *withDashFlag != true {
  616. t.Error("withDashFlag flag should be true, is ", *withDashFlag)
  617. }
  618. if *withUnderFlag != true {
  619. t.Error("withUnderFlag flag should be true, is ", *withUnderFlag)
  620. }
  621. if *withBothFlag != true {
  622. t.Error("withBothFlag flag should be true, is ", *withBothFlag)
  623. }
  624. }
  625. func TestWordSepNormalizedNames(t *testing.T) {
  626. args := []string{
  627. "--with-dash-flag",
  628. "--with-under-flag",
  629. "--with-both-flag",
  630. }
  631. testWordSepNormalizedNames(args, t)
  632. args = []string{
  633. "--with_dash_flag",
  634. "--with_under_flag",
  635. "--with_both_flag",
  636. }
  637. testWordSepNormalizedNames(args, t)
  638. args = []string{
  639. "--with-dash_flag",
  640. "--with-under_flag",
  641. "--with-both_flag",
  642. }
  643. testWordSepNormalizedNames(args, t)
  644. }
  645. func aliasAndWordSepFlagNames(f *FlagSet, name string) NormalizedName {
  646. seps := []string{"-", "_"}
  647. oldName := replaceSeparators("old-valid_flag", seps, ".")
  648. newName := replaceSeparators("valid-flag", seps, ".")
  649. name = replaceSeparators(name, seps, ".")
  650. switch name {
  651. case oldName:
  652. name = newName
  653. }
  654. return NormalizedName(name)
  655. }
  656. func TestCustomNormalizedNames(t *testing.T) {
  657. f := NewFlagSet("normalized", ContinueOnError)
  658. if f.Parsed() {
  659. t.Error("f.Parse() = true before Parse")
  660. }
  661. validFlag := f.Bool("valid-flag", false, "bool value")
  662. f.SetNormalizeFunc(aliasAndWordSepFlagNames)
  663. someOtherFlag := f.Bool("some-other-flag", false, "bool value")
  664. args := []string{"--old_valid_flag", "--some-other_flag"}
  665. if err := f.Parse(args); err != nil {
  666. t.Fatal(err)
  667. }
  668. if *validFlag != true {
  669. t.Errorf("validFlag is %v even though we set the alias --old_valid_falg", *validFlag)
  670. }
  671. if *someOtherFlag != true {
  672. t.Error("someOtherFlag should be true, is ", *someOtherFlag)
  673. }
  674. }
  675. // Every flag we add, the name (displayed also in usage) should normalized
  676. func TestNormalizationFuncShouldChangeFlagName(t *testing.T) {
  677. // Test normalization after addition
  678. f := NewFlagSet("normalized", ContinueOnError)
  679. f.Bool("valid_flag", false, "bool value")
  680. if f.Lookup("valid_flag").Name != "valid_flag" {
  681. t.Error("The new flag should have the name 'valid_flag' instead of ", f.Lookup("valid_flag").Name)
  682. }
  683. f.SetNormalizeFunc(wordSepNormalizeFunc)
  684. if f.Lookup("valid_flag").Name != "valid.flag" {
  685. t.Error("The new flag should have the name 'valid.flag' instead of ", f.Lookup("valid_flag").Name)
  686. }
  687. // Test normalization before addition
  688. f = NewFlagSet("normalized", ContinueOnError)
  689. f.SetNormalizeFunc(wordSepNormalizeFunc)
  690. f.Bool("valid_flag", false, "bool value")
  691. if f.Lookup("valid_flag").Name != "valid.flag" {
  692. t.Error("The new flag should have the name 'valid.flag' instead of ", f.Lookup("valid_flag").Name)
  693. }
  694. }
  695. // Related to https://github.com/spf13/cobra/issues/521.
  696. func TestNormalizationSharedFlags(t *testing.T) {
  697. f := NewFlagSet("set f", ContinueOnError)
  698. g := NewFlagSet("set g", ContinueOnError)
  699. nfunc := wordSepNormalizeFunc
  700. testName := "valid_flag"
  701. normName := nfunc(nil, testName)
  702. if testName == string(normName) {
  703. t.Error("TestNormalizationSharedFlags meaningless: the original and normalized flag names are identical:", testName)
  704. }
  705. f.Bool(testName, false, "bool value")
  706. g.AddFlagSet(f)
  707. f.SetNormalizeFunc(nfunc)
  708. g.SetNormalizeFunc(nfunc)
  709. if len(f.formal) != 1 {
  710. t.Error("Normalizing flags should not result in duplications in the flag set:", f.formal)
  711. }
  712. if f.orderedFormal[0].Name != string(normName) {
  713. t.Error("Flag name not normalized")
  714. }
  715. for k := range f.formal {
  716. if k != "valid.flag" {
  717. t.Errorf("The key in the flag map should have been normalized: wanted \"%s\", got \"%s\" instead", normName, k)
  718. }
  719. }
  720. if !reflect.DeepEqual(f.formal, g.formal) || !reflect.DeepEqual(f.orderedFormal, g.orderedFormal) {
  721. t.Error("Two flag sets sharing the same flags should stay consistent after being normalized. Original set:", f.formal, "Duplicate set:", g.formal)
  722. }
  723. }
  724. func TestNormalizationSetFlags(t *testing.T) {
  725. f := NewFlagSet("normalized", ContinueOnError)
  726. nfunc := wordSepNormalizeFunc
  727. testName := "valid_flag"
  728. normName := nfunc(nil, testName)
  729. if testName == string(normName) {
  730. t.Error("TestNormalizationSetFlags meaningless: the original and normalized flag names are identical:", testName)
  731. }
  732. f.Bool(testName, false, "bool value")
  733. f.Set(testName, "true")
  734. f.SetNormalizeFunc(nfunc)
  735. if len(f.formal) != 1 {
  736. t.Error("Normalizing flags should not result in duplications in the flag set:", f.formal)
  737. }
  738. if f.orderedFormal[0].Name != string(normName) {
  739. t.Error("Flag name not normalized")
  740. }
  741. for k := range f.formal {
  742. if k != "valid.flag" {
  743. t.Errorf("The key in the flag map should have been normalized: wanted \"%s\", got \"%s\" instead", normName, k)
  744. }
  745. }
  746. if !reflect.DeepEqual(f.formal, f.actual) {
  747. t.Error("The map of set flags should get normalized. Formal:", f.formal, "Actual:", f.actual)
  748. }
  749. }
  750. // Declare a user-defined flag type.
  751. type flagVar []string
  752. func (f *flagVar) String() string {
  753. return fmt.Sprint([]string(*f))
  754. }
  755. func (f *flagVar) Set(value string) error {
  756. *f = append(*f, value)
  757. return nil
  758. }
  759. func (f *flagVar) Type() string {
  760. return "flagVar"
  761. }
  762. func TestUserDefined(t *testing.T) {
  763. var flags FlagSet
  764. flags.Init("test", ContinueOnError)
  765. var v flagVar
  766. flags.VarP(&v, "v", "v", "usage")
  767. if err := flags.Parse([]string{"--v=1", "-v2", "-v", "3"}); err != nil {
  768. t.Error(err)
  769. }
  770. if len(v) != 3 {
  771. t.Fatal("expected 3 args; got ", len(v))
  772. }
  773. expect := "[1 2 3]"
  774. if v.String() != expect {
  775. t.Errorf("expected value %q got %q", expect, v.String())
  776. }
  777. }
  778. func TestSetOutput(t *testing.T) {
  779. var flags FlagSet
  780. var buf bytes.Buffer
  781. flags.SetOutput(&buf)
  782. flags.Init("test", ContinueOnError)
  783. flags.Parse([]string{"--unknown"})
  784. if out := buf.String(); !strings.Contains(out, "--unknown") {
  785. t.Logf("expected output mentioning unknown; got %q", out)
  786. }
  787. }
  788. // This tests that one can reset the flags. This still works but not well, and is
  789. // superseded by FlagSet.
  790. func TestChangingArgs(t *testing.T) {
  791. ResetForTesting(func() { t.Fatal("bad parse") })
  792. oldArgs := os.Args
  793. defer func() { os.Args = oldArgs }()
  794. os.Args = []string{"cmd", "--before", "subcmd"}
  795. before := Bool("before", false, "")
  796. if err := GetCommandLine().Parse(os.Args[1:]); err != nil {
  797. t.Fatal(err)
  798. }
  799. cmd := Arg(0)
  800. os.Args = []string{"subcmd", "--after", "args"}
  801. after := Bool("after", false, "")
  802. Parse()
  803. args := Args()
  804. if !*before || cmd != "subcmd" || !*after || len(args) != 1 || args[0] != "args" {
  805. t.Fatalf("expected true subcmd true [args] got %v %v %v %v", *before, cmd, *after, args)
  806. }
  807. }
  808. // Test that -help invokes the usage message and returns ErrHelp.
  809. func TestHelp(t *testing.T) {
  810. var helpCalled = false
  811. fs := NewFlagSet("help test", ContinueOnError)
  812. fs.Usage = func() { helpCalled = true }
  813. var flag bool
  814. fs.BoolVar(&flag, "flag", false, "regular flag")
  815. // Regular flag invocation should work
  816. err := fs.Parse([]string{"--flag=true"})
  817. if err != nil {
  818. t.Fatal("expected no error; got ", err)
  819. }
  820. if !flag {
  821. t.Error("flag was not set by --flag")
  822. }
  823. if helpCalled {
  824. t.Error("help called for regular flag")
  825. helpCalled = false // reset for next test
  826. }
  827. // Help flag should work as expected.
  828. err = fs.Parse([]string{"--help"})
  829. if err == nil {
  830. t.Fatal("error expected")
  831. }
  832. if err != ErrHelp {
  833. t.Fatal("expected ErrHelp; got ", err)
  834. }
  835. if !helpCalled {
  836. t.Fatal("help was not called")
  837. }
  838. // If we define a help flag, that should override.
  839. var help bool
  840. fs.BoolVar(&help, "help", false, "help flag")
  841. helpCalled = false
  842. err = fs.Parse([]string{"--help"})
  843. if err != nil {
  844. t.Fatal("expected no error for defined --help; got ", err)
  845. }
  846. if helpCalled {
  847. t.Fatal("help was called; should not have been for defined help flag")
  848. }
  849. }
  850. func TestNoInterspersed(t *testing.T) {
  851. f := NewFlagSet("test", ContinueOnError)
  852. f.SetInterspersed(false)
  853. f.Bool("true", true, "always true")
  854. f.Bool("false", false, "always false")
  855. err := f.Parse([]string{"--true", "break", "--false"})
  856. if err != nil {
  857. t.Fatal("expected no error; got ", err)
  858. }
  859. args := f.Args()
  860. if len(args) != 2 || args[0] != "break" || args[1] != "--false" {
  861. t.Fatal("expected interspersed options/non-options to fail")
  862. }
  863. }
  864. func TestTermination(t *testing.T) {
  865. f := NewFlagSet("termination", ContinueOnError)
  866. boolFlag := f.BoolP("bool", "l", false, "bool value")
  867. if f.Parsed() {
  868. t.Error("f.Parse() = true before Parse")
  869. }
  870. arg1 := "ls"
  871. arg2 := "-l"
  872. args := []string{
  873. "--",
  874. arg1,
  875. arg2,
  876. }
  877. f.SetOutput(ioutil.Discard)
  878. if err := f.Parse(args); err != nil {
  879. t.Fatal("expected no error; got ", err)
  880. }
  881. if !f.Parsed() {
  882. t.Error("f.Parse() = false after Parse")
  883. }
  884. if *boolFlag {
  885. t.Error("expected boolFlag=false, got true")
  886. }
  887. if len(f.Args()) != 2 {
  888. t.Errorf("expected 2 arguments, got %d: %v", len(f.Args()), f.Args())
  889. }
  890. if f.Args()[0] != arg1 {
  891. t.Errorf("expected argument %q got %q", arg1, f.Args()[0])
  892. }
  893. if f.Args()[1] != arg2 {
  894. t.Errorf("expected argument %q got %q", arg2, f.Args()[1])
  895. }
  896. if f.ArgsLenAtDash() != 0 {
  897. t.Errorf("expected argsLenAtDash %d got %d", 0, f.ArgsLenAtDash())
  898. }
  899. }
  900. func getDeprecatedFlagSet() *FlagSet {
  901. f := NewFlagSet("bob", ContinueOnError)
  902. f.Bool("badflag", true, "always true")
  903. f.MarkDeprecated("badflag", "use --good-flag instead")
  904. return f
  905. }
  906. func TestDeprecatedFlagInDocs(t *testing.T) {
  907. f := getDeprecatedFlagSet()
  908. out := new(bytes.Buffer)
  909. f.SetOutput(out)
  910. f.PrintDefaults()
  911. if strings.Contains(out.String(), "badflag") {
  912. t.Errorf("found deprecated flag in usage!")
  913. }
  914. }
  915. func TestUnHiddenDeprecatedFlagInDocs(t *testing.T) {
  916. f := getDeprecatedFlagSet()
  917. flg := f.Lookup("badflag")
  918. if flg == nil {
  919. t.Fatalf("Unable to lookup 'bob' in TestUnHiddenDeprecatedFlagInDocs")
  920. }
  921. flg.Hidden = false
  922. out := new(bytes.Buffer)
  923. f.SetOutput(out)
  924. f.PrintDefaults()
  925. defaults := out.String()
  926. if !strings.Contains(defaults, "badflag") {
  927. t.Errorf("Did not find deprecated flag in usage!")
  928. }
  929. if !strings.Contains(defaults, "use --good-flag instead") {
  930. t.Errorf("Did not find 'use --good-flag instead' in defaults")
  931. }
  932. }
  933. func TestDeprecatedFlagShorthandInDocs(t *testing.T) {
  934. f := NewFlagSet("bob", ContinueOnError)
  935. name := "noshorthandflag"
  936. f.BoolP(name, "n", true, "always true")
  937. f.MarkShorthandDeprecated("noshorthandflag", fmt.Sprintf("use --%s instead", name))
  938. out := new(bytes.Buffer)
  939. f.SetOutput(out)
  940. f.PrintDefaults()
  941. if strings.Contains(out.String(), "-n,") {
  942. t.Errorf("found deprecated flag shorthand in usage!")
  943. }
  944. }
  945. func parseReturnStderr(t *testing.T, f *FlagSet, args []string) (string, error) {
  946. oldStderr := os.Stderr
  947. r, w, _ := os.Pipe()
  948. os.Stderr = w
  949. err := f.Parse(args)
  950. outC := make(chan string)
  951. // copy the output in a separate goroutine so printing can't block indefinitely
  952. go func() {
  953. var buf bytes.Buffer
  954. io.Copy(&buf, r)
  955. outC <- buf.String()
  956. }()
  957. w.Close()
  958. os.Stderr = oldStderr
  959. out := <-outC
  960. return out, err
  961. }
  962. func TestDeprecatedFlagUsage(t *testing.T) {
  963. f := NewFlagSet("bob", ContinueOnError)
  964. f.Bool("badflag", true, "always true")
  965. usageMsg := "use --good-flag instead"
  966. f.MarkDeprecated("badflag", usageMsg)
  967. args := []string{"--badflag"}
  968. out, err := parseReturnStderr(t, f, args)
  969. if err != nil {
  970. t.Fatal("expected no error; got ", err)
  971. }
  972. if !strings.Contains(out, usageMsg) {
  973. t.Errorf("usageMsg not printed when using a deprecated flag!")
  974. }
  975. }
  976. func TestDeprecatedFlagShorthandUsage(t *testing.T) {
  977. f := NewFlagSet("bob", ContinueOnError)
  978. name := "noshorthandflag"
  979. f.BoolP(name, "n", true, "always true")
  980. usageMsg := fmt.Sprintf("use --%s instead", name)
  981. f.MarkShorthandDeprecated(name, usageMsg)
  982. args := []string{"-n"}
  983. out, err := parseReturnStderr(t, f, args)
  984. if err != nil {
  985. t.Fatal("expected no error; got ", err)
  986. }
  987. if !strings.Contains(out, usageMsg) {
  988. t.Errorf("usageMsg not printed when using a deprecated flag!")
  989. }
  990. }
  991. func TestDeprecatedFlagUsageNormalized(t *testing.T) {
  992. f := NewFlagSet("bob", ContinueOnError)
  993. f.Bool("bad-double_flag", true, "always true")
  994. f.SetNormalizeFunc(wordSepNormalizeFunc)
  995. usageMsg := "use --good-flag instead"
  996. f.MarkDeprecated("bad_double-flag", usageMsg)
  997. args := []string{"--bad_double_flag"}
  998. out, err := parseReturnStderr(t, f, args)
  999. if err != nil {
  1000. t.Fatal("expected no error; got ", err)
  1001. }
  1002. if !strings.Contains(out, usageMsg) {
  1003. t.Errorf("usageMsg not printed when using a deprecated flag!")
  1004. }
  1005. }
  1006. // Name normalization function should be called only once on flag addition
  1007. func TestMultipleNormalizeFlagNameInvocations(t *testing.T) {
  1008. normalizeFlagNameInvocations = 0
  1009. f := NewFlagSet("normalized", ContinueOnError)
  1010. f.SetNormalizeFunc(wordSepNormalizeFunc)
  1011. f.Bool("with_under_flag", false, "bool value")
  1012. if normalizeFlagNameInvocations != 1 {
  1013. t.Fatal("Expected normalizeFlagNameInvocations to be 1; got ", normalizeFlagNameInvocations)
  1014. }
  1015. }
  1016. //
  1017. func TestHiddenFlagInUsage(t *testing.T) {
  1018. f := NewFlagSet("bob", ContinueOnError)
  1019. f.Bool("secretFlag", true, "shhh")
  1020. f.MarkHidden("secretFlag")
  1021. out := new(bytes.Buffer)
  1022. f.SetOutput(out)
  1023. f.PrintDefaults()
  1024. if strings.Contains(out.String(), "secretFlag") {
  1025. t.Errorf("found hidden flag in usage!")
  1026. }
  1027. }
  1028. //
  1029. func TestHiddenFlagUsage(t *testing.T) {
  1030. f := NewFlagSet("bob", ContinueOnError)
  1031. f.Bool("secretFlag", true, "shhh")
  1032. f.MarkHidden("secretFlag")
  1033. args := []string{"--secretFlag"}
  1034. out, err := parseReturnStderr(t, f, args)
  1035. if err != nil {
  1036. t.Fatal("expected no error; got ", err)
  1037. }
  1038. if strings.Contains(out, "shhh") {
  1039. t.Errorf("usage message printed when using a hidden flag!")
  1040. }
  1041. }
  1042. const defaultOutput = ` --A for bootstrapping, allow 'any' type
  1043. --Alongflagname disable bounds checking
  1044. -C, --CCC a boolean defaulting to true (default true)
  1045. --D path set relative path for local imports
  1046. -E, --EEE num[=1234] a num with NoOptDefVal (default 4321)
  1047. --F number a non-zero number (default 2.7)
  1048. --G float a float that defaults to zero
  1049. --IP ip IP address with no default
  1050. --IPMask ipMask Netmask address with no default
  1051. --IPNet ipNet IP network with no default
  1052. --Ints ints int slice with zero default
  1053. --N int a non-zero int (default 27)
  1054. --ND1 string[="bar"] a string with NoOptDefVal (default "foo")
  1055. --ND2 num[=4321] a num with NoOptDefVal (default 1234)
  1056. --StringArray stringArray string array with zero default
  1057. --StringSlice strings string slice with zero default
  1058. --Z int an int that defaults to zero
  1059. --custom custom custom Value implementation
  1060. --customP custom a VarP with default (default 10)
  1061. --maxT timeout set timeout for dial
  1062. -v, --verbose count verbosity
  1063. `
  1064. // Custom value that satisfies the Value interface.
  1065. type customValue int
  1066. func (cv *customValue) String() string { return fmt.Sprintf("%v", *cv) }
  1067. func (cv *customValue) Set(s string) error {
  1068. v, err := strconv.ParseInt(s, 0, 64)
  1069. *cv = customValue(v)
  1070. return err
  1071. }
  1072. func (cv *customValue) Type() string { return "custom" }
  1073. func TestPrintDefaults(t *testing.T) {
  1074. fs := NewFlagSet("print defaults test", ContinueOnError)
  1075. var buf bytes.Buffer
  1076. fs.SetOutput(&buf)
  1077. fs.Bool("A", false, "for bootstrapping, allow 'any' type")
  1078. fs.Bool("Alongflagname", false, "disable bounds checking")
  1079. fs.BoolP("CCC", "C", true, "a boolean defaulting to true")
  1080. fs.String("D", "", "set relative `path` for local imports")
  1081. fs.Float64("F", 2.7, "a non-zero `number`")
  1082. fs.Float64("G", 0, "a float that defaults to zero")
  1083. fs.Int("N", 27, "a non-zero int")
  1084. fs.IntSlice("Ints", []int{}, "int slice with zero default")
  1085. fs.IP("IP", nil, "IP address with no default")
  1086. fs.IPMask("IPMask", nil, "Netmask address with no default")
  1087. fs.IPNet("IPNet", net.IPNet{}, "IP network with no default")
  1088. fs.Int("Z", 0, "an int that defaults to zero")
  1089. fs.Duration("maxT", 0, "set `timeout` for dial")
  1090. fs.String("ND1", "foo", "a string with NoOptDefVal")
  1091. fs.Lookup("ND1").NoOptDefVal = "bar"
  1092. fs.Int("ND2", 1234, "a `num` with NoOptDefVal")
  1093. fs.Lookup("ND2").NoOptDefVal = "4321"
  1094. fs.IntP("EEE", "E", 4321, "a `num` with NoOptDefVal")
  1095. fs.ShorthandLookup("E").NoOptDefVal = "1234"
  1096. fs.StringSlice("StringSlice", []string{}, "string slice with zero default")
  1097. fs.StringArray("StringArray", []string{}, "string array with zero default")
  1098. fs.CountP("verbose", "v", "verbosity")
  1099. var cv customValue
  1100. fs.Var(&cv, "custom", "custom Value implementation")
  1101. cv2 := customValue(10)
  1102. fs.VarP(&cv2, "customP", "", "a VarP with default")
  1103. fs.PrintDefaults()
  1104. got := buf.String()
  1105. if got != defaultOutput {
  1106. fmt.Println("\n" + got)
  1107. fmt.Println("\n" + defaultOutput)
  1108. t.Errorf("got %q want %q\n", got, defaultOutput)
  1109. }
  1110. }
  1111. func TestVisitAllFlagOrder(t *testing.T) {
  1112. fs := NewFlagSet("TestVisitAllFlagOrder", ContinueOnError)
  1113. fs.SortFlags = false
  1114. // https://github.com/spf13/pflag/issues/120
  1115. fs.SetNormalizeFunc(func(f *FlagSet, name string) NormalizedName {
  1116. return NormalizedName(name)
  1117. })
  1118. names := []string{"C", "B", "A", "D"}
  1119. for _, name := range names {
  1120. fs.Bool(name, false, "")
  1121. }
  1122. i := 0
  1123. fs.VisitAll(func(f *Flag) {
  1124. if names[i] != f.Name {
  1125. t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name)
  1126. }
  1127. i++
  1128. })
  1129. }
  1130. func TestVisitFlagOrder(t *testing.T) {
  1131. fs := NewFlagSet("TestVisitFlagOrder", ContinueOnError)
  1132. fs.SortFlags = false
  1133. names := []string{"C", "B", "A", "D"}
  1134. for _, name := range names {
  1135. fs.Bool(name, false, "")
  1136. fs.Set(name, "true")
  1137. }
  1138. i := 0
  1139. fs.Visit(func(f *Flag) {
  1140. if names[i] != f.Name {
  1141. t.Errorf("Incorrect order. Expected %v, got %v", names[i], f.Name)
  1142. }
  1143. i++
  1144. })
  1145. }