Fix the code and update tests that verify the new code works

Signed-off-by: Milos Gajdos <milosthegajdos@gmail.com>
This commit is contained in:
Milos Gajdos 2023-07-17 22:40:32 +01:00
parent 916b94eb3a
commit 0cf87b1fd1
No known key found for this signature in database
GPG key ID: 01300E5E6D417439
2 changed files with 47 additions and 6 deletions

View file

@ -172,10 +172,18 @@ func (p *Parser) overwriteFields(v reflect.Value, fullpath string, path []string
panic("non-numeric index: " + path[0]) panic("non-numeric index: " + path[0])
} }
if idx >= v.Len() { if idx > v.Len() {
panic("Undefined index: " + path[0]) panic("undefined index: " + path[0])
} }
// if there is no element or the current slice length
// is the same as the indexed variable create a new element,
// append it and then set it to the passed in env var value.
if v.Len() == 0 || idx == v.Len() {
typ := v.Type().Elem()
elem := reflect.New(typ).Elem()
v.Set(reflect.Append(v, elem))
}
return p.overwriteFields(v.Index(idx), fullpath, path[1:], payload) return p.overwriteFields(v.Index(idx), fullpath, path[1:], payload)
case reflect.Interface: case reflect.Interface:
if v.NumMethod() == 0 { if v.NumMethod() == 0 {

View file

@ -8,21 +8,39 @@ import (
) )
type localConfiguration struct { type localConfiguration struct {
Version Version `yaml:"version"` Version Version `yaml:"version"`
Log *Log `yaml:"log"` Log *Log `yaml:"log"`
Notifications []Notif `yaml:"notifications,omitempty"`
} }
type Log struct { type Log struct {
Formatter string `yaml:"formatter,omitempty"` Formatter string `yaml:"formatter,omitempty"`
} }
type Notif struct {
Name string `yaml:"name"`
}
var expectedConfig = localConfiguration{ var expectedConfig = localConfiguration{
Version: "0.1", Version: "0.1",
Log: &Log{ Log: &Log{
Formatter: "json", 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"`
type ParserSuite struct{} type ParserSuite struct{}
var _ = check.Suite(new(ParserSuite)) var _ = check.Suite(new(ParserSuite))
@ -43,17 +61,32 @@ func (suite *ParserSuite) TestParserOverwriteIninitializedPoiner(c *check.C) {
}, },
}) })
err := p.Parse([]byte(`{version: "0.1", log: {formatter: "text"}}`), &config) err := p.Parse([]byte(testConfig), &config)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(config, check.DeepEquals, expectedConfig) c.Assert(config, check.DeepEquals, expectedConfig)
} }
const testConfig2 = `version: "0.1"
log:
formatter: "text"
notifications:
- name: "val1"
- name: "val2"
- name: "car"`
func (suite *ParserSuite) TestParseOverwriteUnininitializedPoiner(c *check.C) { func (suite *ParserSuite) TestParseOverwriteUnininitializedPoiner(c *check.C) {
config := localConfiguration{} config := localConfiguration{}
os.Setenv("REGISTRY_LOG_FORMATTER", "json") os.Setenv("REGISTRY_LOG_FORMATTER", "json")
defer os.Unsetenv("REGISTRY_LOG_FORMATTER") defer os.Unsetenv("REGISTRY_LOG_FORMATTER")
// override only first two notificationsvalues
// in the tetConfig: leave the last value unchanged.
os.Setenv("REGISTRY_NOTIFICATIONS_0_NAME", "foo")
defer os.Unsetenv("REGISTRY_NOTIFICATIONS_0_NAME")
os.Setenv("REGISTRY_NOTIFICATIONS_1_NAME", "bar")
defer os.Unsetenv("REGISTRY_NOTIFICATIONS_1_NAME")
p := NewParser("registry", []VersionedParseInfo{ p := NewParser("registry", []VersionedParseInfo{
{ {
Version: "0.1", Version: "0.1",
@ -64,7 +97,7 @@ func (suite *ParserSuite) TestParseOverwriteUnininitializedPoiner(c *check.C) {
}, },
}) })
err := p.Parse([]byte(`{version: "0.1"}`), &config) err := p.Parse([]byte(testConfig2), &config)
c.Assert(err, check.IsNil) c.Assert(err, check.IsNil)
c.Assert(config, check.DeepEquals, expectedConfig) c.Assert(config, check.DeepEquals, expectedConfig)
} }