|
1 | 1 | package config |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "os" |
| 5 | + "path/filepath" |
4 | 6 | "testing" |
5 | 7 |
|
6 | 8 | "github.com/stretchr/testify/assert" |
@@ -84,3 +86,124 @@ func TestResolveTagsComplex(t *testing.T) { |
84 | 86 | assert.Len(t, testData.GmdDataMap1, 3) |
85 | 87 | assert.Len(t, testData.GmdDataMap2, 4) |
86 | 88 | } |
| 89 | + |
| 90 | +func TestLoadFromEnvironmentNonPointer(t *testing.T) { |
| 91 | + type Cfg struct { |
| 92 | + Val string `env:"name=X"` |
| 93 | + } |
| 94 | + err := LoadFromEnvironment(Cfg{}) |
| 95 | + require.Error(t, err) |
| 96 | + assert.Contains(t, err.Error(), "pointer") |
| 97 | +} |
| 98 | + |
| 99 | +func TestLoadFromEnvironmentBoolField(t *testing.T) { |
| 100 | + type Cfg struct { |
| 101 | + Flag bool `env:"name=BOOL_CFG"` |
| 102 | + } |
| 103 | + t.Setenv("BOOL_CFG", "true") |
| 104 | + |
| 105 | + var cfg Cfg |
| 106 | + err := LoadFromEnvironment(&cfg) |
| 107 | + require.NoError(t, err) |
| 108 | + assert.True(t, cfg.Flag) |
| 109 | +} |
| 110 | + |
| 111 | +type unexportedFieldConfig struct { |
| 112 | + Public string `env:"name=PUB_VAL"` |
| 113 | + private string `env:"name=PRIV_VAL"` //nolint:unused // test for unexported field handling |
| 114 | +} |
| 115 | + |
| 116 | +func TestLoadFromEnvironmentUnexportedField(t *testing.T) { |
| 117 | + t.Setenv("PUB_VAL", "public") |
| 118 | + t.Setenv("PRIV_VAL", "private") |
| 119 | + |
| 120 | + cfg := unexportedFieldConfig{} |
| 121 | + err := LoadFromEnvironment(&cfg) |
| 122 | + require.NoError(t, err) |
| 123 | + assert.Equal(t, "public", cfg.Public) |
| 124 | + // private field should not be set (unexported) |
| 125 | +} |
| 126 | + |
| 127 | +func TestLoadFromEnvironmentNoTags(t *testing.T) { |
| 128 | + type Cfg struct { |
| 129 | + Value string |
| 130 | + } |
| 131 | + cfg := Cfg{Value: "original"} |
| 132 | + err := LoadFromEnvironment(&cfg) |
| 133 | + require.NoError(t, err) |
| 134 | + assert.Equal(t, "original", cfg.Value, "fields without env tag should not be modified") |
| 135 | +} |
| 136 | + |
| 137 | +func TestLoadFromFileYaml(t *testing.T) { |
| 138 | + type FileCfg struct { |
| 139 | + Host string `yaml:"host" env:"name=YAML_FILE_HOST"` |
| 140 | + Port int `yaml:"port" env:"name=YAML_FILE_PORT"` |
| 141 | + } |
| 142 | + content := ` |
| 143 | +host: filehost |
| 144 | +port: 3000 |
| 145 | +` |
| 146 | + path := createTempConfigFile(t, "config.yaml", content) |
| 147 | + |
| 148 | + // Set env vars to match file values so LoadFromEnvironment doesn't overwrite |
| 149 | + t.Setenv("YAML_FILE_HOST", "filehost") |
| 150 | + t.Setenv("YAML_FILE_PORT", "3000") |
| 151 | + |
| 152 | + var cfg FileCfg |
| 153 | + err := LoadFromFile(path, &cfg, YAML) |
| 154 | + require.NoError(t, err) |
| 155 | + assert.Equal(t, "filehost", cfg.Host) |
| 156 | + assert.Equal(t, 3000, cfg.Port) |
| 157 | +} |
| 158 | + |
| 159 | +func TestLoadFromFileJson(t *testing.T) { |
| 160 | + type FileCfg struct { |
| 161 | + Host string `json:"host" env:"name=JSON_FILE_HOST"` |
| 162 | + Port int `json:"port" env:"name=JSON_FILE_PORT"` |
| 163 | + } |
| 164 | + content := `{"host":"jsonhost","port":4000}` |
| 165 | + path := createTempConfigFile(t, "config.json", content) |
| 166 | + |
| 167 | + t.Setenv("JSON_FILE_HOST", "jsonhost") |
| 168 | + t.Setenv("JSON_FILE_PORT", "4000") |
| 169 | + |
| 170 | + var cfg FileCfg |
| 171 | + err := LoadFromFile(path, &cfg, JSON) |
| 172 | + require.NoError(t, err) |
| 173 | + assert.Equal(t, "jsonhost", cfg.Host) |
| 174 | + assert.Equal(t, 4000, cfg.Port) |
| 175 | +} |
| 176 | + |
| 177 | +func TestLoadFromFileNotFound(t *testing.T) { |
| 178 | + type Cfg struct { |
| 179 | + Val string `env:"name=X"` |
| 180 | + } |
| 181 | + var cfg Cfg |
| 182 | + err := LoadFromFile("/nonexistent/config.yaml", &cfg, YAML) |
| 183 | + require.Error(t, err) |
| 184 | +} |
| 185 | + |
| 186 | +func TestLoadFromFileEnvOverride(t *testing.T) { |
| 187 | + type FileCfg struct { |
| 188 | + Host string `yaml:"host" env:"name=OVERRIDE_HOST"` |
| 189 | + } |
| 190 | + content := `host: fromfile` |
| 191 | + path := createTempConfigFile(t, "config.yaml", content) |
| 192 | + |
| 193 | + t.Setenv("OVERRIDE_HOST", "fromenv") |
| 194 | + |
| 195 | + var cfg FileCfg |
| 196 | + err := LoadFromFile(path, &cfg, YAML) |
| 197 | + require.NoError(t, err) |
| 198 | + // Environment should override file value |
| 199 | + assert.Equal(t, "fromenv", cfg.Host) |
| 200 | +} |
| 201 | + |
| 202 | +func createTempConfigFile(t *testing.T, name, content string) string { |
| 203 | + t.Helper() |
| 204 | + dir := t.TempDir() |
| 205 | + path := filepath.Join(dir, name) |
| 206 | + err := os.WriteFile(path, []byte(content), 0600) |
| 207 | + require.NoError(t, err) |
| 208 | + return path |
| 209 | +} |
0 commit comments