Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Questionable mapping node merge behavior #81

Open
bjaglin opened this issue Feb 15, 2015 · 0 comments
Open

Questionable mapping node merge behavior #81

bjaglin opened this issue Feb 15, 2015 · 0 comments

Comments

@bjaglin
Copy link

bjaglin commented Feb 15, 2015

It seems that the interpretation of the specification for merge is different than other parsers (PyYAML, JS-YAML, SnakeYAML), and in my opinion incorrect (although I do happen to rely on it for some "features").

I have found that when merging a single mapping node into a target mapping, values for keys that are present in that source mapping and had previously been declared in the target mapping are overriding the existing ones. Other parsers' interpretation of the spec is that values in the source mapping should be completely ignored:

If the value associated with the key is a single mapping node, each of its key/value pairs is inserted into the current mapping, unless the key already exists in it

I ran into this when bumping from v1 to v2, which resulted in a slightly changed behavior when the source value is a mapping but not the target one (in that particular case, going in the direction of other parsers' interpretation, but breaking a behavior I had taken for granted).

Tests exhibiting the current v2 behavior against the expected one are available at bjaglin@3697451:

anchors:
  list:
    - &FOO { empty: notreally, flat: false, nested: { foo: merged } }

# All the following maps should be equal:

plain:
  empty:
  flat: true
  nested:
    foo: foo
    bar: bar

mergeBefore:
  << : *FOO
  empty:
  flat: true
  nested:
    foo: foo
    bar: bar

mergeAfter:
  empty:
  flat: true
  nested:
    foo: foo
    bar: bar
  << : *FOO
----------------------------------------------------------------------
FAIL: decode_test.go:935: S.TestMergeMap

decode_test.go:949:
    c.Assert(test, DeepEquals, want, Commentf("test %q failed", name))
... obtained map[interface {}]interface {} = map[interface {}]interface {}{"empty":"notreally", "flat":false, "nested":map[interface {}]interface {}{"foo":"merged"}}
... expected map[interface {}]interface {} = map[interface {}]interface {}{"empty":interface {}(nil), "flat":true, "nested":map[interface {}]interface {}{"foo":"foo", "bar":"bar"}}
... test "mergeAfter" failed


----------------------------------------------------------------------
FAIL: decode_test.go:953: S.TestMergeMapStruct

decode_test.go:971:
    c.Assert(test, Equals, want, Commentf("test %q failed", name))
... obtained yaml_test.Data = yaml_test.Data{Flat:false, Nested:yaml_test.Nested{Foo:"merged", Bar:"bar"}}
... expected yaml_test.Data = yaml_test.Data{Flat:true, Nested:yaml_test.Nested{Foo:"foo", Bar:"bar"}}
... test "mergeAfter" failed

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant