From cfcfed504d84a1e605a7ee99d48affa1650b8e97 Mon Sep 17 00:00:00 2001 From: Mark Sagi-Kazar Date: Wed, 30 Sep 2020 13:02:07 +0200 Subject: [PATCH] refactor: add setenv helper for tests Signed-off-by: Mark Sagi-Kazar --- internal/testutil/env.go | 42 ++++++++++++++++++++++++++++ util_test.go | 6 ++-- viper_test.go | 60 ++++++++++++++++++++-------------------- 3 files changed, 76 insertions(+), 32 deletions(-) create mode 100644 internal/testutil/env.go diff --git a/internal/testutil/env.go b/internal/testutil/env.go new file mode 100644 index 0000000..e5eaddd --- /dev/null +++ b/internal/testutil/env.go @@ -0,0 +1,42 @@ +package testutil + +import ( + "os" + "testing" +) + +// Based on https://github.com/frankban/quicktest/blob/577841610793d24f99e31cc2c0ef3a541fefd7c7/patch.go#L34-L64 +// Licensed under the MIT license +// Copyright (c) 2017 Canonical Ltd. + +// Setenv sets an environment variable to a temporary value for the +// duration of the test. +// +// At the end of the test (see "Deferred execution" in the package docs), the +// environment variable is returned to its original value. +func Setenv(t *testing.T, name, val string) { + setenv(t, name, val, true) +} + +// Unsetenv unsets an environment variable for the duration of a test. +func Unsetenv(t *testing.T, name string) { + setenv(t, name, "", false) +} + +// setenv sets or unsets an environment variable to a temporary value for the +// duration of the test +func setenv(t *testing.T, name, val string, valOK bool) { + oldVal, oldOK := os.LookupEnv(name) + if valOK { + os.Setenv(name, val) + } else { + os.Unsetenv(name) + } + t.Cleanup(func() { + if oldOK { + os.Setenv(name, oldVal) + } else { + os.Unsetenv(name) + } + }) +} diff --git a/util_test.go b/util_test.go index 8c98704..a377d5b 100644 --- a/util_test.go +++ b/util_test.go @@ -15,6 +15,8 @@ import ( "path/filepath" "reflect" "testing" + + "github.com/spf13/viper/internal/testutil" ) func TestCopyAndInsensitiviseMap(t *testing.T) { @@ -62,8 +64,8 @@ func TestAbsPathify(t *testing.T) { homer := filepath.Join(home, "homer") wd, _ := os.Getwd() - os.Setenv("HOMER_ABSOLUTE_PATH", homer) - os.Setenv("VAR_WITH_RELATIVE_PATH", "relative") + testutil.Setenv(t, "HOMER_ABSOLUTE_PATH", homer) + testutil.Setenv(t, "VAR_WITH_RELATIVE_PATH", "relative") tests := []struct { input string diff --git a/viper_test.go b/viper_test.go index 28c7f13..29a4bfb 100644 --- a/viper_test.go +++ b/viper_test.go @@ -29,6 +29,8 @@ import ( "github.com/spf13/pflag" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + + "github.com/spf13/viper/internal/testutil" ) var yamlExample = []byte(`Hacker: true @@ -488,10 +490,10 @@ func TestEnv(t *testing.T) { BindEnv("id") BindEnv("f", "FOOD", "OLD_FOOD") - os.Setenv("ID", "13") - os.Setenv("FOOD", "apple") - os.Setenv("OLD_FOOD", "banana") - os.Setenv("NAME", "crunk") + testutil.Setenv(t, "ID", "13") + testutil.Setenv(t, "FOOD", "apple") + testutil.Setenv(t, "OLD_FOOD", "banana") + testutil.Setenv(t, "NAME", "crunk") assert.Equal(t, "13", Get("id")) assert.Equal(t, "apple", Get("f")) @@ -507,8 +509,7 @@ func TestMultipleEnv(t *testing.T) { BindEnv("f", "FOOD", "OLD_FOOD") - os.Unsetenv("FOOD") - os.Setenv("OLD_FOOD", "banana") + testutil.Setenv(t, "OLD_FOOD", "banana") assert.Equal(t, "banana", Get("f")) } @@ -519,12 +520,7 @@ func TestEmptyEnv(t *testing.T) { BindEnv("type") // Empty environment variable BindEnv("name") // Bound, but not set environment variable - os.Unsetenv("type") - os.Unsetenv("TYPE") - os.Unsetenv("name") - os.Unsetenv("NAME") - - os.Setenv("TYPE", "") + testutil.Setenv(t, "TYPE", "") assert.Equal(t, "donut", Get("type")) assert.Equal(t, "Cake", Get("name")) @@ -538,12 +534,7 @@ func TestEmptyEnv_Allowed(t *testing.T) { BindEnv("type") // Empty environment variable BindEnv("name") // Bound, but not set environment variable - os.Unsetenv("type") - os.Unsetenv("TYPE") - os.Unsetenv("name") - os.Unsetenv("NAME") - - os.Setenv("TYPE", "") + testutil.Setenv(t, "TYPE", "") assert.Equal(t, "", Get("type")) assert.Equal(t, "Cake", Get("name")) @@ -556,9 +547,9 @@ func TestEnvPrefix(t *testing.T) { BindEnv("id") BindEnv("f", "FOOD") // not using prefix - os.Setenv("FOO_ID", "13") - os.Setenv("FOOD", "apple") - os.Setenv("FOO_NAME", "crunk") + testutil.Setenv(t, "FOO_ID", "13") + testutil.Setenv(t, "FOOD", "apple") + testutil.Setenv(t, "FOO_NAME", "crunk") assert.Equal(t, "13", Get("id")) assert.Equal(t, "apple", Get("f")) @@ -573,7 +564,9 @@ func TestAutoEnv(t *testing.T) { Reset() AutomaticEnv() - os.Setenv("FOO_BAR", "13") + + testutil.Setenv(t, "FOO_BAR", "13") + assert.Equal(t, "13", Get("foo_bar")) } @@ -582,7 +575,9 @@ func TestAutoEnvWithPrefix(t *testing.T) { AutomaticEnv() SetEnvPrefix("Baz") - os.Setenv("BAZ_BAR", "13") + + testutil.Setenv(t, "BAZ_BAR", "13") + assert.Equal(t, "13", Get("bar")) } @@ -590,7 +585,8 @@ func TestSetEnvKeyReplacer(t *testing.T) { Reset() AutomaticEnv() - os.Setenv("REFRESH_INTERVAL", "30s") + + testutil.Setenv(t, "REFRESH_INTERVAL", "30s") replacer := strings.NewReplacer("-", "_") SetEnvKeyReplacer(replacer) @@ -602,7 +598,8 @@ func TestEnvKeyReplacer(t *testing.T) { v := NewWithOptions(EnvKeyReplacer(strings.NewReplacer("-", "_"))) v.AutomaticEnv() - _ = os.Setenv("REFRESH_INTERVAL", "30s") + + testutil.Setenv(t, "REFRESH_INTERVAL", "30s") assert.Equal(t, "30s", v.Get("refresh-interval")) } @@ -729,8 +726,9 @@ func TestAllKeysWithEnv(t *testing.T) { v.BindEnv("id") v.BindEnv("foo.bar") v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) - os.Setenv("ID", "13") - os.Setenv("FOO_BAR", "baz") + + testutil.Setenv(t, "ID", "13") + testutil.Setenv(t, "FOO_BAR", "baz") expectedKeys := sort.StringSlice{"id", "foo.bar"} expectedKeys.Sort() @@ -1038,7 +1036,8 @@ func TestBoundCaseSensitivity(t *testing.T) { assert.Equal(t, "brown", Get("eyes")) BindEnv("eYEs", "TURTLE_EYES") - os.Setenv("TURTLE_EYES", "blue") + + testutil.Setenv(t, "TURTLE_EYES", "blue") assert.Equal(t, "blue", Get("eyes")) @@ -1219,8 +1218,9 @@ func TestIsSet(t *testing.T) { v.BindEnv("foo") v.BindEnv("clothing.hat") v.BindEnv("clothing.hats") - os.Setenv("FOO", "bar") - os.Setenv("CLOTHING_HAT", "bowler") + + testutil.Setenv(t, "FOO", "bar") + testutil.Setenv(t, "CLOTHING_HAT", "bowler") assert.True(t, v.IsSet("eyes")) // in the config file assert.True(t, v.IsSet("foo")) // in the environment