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  }