Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions mergevalues.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,17 @@ func MergeValues(a, b *Value) (v *Value, changed bool, err error) {
if b == nil {
return a, false, nil
}
if b.Type() == TypeNull && a.Type() == TypeObject {
// we assume that null was returned in an error case for resolving a nested object field
// as we've got an object on the left side, we don't override the whole object with null
// instead, we keep the left object and discard the null on the right side
return a, false, nil
}
aBool, bBool := a.Type() == TypeTrue || a.Type() == TypeFalse, b.Type() == TypeTrue || b.Type() == TypeFalse
booleans := aBool && bBool
oneIsNull := a.Type() == TypeNull || b.Type() == TypeNull
if a.Type() != b.Type() && !booleans && !oneIsNull {
if a.Type() != b.Type() && !booleans {
return nil, false, ErrMergeDifferentTypes
}
if b.Type() == TypeNull && a.Type() != TypeNull {
return b, true, nil
}
switch a.Type() {
case TypeObject:
ao, _ := a.Object()
Expand Down
45 changes: 25 additions & 20 deletions mergevalues_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,20 +183,14 @@ func TestMergeValues(t *testing.T) {
t.Run("null not null", func(t *testing.T) {
t.Parallel()
a, b := MustParse(`null`), MustParse(`1`)
merged, changed, err := MergeValues(a, b)
require.NoError(t, err)
require.Equal(t, true, changed)
out := merged.MarshalTo(nil)
require.Equal(t, `1`, string(out))
_, _, err := MergeValues(a, b)
require.Error(t, err)
})
t.Run("null not null reverse", func(t *testing.T) {
t.Parallel()
a, b := MustParse(`1`), MustParse(`null`)
merged, changed, err := MergeValues(a, b)
require.NoError(t, err)
require.Equal(t, true, changed)
out := merged.MarshalTo(nil)
require.Equal(t, `null`, string(out))
_, _, err := MergeValues(a, b)
require.Error(t, err)
})
t.Run("array objects", func(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -272,32 +266,43 @@ func TestMergeValues(t *testing.T) {
t.Parallel()
left := MustParse(`null`)
right := MustParse(`true`)
out, _, err := MergeValues(left, right)
require.NoError(t, err)
require.Equal(t, `true`, out.String())
_, _, err := MergeValues(left, right)
require.Error(t, err)
})
t.Run("true null", func(t *testing.T) {
t.Parallel()
left := MustParse(`true`)
right := MustParse(`null`)
out, _, err := MergeValues(left, right)
require.NoError(t, err)
require.Equal(t, `null`, out.String())
_, _, err := MergeValues(left, right)
require.Error(t, err)
})
t.Run("nested null true", func(t *testing.T) {
t.Parallel()
left := MustParse(`{"a":null}`)
right := MustParse(`{"a":true}`)
out, _, err := MergeValues(left, right)
require.NoError(t, err)
require.Equal(t, `{"a":true}`, out.String())
_, _, err := MergeValues(left, right)
require.Error(t, err)
})
t.Run("nested true null", func(t *testing.T) {
t.Parallel()
left := MustParse(`{"a":true}`)
right := MustParse(`{"a":null}`)
_, _, err := MergeValues(left, right)
require.Error(t, err)
})
t.Run("nested null into nested object", func(t *testing.T) {
t.Parallel()
left := MustParse(`{"a":{"b":"c"}}`)
right := MustParse(`{"a":null}`)
out, _, err := MergeValues(left, right)
require.NoError(t, err)
require.Equal(t, `{"a":null}`, out.String())
require.Equal(t, `{"a":{"b":"c"}}`, out.String())
})
t.Run("nested object into nested null", func(t *testing.T) {
t.Parallel()
left := MustParse(`{"a":null}`)
right := MustParse(`{"a":{"b":"c"}}`)
_, _, err := MergeValues(left, right)
require.Error(t, err)
})
}
Loading