Skip to content

Commit

Permalink
fix: inherit issue when parent after inherits (#2586)
Browse files Browse the repository at this point in the history
* fix: inherit issue when parent after inherits

* chore: add more tests
  • Loading branch information
kevwan committed Nov 10, 2022
1 parent 4b071f4 commit e3e08a7
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 12 deletions.
91 changes: 91 additions & 0 deletions core/mapping/unmarshaler_test.go
Expand Up @@ -2991,6 +2991,97 @@ func TestUnmarshaler_InheritFromGrandparent(t *testing.T) {
assert.Equal(t, "localhost:8080", s.Middle.Value.Discovery)
}

func TestUnmarshaler_InheritSequence(t *testing.T) {
var testConf = []byte(`
Nacos:
NamespaceId: "123"
RpcConf:
Nacos:
NamespaceId: "456"
Name: hello
`)

type (
NacosConf struct {
NamespaceId string
}

RpcConf struct {
Nacos NacosConf `json:",inherit"`
Name string
}

Config1 struct {
RpcConf RpcConf
Nacos NacosConf
}

Config2 struct {
RpcConf RpcConf
Nacos NacosConf
}
)

var c1 Config1
assert.NoError(t, UnmarshalYamlBytes(testConf, &c1))
assert.Equal(t, "123", c1.Nacos.NamespaceId)
assert.Equal(t, "456", c1.RpcConf.Nacos.NamespaceId)

var c2 Config2
assert.NoError(t, UnmarshalYamlBytes(testConf, &c2))
assert.Equal(t, "123", c1.Nacos.NamespaceId)
assert.Equal(t, "456", c1.RpcConf.Nacos.NamespaceId)
}

func TestUnmarshaler_InheritNested(t *testing.T) {
var testConf = []byte(`
Nacos:
Value1: "123"
Server:
Nacos:
Value2: "456"
Rpc:
Nacos:
Value3: "789"
Name: hello
`)

type (
NacosConf struct {
Value1 string `json:",optional"`
Value2 string `json:",optional"`
Value3 string `json:",optional"`
}

RpcConf struct {
Nacos NacosConf `json:",inherit"`
Name string
}

ServerConf struct {
Nacos NacosConf `json:",inherit"`
Rpc RpcConf
}

Config struct {
Server ServerConf
Nacos NacosConf
}
)

var c Config
assert.NoError(t, UnmarshalYamlBytes(testConf, &c))
assert.Equal(t, "123", c.Nacos.Value1)
assert.Empty(t, c.Nacos.Value2)
assert.Empty(t, c.Nacos.Value3)
assert.Equal(t, "123", c.Server.Nacos.Value1)
assert.Equal(t, "456", c.Server.Nacos.Value2)
assert.Empty(t, c.Nacos.Value3)
assert.Equal(t, "123", c.Server.Rpc.Nacos.Value1)
assert.Equal(t, "456", c.Server.Rpc.Nacos.Value2)
assert.Equal(t, "789", c.Server.Rpc.Nacos.Value3)
}

func TestUnmarshalValuer(t *testing.T) {
unmarshaler := NewUnmarshaler(jsonTagKey)
var foo string
Expand Down
36 changes: 24 additions & 12 deletions core/mapping/valuer.go
Expand Up @@ -70,21 +70,33 @@ func (rv recursiveValuer) Value(key string) (interface{}, bool) {
return nil, false
}

if vm, ok := val.(map[string]interface{}); ok {
if parent := rv.Parent(); parent != nil {
pv, pok := parent.Value(key)
if pok {
if pm, ok := pv.(map[string]interface{}); ok {
for k, v := range vm {
pm[k] = v
}
return pm, true
}
}
vm, ok := val.(map[string]interface{})
if !ok {
return val, true
}

parent := rv.Parent()
if parent == nil {
return val, true
}

pv, ok := parent.Value(key)
if !ok {
return val, true
}

pm, ok := pv.(map[string]interface{})
if !ok {
return val, true
}

for k, v := range pm {
if _, ok := vm[k]; !ok {
vm[k] = v
}
}

return val, true
return vm, true
}

// Parent get the parent valuer from rv.
Expand Down

0 comments on commit e3e08a7

Please sign in to comment.