Skip to content

Commit 2a1aada

Browse files
committed
Fix order for merging iterator
Consider the following YAML: trait1: &t1 foo: 1 trait2: &t2 foo: 2 merged: <<: *t1 <<: *t2 yq reports: $ yq .merged.foo < /tmp/yaml 2 while the order that yaml-cpp returns is different, since it will firstly handle 1, and will not replace it with 2: $ util/parse < /tmp/yaml trait1: ? &1 foo : &2 1 trait2: foo: 2 merged: *1 : *2 (Don't mix up "*2" with "2", it is trait1)
1 parent eef68f3 commit 2a1aada

File tree

2 files changed

+21
-3
lines changed

2 files changed

+21
-3
lines changed

src/nodebuilder.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,9 @@ void NodeBuilder::OnMapEnd() {
9797
assert(m_mapDepth > 0);
9898
detail::node& collection = *m_stack.back();
9999
auto& toMerge = *m_mergeDicts.rbegin();
100-
for (detail::node* n : toMerge) {
101-
MergeMapCollection(collection, *n, m_pMemory);
100+
/// The elements for merging should be traversed in reverse order to prefer last values.
101+
for (auto it = toMerge.rbegin(); it != toMerge.rend(); ++it) {
102+
MergeMapCollection(collection, **it, m_pMemory);
102103
}
103104
m_mapDepth--;
104105
m_mergeDicts.pop_back();

test/integration/load_node_test.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,23 @@ TEST(LoadNodeTest, MergeKeyAIterator) {
199199
ASSERT_EQ(z_b_keys, 1);
200200
}
201201

202+
TEST(LoadNodeTest, MergeKeyTwoOverrides) {
203+
Node node = Load(R"(
204+
trait1: &t1
205+
foo: 1
206+
207+
trait2: &t2
208+
foo: 2
209+
210+
merged:
211+
<<: *t1
212+
<<: *t2
213+
)");
214+
EXPECT_EQ(NodeType::Map, node["merged"].Type());
215+
EXPECT_FALSE(node["merged"]["<<"]);
216+
EXPECT_EQ(2, node["merged"]["foo"].as<int>());
217+
}
218+
202219
TEST(LoadNodeTest, MergeKeyB) {
203220
Node node = Load(
204221
"{x: &foo {a : 1,b : 1,c : 1}, y: &bar {d: 2, e : 2, f : 2, a : 2}, z: "
@@ -211,7 +228,7 @@ TEST(LoadNodeTest, MergeKeyB) {
211228
EXPECT_EQ(3, node["z"]["b"].as<int>());
212229
EXPECT_EQ(1, node["z"]["c"].as<int>());
213230

214-
EXPECT_EQ(1, node["w"]["a"].as<int>());
231+
EXPECT_EQ(2, node["w"]["a"].as<int>());
215232
EXPECT_EQ(3, node["w"]["b"].as<int>());
216233
EXPECT_EQ(4, node["w"]["c"].as<int>());
217234
EXPECT_EQ(2, node["w"]["d"].as<int>());

0 commit comments

Comments
 (0)