package configuration import ( "reflect" "testing" "github.com/stretchr/testify/require" ) type localConfiguration struct { Version Version `yaml:"version"` Log *Log `yaml:"log"` Notifications []Notif `yaml:"notifications,omitempty"` Inlined Inlined `yaml:",inline"` } type Notif struct { Name string `yaml:"name"` } type Inlined struct { FirstValue string `yaml:"firstValue"` SecondValue string `yaml:"secondValue"` } var expectedConfig = localConfiguration{ Version: "0.1", Log: &Log{ Formatter: "json", }, Notifications: []Notif{ {Name: "foo"}, {Name: "bar"}, {Name: "car"}, }, } const testConfig = `version: "0.1" log: formatter: "text" notifications: - name: "foo" - name: "bar" - name: "car"` func TestParserOverwriteIninitializedPoiner(t *testing.T) { config := localConfiguration{} t.Setenv("REGISTRY_LOG_FORMATTER", "json") p := NewParser("registry", []VersionedParseInfo{ { Version: "0.1", ParseAs: reflect.TypeFor[localConfiguration](), ConversionFunc: func(c any) (any, error) { return c, nil }, }, }) err := p.Parse([]byte(testConfig), &config) require.NoError(t, err) require.Equal(t, expectedConfig, config) } const testConfig2 = `version: "0.1" log: formatter: "text" notifications: - name: "val1" - name: "val2" - name: "car"` func TestParseOverwriteUnininitializedPoiner(t *testing.T) { config := localConfiguration{} t.Setenv("REGISTRY_LOG_FORMATTER", "json") // override only first two notificationsvalues // in the tetConfig: leave the last value unchanged. t.Setenv("REGISTRY_NOTIFICATIONS_0_NAME", "foo") t.Setenv("REGISTRY_NOTIFICATIONS_1_NAME", "bar") p := NewParser("registry", []VersionedParseInfo{ { Version: "0.1", ParseAs: reflect.TypeFor[localConfiguration](), ConversionFunc: func(c any) (any, error) { return c, nil }, }, }) err := p.Parse([]byte(testConfig2), &config) require.NoError(t, err) require.Equal(t, expectedConfig, config) } const testConfig3 = `version: "0.1" log: formatter: "text"` func TestParseInlinedStruct(t *testing.T) { config := localConfiguration{} expected := localConfiguration{ Version: "0.1", Log: &Log{ Formatter: "text", }, Inlined: Inlined{ FirstValue: "foo", SecondValue: "bar", }, } // Test without inlined struct name in the env variable name t.Setenv("REGISTRY_FIRSTVALUE", "foo") // Test with the inlined struct name in the env variable name, for backward compatibility t.Setenv("REGISTRY_INLINED_SECONDVALUE", "bar") p := NewParser("registry", []VersionedParseInfo{ { Version: "0.1", ParseAs: reflect.TypeFor[localConfiguration](), ConversionFunc: func(c any) (any, error) { return c, nil }, }, }) err := p.Parse([]byte(testConfig3), &config) require.NoError(t, err) require.Equal(t, expected, config) }