From 326772ea293b89ac4256a090f01cdfc623984900 Mon Sep 17 00:00:00 2001 From: Trevor Foster Date: Sat, 28 Mar 2020 00:07:50 -0400 Subject: [PATCH] add logic to return flags default if not val set, add a test --- viper.go | 16 ++++++++++++++++ viper_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/viper.go b/viper.go index 1d2610a..5c38cef 100644 --- a/viper.go +++ b/viper.go @@ -1086,6 +1086,9 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} { case "stringToString": s := strings.TrimPrefix(flag.ValueString(), "[") s = strings.TrimSuffix(s, "]") + if s == "" { + return nil + } elements := strings.Split(s, ",") result := make(map[string]string, len(elements)) for _, element := range elements { @@ -1168,6 +1171,19 @@ func (v *Viper) find(lcaseKey string, flagDefault bool) interface{} { s = strings.TrimSuffix(s, "]") res, _ := readAsCSV(s) return cast.ToIntSlice(res) + case "stringToString": + s := strings.TrimPrefix(flag.ValueString(), "[") + s = strings.TrimSuffix(s, "]") + if s == "" { + return nil + } + elements := strings.Split(s, ",") + result := make(map[string]string, len(elements)) + for _, element := range elements { + pair := strings.SplitN(element, "=", 2) + result[pair[0]] = pair[1] + } + return result default: return flag.ValueString() } diff --git a/viper_test.go b/viper_test.go index b8ceccb..f0de6be 100644 --- a/viper_test.go +++ b/viper_test.go @@ -970,6 +970,51 @@ func TestBindPFlag(t *testing.T) { assert.Equal(t, "testing_mutate", Get("testvalue")) } +func TestBindPFlagStringToString(t *testing.T) { + tests := []struct { + Expected map[string]string + Value string + }{ + {nil, ""}, + {map[string]string{"yo": "hi"}, "yo=hi"}, + {map[string]string{"yo": "hi", "oh": "hi=there"}, "yo=hi,oh=hi=there"}, + } + + v := New() // create independent Viper object + defaultVal := map[string]string{} + v.SetDefault("stringtostring", defaultVal) + + for _, testValue := range tests { + flagSet := pflag.NewFlagSet("test", pflag.ContinueOnError) + flagSet.StringToString("stringtostring", testValue.Expected, "test") + + for _, changed := range []bool{true, false} { + flagSet.VisitAll(func(f *pflag.Flag) { + f.Value.Set(testValue.Value) + f.Changed = changed + }) + + err := v.BindPFlags(flagSet) + if err != nil { + t.Fatalf("error binding flag set, %v", err) + } + + type TestMap struct { + StringToString map[string]string + } + val := &TestMap{} + if err := v.Unmarshal(val); err != nil { + t.Fatalf("%+#v cannot unmarshal: %s", testValue.Value, err) + } + if changed { + assert.Equal(t, testValue.Expected, val.StringToString) + } else { + assert.Equal(t, defaultVal, val.StringToString) + } + } + } +} + func TestBoundCaseSensitivity(t *testing.T) { assert.Equal(t, "brown", Get("eyes"))