diff --git a/duration_slice.go b/duration_slice.go index ee987274..9871bc1f 100644 --- a/duration_slice.go +++ b/duration_slice.go @@ -19,7 +19,7 @@ func newDurationSliceValue(val []time.Duration, p *[]time.Duration) *durationSli } func (s *durationSliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]time.Duration, len(ss)) for i, d := range ss { var err error @@ -94,7 +94,7 @@ func durationSliceConv(val string) (interface{}, error) { if len(val) == 0 { return []time.Duration{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]time.Duration, len(ss)) for i, d := range ss { var err error diff --git a/duration_slice_test.go b/duration_slice_test.go index 651fbd8b..372176c3 100644 --- a/duration_slice_test.go +++ b/duration_slice_test.go @@ -40,6 +40,26 @@ func TestEmptyDS(t *testing.T) { } } +func TestEmptyDSValue(t *testing.T) { + var ds []time.Duration + f := setUpDSFlagSet(&ds) + err := f.Parse([]string{"--ds="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getDS, err := f.GetDurationSlice("ds") + if err != nil { + t.Fatal("got an error from GetDurationSlice():", err) + } + if ds == nil || len(ds) != 0 { + t.Fatalf("got ds %v with len=%d but expected non-nil length=0", ds, len(ds)) + } + if len(getDS) != 0 { + t.Fatalf("got ds %v with len=%d but expected length=0", getDS, len(getDS)) + } +} + func TestDS(t *testing.T) { var ds []time.Duration f := setUpDSFlagSet(&ds) diff --git a/float32_slice.go b/float32_slice.go index caa35274..1cf9a96d 100644 --- a/float32_slice.go +++ b/float32_slice.go @@ -20,7 +20,7 @@ func newFloat32SliceValue(val []float32, p *[]float32) *float32SliceValue { } func (s *float32SliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]float32, len(ss)) for i, d := range ss { var err error @@ -101,7 +101,7 @@ func float32SliceConv(val string) (interface{}, error) { if len(val) == 0 { return []float32{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]float32, len(ss)) for i, d := range ss { var err error diff --git a/float32_slice_test.go b/float32_slice_test.go index 997ce5c6..c4d44f55 100644 --- a/float32_slice_test.go +++ b/float32_slice_test.go @@ -40,6 +40,26 @@ func TestEmptyF32S(t *testing.T) { } } +func TestEmptyF32SValue(t *testing.T) { + var f32s []float32 + f := setUpF32SFlagSet(&f32s) + err := f.Parse([]string{"--f32s="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getF32S, err := f.GetFloat32Slice("f32s") + if err != nil { + t.Fatal("got an error from GetFloat32Slice():", err) + } + if f32s == nil || len(f32s) != 0 { + t.Fatalf("got f32s %v with len=%d but expected non-nil length=0", f32s, len(f32s)) + } + if len(getF32S) != 0 { + t.Fatalf("got f32s %v with len=%d but expected length=0", getF32S, len(getF32S)) + } +} + func TestF32S(t *testing.T) { var f32s []float32 f := setUpF32SFlagSet(&f32s) diff --git a/float64_slice.go b/float64_slice.go index 85bf3073..99b18c97 100644 --- a/float64_slice.go +++ b/float64_slice.go @@ -20,7 +20,7 @@ func newFloat64SliceValue(val []float64, p *[]float64) *float64SliceValue { } func (s *float64SliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]float64, len(ss)) for i, d := range ss { var err error @@ -95,7 +95,7 @@ func float64SliceConv(val string) (interface{}, error) { if len(val) == 0 { return []float64{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]float64, len(ss)) for i, d := range ss { var err error diff --git a/float64_slice_test.go b/float64_slice_test.go index 43778ef1..b48bb0f1 100644 --- a/float64_slice_test.go +++ b/float64_slice_test.go @@ -40,6 +40,26 @@ func TestEmptyF64S(t *testing.T) { } } +func TestEmptyF64SValue(t *testing.T) { + var f64s []float64 + f := setUpF64SFlagSet(&f64s) + err := f.Parse([]string{"--f64s="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getF64S, err := f.GetFloat64Slice("f64s") + if err != nil { + t.Fatal("got an error from GetFloat64Slice():", err) + } + if f64s == nil || len(f64s) != 0 { + t.Fatalf("got f64s %v with len=%d but expected non-nil length=0", f64s, len(f64s)) + } + if len(getF64S) != 0 { + t.Fatalf("got f64s %v with len=%d but expected length=0", getF64S, len(getF64S)) + } +} + func TestF64S(t *testing.T) { var f64s []float64 f := setUpF64SFlagSet(&f64s) diff --git a/int32_slice.go b/int32_slice.go index ff128ff0..03240d7a 100644 --- a/int32_slice.go +++ b/int32_slice.go @@ -20,7 +20,7 @@ func newInt32SliceValue(val []int32, p *[]int32) *int32SliceValue { } func (s *int32SliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]int32, len(ss)) for i, d := range ss { var err error @@ -101,7 +101,7 @@ func int32SliceConv(val string) (interface{}, error) { if len(val) == 0 { return []int32{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]int32, len(ss)) for i, d := range ss { var err error diff --git a/int32_slice_test.go b/int32_slice_test.go index 809c5633..c49e7bcc 100644 --- a/int32_slice_test.go +++ b/int32_slice_test.go @@ -40,6 +40,26 @@ func TestEmptyI32S(t *testing.T) { } } +func TestEmptyI32SValue(t *testing.T) { + var is []int32 + f := setUpI32SFlagSet(&is) + err := f.Parse([]string{"--is="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getI32S, err := f.GetInt32Slice("is") + if err != nil { + t.Fatal("got an error from GetInt32Slice():", err) + } + if is == nil || len(is) != 0 { + t.Fatalf("got is %v with len=%d but expected non-nil length=0", is, len(is)) + } + if len(getI32S) != 0 { + t.Fatalf("got is %v with len=%d but expected length=0", getI32S, len(getI32S)) + } +} + func TestI32S(t *testing.T) { var is []int32 f := setUpI32SFlagSet(&is) diff --git a/int64_slice.go b/int64_slice.go index 25464638..2970320a 100644 --- a/int64_slice.go +++ b/int64_slice.go @@ -20,7 +20,7 @@ func newInt64SliceValue(val []int64, p *[]int64) *int64SliceValue { } func (s *int64SliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]int64, len(ss)) for i, d := range ss { var err error @@ -95,7 +95,7 @@ func int64SliceConv(val string) (interface{}, error) { if len(val) == 0 { return []int64{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]int64, len(ss)) for i, d := range ss { var err error diff --git a/int64_slice_test.go b/int64_slice_test.go index 09805c76..aeb84e16 100644 --- a/int64_slice_test.go +++ b/int64_slice_test.go @@ -40,6 +40,26 @@ func TestEmptyI64S(t *testing.T) { } } +func TestEmptyI64SValue(t *testing.T) { + var is []int64 + f := setUpI64SFlagSet(&is) + err := f.Parse([]string{"--is="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getI64S, err := f.GetInt64Slice("is") + if err != nil { + t.Fatal("got an error from GetInt64Slice():", err) + } + if is == nil || len(is) != 0 { + t.Fatalf("got is %v with len=%d but expected non-nil length=0", is, len(is)) + } + if len(getI64S) != 0 { + t.Fatalf("got is %v with len=%d but expected length=0", getI64S, len(getI64S)) + } +} + func TestI64S(t *testing.T) { var is []int64 f := setUpI64SFlagSet(&is) diff --git a/int_slice.go b/int_slice.go index e71c39d9..bc7eb045 100644 --- a/int_slice.go +++ b/int_slice.go @@ -20,7 +20,7 @@ func newIntSliceValue(val []int, p *[]int) *intSliceValue { } func (s *intSliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]int, len(ss)) for i, d := range ss { var err error @@ -87,7 +87,7 @@ func intSliceConv(val string) (interface{}, error) { if len(val) == 0 { return []int{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]int, len(ss)) for i, d := range ss { var err error diff --git a/int_slice_test.go b/int_slice_test.go index 745aecb9..e89c38d1 100644 --- a/int_slice_test.go +++ b/int_slice_test.go @@ -40,6 +40,26 @@ func TestEmptyIS(t *testing.T) { } } +func TestEmptyISValue(t *testing.T) { + var is []int + f := setUpISFlagSet(&is) + err := f.Parse([]string{"--is="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getIS, err := f.GetIntSlice("is") + if err != nil { + t.Fatal("got an error from GetIntSlice():", err) + } + if is == nil || len(is) != 0 { + t.Fatalf("got is %v with len=%d but expected non-nil length=0", is, len(is)) + } + if len(getIS) != 0 { + t.Fatalf("got is %v with len=%d but expected length=0", getIS, len(getIS)) + } +} + func TestIS(t *testing.T) { var is []int f := setUpISFlagSet(&is) diff --git a/slice_helpers.go b/slice_helpers.go new file mode 100644 index 00000000..06fbe504 --- /dev/null +++ b/slice_helpers.go @@ -0,0 +1,12 @@ +package pflag + +import "strings" + +// splitCommaSeparatedSliceValue preserves an explicit empty flag value as an +// empty slice instead of strings.Split's single empty-string element. +func splitCommaSeparatedSliceValue(val string) []string { + if val == "" { + return []string{} + } + return strings.Split(val, ",") +} diff --git a/uint_slice.go b/uint_slice.go index 5fa92483..8129fb0f 100644 --- a/uint_slice.go +++ b/uint_slice.go @@ -20,10 +20,10 @@ func newUintSliceValue(val []uint, p *[]uint) *uintSliceValue { } func (s *uintSliceValue) Set(val string) error { - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]uint, len(ss)) for i, d := range ss { - u, err := strconv.ParseUint(d, 10, 0) + u, err := strconv.ParseUint(d, 0, 0) if err != nil { return err } @@ -51,7 +51,7 @@ func (s *uintSliceValue) String() string { } func (s *uintSliceValue) fromString(val string) (uint, error) { - t, err := strconv.ParseUint(val, 10, 0) + t, err := strconv.ParseUint(val, 0, 0) if err != nil { return 0, err } @@ -98,10 +98,10 @@ func uintSliceConv(val string) (interface{}, error) { if len(val) == 0 { return []uint{}, nil } - ss := strings.Split(val, ",") + ss := splitCommaSeparatedSliceValue(val) out := make([]uint, len(ss)) for i, d := range ss { - u, err := strconv.ParseUint(d, 10, 0) + u, err := strconv.ParseUint(d, 0, 0) if err != nil { return nil, err } diff --git a/uint_slice_test.go b/uint_slice_test.go index d0da4d07..2bb146cd 100644 --- a/uint_slice_test.go +++ b/uint_slice_test.go @@ -36,6 +36,26 @@ func TestEmptyUIS(t *testing.T) { } } +func TestEmptyUISValue(t *testing.T) { + var uis []uint + f := setUpUISFlagSet(&uis) + err := f.Parse([]string{"--uis="}) + if err != nil { + t.Fatal("expected no error; got", err) + } + + getUIS, err := f.GetUintSlice("uis") + if err != nil { + t.Fatal("got an error from GetUintSlice():", err) + } + if uis == nil || len(uis) != 0 { + t.Fatalf("got uis %v with len=%d but expected non-nil length=0", uis, len(uis)) + } + if len(getUIS) != 0 { + t.Fatalf("got uis %v with len=%d but expected length=0", getUIS, len(getUIS)) + } +} + func TestUIS(t *testing.T) { var uis []uint f := setUpUISFlagSet(&uis)