From 13a79f2a27e1854724afc7a8bb38d43be41abe95 Mon Sep 17 00:00:00 2001 From: Joe Buck Date: Thu, 18 Feb 2016 21:24:56 -0800 Subject: [PATCH 1/3] Add a field to the JSON test data The field is being added in preparation for testing nested key parsing from environment variables. --- viper_test.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/viper_test.go b/viper_test.go index 858caff..dde1fe0 100644 --- a/viper_test.go +++ b/viper_test.go @@ -65,6 +65,9 @@ var jsonExample = []byte(`{ { "type": "Blueberry" }, { "type": "Devil's Food" } ] + }, +"icing": { + "type": "fancy" } }`) @@ -420,9 +423,9 @@ func TestSetEnvReplacer(t *testing.T) { func TestAllKeys(t *testing.T) { initConfigs() - ks := sort.StringSlice{"title", "newkey", "owner", "name", "beard", "ppu", "batters", "hobbies", "clothing", "age", "hacker", "id", "type", "eyes", "p_id", "p_ppu", "p_batters.batter.type", "p_type", "p_name", "foos"} + ks := sort.StringSlice{"title", "newkey", "owner", "name", "beard", "ppu", "batters", "hobbies", "icing", "clothing", "age", "hacker", "id", "type", "eyes", "p_id", "p_ppu", "p_batters.batter.type", "p_type", "p_name", "foos"} dob, _ := time.Parse(time.RFC3339, "1979-05-27T07:32:00Z") - all := map[string]interface{}{"owner": map[string]interface{}{"organization": "MongoDB", "Bio": "MongoDB Chief Developer Advocate & Hacker at Large", "dob": dob}, "title": "TOML Example", "ppu": 0.55, "eyes": "brown", "clothing": map[interface{}]interface{}{"trousers": "denim", "jacket": "leather", "pants": map[interface{}]interface{}{"size": "large"}}, "id": "0001", "batters": map[string]interface{}{"batter": []interface{}{map[string]interface{}{"type": "Regular"}, map[string]interface{}{"type": "Chocolate"}, map[string]interface{}{"type": "Blueberry"}, map[string]interface{}{"type": "Devil's Food"}}}, "hacker": true, "beard": true, "hobbies": []interface{}{"skateboarding", "snowboarding", "go"}, "age": 35, "type": "donut", "newkey": "remote", "name": "Cake", "p_id": "0001", "p_ppu": "0.55", "p_name": "Cake", "p_batters.batter.type": "Regular", "p_type": "donut", "foos": []map[string]interface{}{map[string]interface{}{"foo": []map[string]interface{}{map[string]interface{}{"key": 1}, map[string]interface{}{"key": 2}, map[string]interface{}{"key": 3}, map[string]interface{}{"key": 4}}}}} + all := map[string]interface{}{"owner": map[string]interface{}{"organization": "MongoDB", "Bio": "MongoDB Chief Developer Advocate & Hacker at Large", "dob": dob}, "title": "TOML Example", "ppu": 0.55, "eyes": "brown", "clothing": map[interface{}]interface{}{"trousers": "denim", "jacket": "leather", "pants": map[interface{}]interface{}{"size": "large"}}, "id": "0001", "icing": map[string]interface{}{"type": "fancy"}, "batters": map[string]interface{}{"batter": []interface{}{map[string]interface{}{"type": "Regular"}, map[string]interface{}{"type": "Chocolate"}, map[string]interface{}{"type": "Blueberry"}, map[string]interface{}{"type": "Devil's Food"}}}, "hacker": true, "beard": true, "hobbies": []interface{}{"skateboarding", "snowboarding", "go"}, "age": 35, "type": "donut", "newkey": "remote", "name": "Cake", "p_id": "0001", "p_ppu": "0.55", "p_name": "Cake", "p_batters.batter.type": "Regular", "p_type": "donut", "foos": []map[string]interface{}{map[string]interface{}{"foo": []map[string]interface{}{map[string]interface{}{"key": 1}, map[string]interface{}{"key": 2}, map[string]interface{}{"key": 3}, map[string]interface{}{"key": 4}}}}} var allkeys sort.StringSlice allkeys = AllKeys() From e8036e1a2445b59499088b9167d8c1e6176de894 Mon Sep 17 00:00:00 2001 From: Joe Buck Date: Thu, 18 Feb 2016 21:27:02 -0800 Subject: [PATCH 2/3] Add test for parsing nested keys from environment variables Add a test where an environment variable with a nested key is set and then retrieved. The nested key uses an underscore in place of a dot to indicate the key hierarchy. --- viper_test.go | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/viper_test.go b/viper_test.go index dde1fe0..44c4b4c 100644 --- a/viper_test.go +++ b/viper_test.go @@ -371,6 +371,30 @@ func TestEnv(t *testing.T) { } +func TestEnvNestedKeys(t *testing.T) { + initJSON() + + BindEnv("id") + BindEnv("f", "FOOD") + + // Validate the default value + assert.Equal(t, "fancy", Get("icing.type")) + + os.Setenv("ID", "13") + os.Setenv("FOOD", "apple") + os.Setenv("NAME", "crunk") + os.Setenv("ICING_TYPE", "plain") + + assert.Equal(t, "13", Get("id")) + assert.Equal(t, "apple", Get("f")) + assert.Equal(t, "Cake", Get("name")) + + AutomaticEnv() + + assert.Equal(t, "plain", Get("icing.type")) + assert.Equal(t, "crunk", Get("name")) +} + func TestEnvPrefix(t *testing.T) { initJSON() From 8b2b4b8675992e4ca53ca0bd50ecdc4182614bac Mon Sep 17 00:00:00 2001 From: Joe Buck Date: Thu, 18 Feb 2016 21:48:15 -0800 Subject: [PATCH 3/3] Replace "." characters with "_" when parsing environment variables This brings viper in line with other configuration parsing libraries and in line with what I would anticipate are the expectations of most programms. --- viper.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/viper.go b/viper.go index 7a49a0a..0f0a6d4 100644 --- a/viper.go +++ b/viper.go @@ -305,6 +305,10 @@ func (v *Viper) getEnv(key string) string { if v.envKeyReplacer != nil { key = v.envKeyReplacer.Replace(key) } + + // Replace dots with underscores, since that is the sensible mapping + // for environment variables. The -1 means replace all insstances of "." with "_" + key = strings.Replace(key, ".", "_", -1) return os.Getenv(key) }