Skip to content

Commit 86ff133

Browse files
committed
test: add additional unit tests for all modules
1 parent 8210256 commit 86ff133

11 files changed

Lines changed: 1100 additions & 6 deletions

File tree

config/config_test.go

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package config
22

33
import (
4+
"os"
5+
"path/filepath"
46
"testing"
57

68
"github.com/stretchr/testify/assert"
@@ -84,3 +86,124 @@ func TestResolveTagsComplex(t *testing.T) {
8486
assert.Len(t, testData.GmdDataMap1, 3)
8587
assert.Len(t, testData.GmdDataMap2, 4)
8688
}
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+
}

config/formats/formats_test.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package formats
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"testing"
7+
8+
"github.com/stretchr/testify/assert"
9+
"github.com/stretchr/testify/require"
10+
)
11+
12+
type testConfig struct {
13+
Name string `yaml:"name" json:"name"`
14+
Port int `yaml:"port" json:"port"`
15+
}
16+
17+
func createTempFile(t *testing.T, filename, content string) string {
18+
t.Helper()
19+
dir := t.TempDir()
20+
path := filepath.Join(dir, filename)
21+
err := os.WriteFile(path, []byte(content), 0600)
22+
require.NoError(t, err)
23+
return path
24+
}
25+
26+
func TestParseYamlConfig(t *testing.T) {
27+
path := createTempFile(t, "config.yaml", `
28+
name: testapp
29+
port: 8080
30+
`)
31+
var cfg testConfig
32+
err := ParseYamlConfig(path, &cfg)
33+
require.NoError(t, err)
34+
assert.Equal(t, "testapp", cfg.Name)
35+
assert.Equal(t, 8080, cfg.Port)
36+
}
37+
38+
func TestParseJsonConfig(t *testing.T) {
39+
path := createTempFile(t, "config.json", `{"name":"jsonapp","port":9090}`)
40+
41+
var cfg testConfig
42+
err := ParseJsonConfig(path, &cfg)
43+
require.NoError(t, err)
44+
assert.Equal(t, "jsonapp", cfg.Name)
45+
assert.Equal(t, 9090, cfg.Port)
46+
}
47+
48+
func TestParseConfigWithCustomParser(t *testing.T) {
49+
path := createTempFile(t, "config.yaml", `
50+
name: custom
51+
port: 3000
52+
`)
53+
var cfg testConfig
54+
err := ParseConfig(path, &cfg, func(in []byte, out any) error {
55+
// Use yaml under the hood
56+
return ParseYamlConfig(path, out)
57+
})
58+
// ParseConfig calls parseConfig which calls loadConfigFile and then the parser
59+
// The custom parser here re-reads via ParseYamlConfig, but that's fine for testing
60+
require.NoError(t, err)
61+
assert.Equal(t, "custom", cfg.Name)
62+
}
63+
64+
func TestParseYamlConfigFileNotFound(t *testing.T) {
65+
var cfg testConfig
66+
err := ParseYamlConfig("/nonexistent/path/config.yaml", &cfg)
67+
require.Error(t, err)
68+
assert.Contains(t, err.Error(), "reading config file")
69+
}
70+
71+
func TestParseJsonConfigFileNotFound(t *testing.T) {
72+
var cfg testConfig
73+
err := ParseJsonConfig("/nonexistent/path/config.json", &cfg)
74+
require.Error(t, err)
75+
assert.Contains(t, err.Error(), "reading config file")
76+
}
77+
78+
func TestParseYamlConfigInvalidContent(t *testing.T) {
79+
path := createTempFile(t, "bad.yaml", `{{{invalid yaml`)
80+
81+
var cfg testConfig
82+
err := ParseYamlConfig(path, &cfg)
83+
require.Error(t, err)
84+
}
85+
86+
func TestParseJsonConfigInvalidContent(t *testing.T) {
87+
path := createTempFile(t, "bad.json", `{not json`)
88+
89+
var cfg testConfig
90+
err := ParseJsonConfig(path, &cfg)
91+
require.Error(t, err)
92+
}

0 commit comments

Comments
 (0)