github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/util/flagutil/flagutil_test.go (about) 1 // Copyright 2018 The Cockroach Authors. 2 // 3 // Use of this software is governed by the Business Source License 4 // included in the file licenses/BSL.txt. 5 // 6 // As of the Change Date specified in that file, in accordance with 7 // the Business Source License, use of this software will be governed 8 // by the Apache License, Version 2.0, included in the file 9 // licenses/APL.txt. 10 11 package flagutil 12 13 import ( 14 "fmt" 15 "regexp" 16 "testing" 17 "time" 18 19 "github.com/cockroachdb/cockroach/pkg/util/log" 20 "github.com/cockroachdb/cockroach/pkg/util/timeutil" 21 "github.com/spf13/pflag" 22 ) 23 24 func Example() { 25 var when time.Time 26 var re *regexp.Regexp 27 flags := pflag.NewFlagSet("flags", pflag.PanicOnError) 28 flags.Var(Time(&when), "when", "sets the time when it happens") 29 flags.Var(Regexp(&re), "re", "pattern to tell if it's a match") 30 if err := flags.Parse([]string{ 31 "--when", "13:02", 32 "--re", "a match$", 33 }); err != nil { 34 panic(err) 35 } 36 fmt.Println("it happens at", when.Format(time.Kitchen), re.MatchString("it's a match")) 37 // Output: 38 // it happens at 1:02PM true 39 } 40 41 func TestZeroValueEmptyString(t *testing.T) { 42 if got := Time(&time.Time{}).String(); got != "" { 43 t.Fatalf("got unexpected %v from empty timeFlag.String()", got) 44 } 45 var r *regexp.Regexp 46 if got := Regexp(&r).String(); got != "" { 47 t.Fatalf("unexpected value %v from empty regexp string", got) 48 } 49 } 50 51 func TestDuration(t *testing.T) { 52 got := parseTime(t, "1m") 53 if then := timeutil.Now().Add(-1 * time.Minute); then.Sub(got) > 50*time.Millisecond { 54 t.Fatalf("Parsed duration is not near now less a minute: got %v, expected near %v, delta %v", 55 got, then, then.Sub(got)) 56 } 57 } 58 59 func TestTimeNegative(t *testing.T) { 60 var when time.Time 61 flags := pflag.NewFlagSet("test", pflag.PanicOnError) 62 flags.Var(Time(&when), "time", "it's a test") 63 defer func() { 64 if r := recover(); r == nil { 65 t.Fatalf("did not panic during Parse") 66 } 67 }() 68 if err := flags.Parse([]string{"--time", "junk"}); err != nil { 69 t.Fatalf("error parsing flags: %v", err) 70 } 71 } 72 73 func TestType(t *testing.T) { 74 Regexp(nil).Type() 75 Time(nil).Type() 76 } 77 78 func TestTimeFlag(t *testing.T) { 79 for _, c := range []timeCase{ 80 {"12:01", mustParse(time.Kitchen, "12:01PM")}, 81 {"00:01", mustParse(time.Kitchen, "12:01AM")}, 82 {"07:01Z", mustParse("15:04:05.999999999Z07:00", "07:01:00.0Z")}, 83 } { 84 c.run(t) 85 } 86 } 87 88 type timeCase struct { 89 flag string 90 expected time.Time 91 } 92 93 func (c *timeCase) run(t *testing.T) { 94 when := parseTime(t, c.flag) 95 if !when.Equal(c.expected) { 96 t.Errorf("parsing of %v did not equal %v, got %v", c.flag, c.expected, when) 97 } 98 s := Time(&when).String() 99 expected := when.Format(log.MessageTimeFormat) 100 if s != expected { 101 t.Errorf("String() method returned unexpected %q, expected %q", s, expected) 102 } 103 } 104 105 func mustParse(format, s string) time.Time { 106 t, err := time.Parse(format, s) 107 if err != nil { 108 panic(err) 109 } 110 return t.UTC() 111 } 112 113 func parseTime(t *testing.T, flag string) time.Time { 114 var when time.Time 115 flags := pflag.NewFlagSet("test", pflag.PanicOnError) 116 flags.Var(Time(&when), "time", "it's a test") 117 defer func() { 118 if r := recover(); r != nil { 119 t.Fatalf("panicked during Parse: %v", r) 120 } 121 }() 122 if err := flags.Parse([]string{"--time", flag}); err != nil { 123 t.Fatalf("unexpected error from flag.Parse: %v", err) 124 } 125 return when 126 } 127 128 func TestRegexpNegative(t *testing.T) { 129 var re *regexp.Regexp 130 flags := pflag.NewFlagSet("test", pflag.PanicOnError) 131 flags.Var(Regexp(&re), "re", "it's a test") 132 defer func() { 133 if r := recover(); r == nil { 134 t.Fatalf("did not panic during Parse") 135 } 136 }() 137 if err := flags.Parse([]string{"--re", "a+*"}); err != nil { 138 t.Fatalf("shouldn't have gotten to this code") 139 } 140 } 141 142 func TestRegexpString(t *testing.T) { 143 re := regexp.MustCompile(".*") 144 if Regexp(&re).String() != re.String() { 145 t.Fatalf("unexpected string value from non-empty Regexp") 146 } 147 } 148 149 func TestEmptyStringZeroes(t *testing.T) { 150 now := timeutil.Now() 151 re := regexp.MustCompile(".*") 152 flags := pflag.NewFlagSet("test", pflag.PanicOnError) 153 flags.Var(Time(&now), "time", "it's a test") 154 flags.Var(Regexp(&re), "re", "it's a test") 155 if err := flags.Parse([]string{"--time", "", "--re", ""}); err != nil { 156 t.Fatalf("error parsing flags: %v", err) 157 } 158 if re != nil { 159 t.Errorf("expected empty string to zero regexp") 160 } 161 if !now.IsZero() { 162 t.Errorf("expected empty string to zero time") 163 } 164 }