(t *testing.T)
| 965 | } |
| 966 | |
| 967 | func TestUnmarshalWithAutomaticEnv(t *testing.T) { |
| 968 | t.Setenv("PORT", "1313") |
| 969 | t.Setenv("NAME", "Steve") |
| 970 | t.Setenv("DURATION", "1s1ms") |
| 971 | t.Setenv("MODES", "1,2,3") |
| 972 | t.Setenv("SECRET", "42") |
| 973 | t.Setenv("FILESYSTEM_SIZE", "4096") |
| 974 | |
| 975 | type AuthConfig struct { |
| 976 | Secret string `mapstructure:"secret"` |
| 977 | } |
| 978 | |
| 979 | type StorageConfig struct { |
| 980 | Size int `mapstructure:"size"` |
| 981 | } |
| 982 | |
| 983 | type Configuration struct { |
| 984 | Port int `mapstructure:"port"` |
| 985 | Name string `mapstructure:"name"` |
| 986 | Duration time.Duration `mapstructure:"duration"` |
| 987 | |
| 988 | // Infer name from struct |
| 989 | Modes []int |
| 990 | |
| 991 | // Squash nested struct (omit prefix) |
| 992 | Authentication AuthConfig `mapstructure:",squash"` |
| 993 | |
| 994 | // Different key |
| 995 | Storage StorageConfig `mapstructure:"filesystem"` |
| 996 | |
| 997 | // Omitted field |
| 998 | Flag bool `mapstructure:"flag"` |
| 999 | } |
| 1000 | |
| 1001 | v := NewWithOptions(ExperimentalBindStruct()) |
| 1002 | v.SetEnvKeyReplacer(strings.NewReplacer(".", "_")) |
| 1003 | v.AutomaticEnv() |
| 1004 | |
| 1005 | t.Run("OK", func(t *testing.T) { |
| 1006 | var config Configuration |
| 1007 | if err := v.Unmarshal(&config); err != nil { |
| 1008 | t.Fatalf("unable to decode into struct, %v", err) |
| 1009 | } |
| 1010 | |
| 1011 | assert.Equal( |
| 1012 | t, |
| 1013 | Configuration{ |
| 1014 | Name: "Steve", |
| 1015 | Port: 1313, |
| 1016 | Duration: time.Second + time.Millisecond, |
| 1017 | Modes: []int{1, 2, 3}, |
| 1018 | Authentication: AuthConfig{ |
| 1019 | Secret: "42", |
| 1020 | }, |
| 1021 | Storage: StorageConfig{ |
| 1022 | Size: 4096, |
| 1023 | }, |
| 1024 | }, |
nothing calls this directly
no test coverage detected