From 1a91f3dce5b5847ac96cd3f459efe2fcb4ba29ba Mon Sep 17 00:00:00 2001 From: Dan Buch Date: Fri, 29 Apr 2016 02:53:58 -0400 Subject: [PATCH] Ensure IntSlice & StringSlice serialization works as expected --- flag.go | 20 +++++++++++++------- flag_test.go | 51 ++++++++++++++++++++++++++++++++++++++++++--------- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/flag.go b/flag.go index 38029c4..a5c8d2c 100644 --- a/flag.go +++ b/flag.go @@ -141,9 +141,9 @@ func (f *StringSlice) Set(value string) error { } if strings.HasPrefix(value, slPfx) { - v := []string{} - _ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), v) - f.slice = append(f.slice, v...) + // Deserializing assumes overwrite + _ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &f.slice) + f.hasBeenSet = true return nil } @@ -242,10 +242,10 @@ func (i *IntSlice) Set(value string) error { i.hasBeenSet = true } - if strings.HasPrefix(slPfx, value) { - v := []int{} - _ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), v) - i.slice = append(i.slice, v...) + if strings.HasPrefix(value, slPfx) { + // Deserializing assumes overwrite + _ = json.Unmarshal([]byte(strings.Replace(value, slPfx, "", 1)), &i.slice) + i.hasBeenSet = true return nil } @@ -263,6 +263,12 @@ func (i *IntSlice) String() string { return fmt.Sprintf("%v", i.slice) } +// Serialized allows IntSlice to fulfill Serializeder +func (i *IntSlice) Serialized() string { + jsonBytes, _ := json.Marshal(i.slice) + return fmt.Sprintf("%s%s", slPfx, string(jsonBytes)) +} + // Value returns the slice of ints set by this flag func (i *IntSlice) Value() []int { return i.slice diff --git a/flag_test.go b/flag_test.go index 1288a73..843f175 100644 --- a/flag_test.go +++ b/flag_test.go @@ -43,7 +43,6 @@ var stringFlagTests = []struct { } func TestStringFlagHelpOutput(t *testing.T) { - for _, test := range stringFlagTests { flag := StringFlag{Name: test.name, Usage: test.usage, Value: test.value} output := flag.String() @@ -376,11 +375,12 @@ func TestParseMultiStringSlice(t *testing.T) { StringSliceFlag{Name: "serve, s", Value: NewStringSlice()}, }, Action: func(ctx *Context) { - if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) { - t.Errorf("main name not set") + expected := []string{"10", "20"} + if !reflect.DeepEqual(ctx.StringSlice("serve"), expected) { + t.Errorf("main name not set: %v != %v", expected, ctx.StringSlice("serve")) } - if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) { - t.Errorf("short name not set") + if !reflect.DeepEqual(ctx.StringSlice("s"), expected) { + t.Errorf("short name not set: %v != %v", expected, ctx.StringSlice("s")) } }, }).Run([]string{"run", "-s", "10", "-s", "20"}) @@ -392,11 +392,12 @@ func TestParseMultiStringSliceWithDefaults(t *testing.T) { StringSliceFlag{Name: "serve, s", Value: NewStringSlice("9", "2")}, }, Action: func(ctx *Context) { - if !reflect.DeepEqual(ctx.StringSlice("serve"), []string{"10", "20"}) { - t.Errorf("main name not set: %v", ctx.StringSlice("serve")) + expected := []string{"10", "20"} + if !reflect.DeepEqual(ctx.StringSlice("serve"), expected) { + t.Errorf("main name not set: %v != %v", expected, ctx.StringSlice("serve")) } - if !reflect.DeepEqual(ctx.StringSlice("s"), []string{"10", "20"}) { - t.Errorf("short name not set: %v", ctx.StringSlice("s")) + if !reflect.DeepEqual(ctx.StringSlice("s"), expected) { + t.Errorf("short name not set: %v != %v", expected, ctx.StringSlice("s")) } }, }).Run([]string{"run", "-s", "10", "-s", "20"}) @@ -960,3 +961,35 @@ func TestParseGenericFromEnvCascade(t *testing.T) { } a.Run([]string{"run"}) } + +func TestStringSlice_Serialized_Set(t *testing.T) { + sl0 := NewStringSlice("a", "b") + ser0 := sl0.Serialized() + + if len(ser0) < len(slPfx) { + t.Fatalf("serialized shorter than expected: %q", ser0) + } + + sl1 := NewStringSlice("c", "d") + sl1.Set(ser0) + + if sl0.String() != sl1.String() { + t.Fatalf("pre and post serialization do not match: %v != %v", sl0, sl1) + } +} + +func TestIntSlice_Serialized_Set(t *testing.T) { + sl0 := NewIntSlice(1, 2) + ser0 := sl0.Serialized() + + if len(ser0) < len(slPfx) { + t.Fatalf("serialized shorter than expected: %q", ser0) + } + + sl1 := NewIntSlice(3, 4) + sl1.Set(ser0) + + if sl0.String() != sl1.String() { + t.Fatalf("pre and post serialization do not match: %v != %v", sl0, sl1) + } +}