Skip to content

Commit a735df9

Browse files
committed
references: fix merge key order for edge case where target is the last element
re #484
1 parent 9fe025b commit a735df9

4 files changed

Lines changed: 117 additions & 3 deletions

File tree

changelog/current.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11

2-
## Fixes
2+
### Fixes
33

44
- Fix [#400](https://github.com/biojppm/rapidyaml/issues/400) ([PR#506](https://github.com/biojppm/rapidyaml/pull/506)): clear anchors after resolving.
5+
- Fix [#484](https://github.com/biojppm/rapidyaml/issues/484) ([PR#506](https://github.com/biojppm/rapidyaml/pull/506)): fix merge key order for last element to be overriden.
56
- [PR#503](https://github.com/biojppm/rapidyaml/pull/503): ensure parse error on `a: b: c` and similar cases containing nested maps opening on the same line.
67
- [PR#502](https://github.com/biojppm/rapidyaml/pull/502): fix parse errors or missing tags:
78
- missing tags in empty documents:

src/c4/yml/tree.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1014,11 +1014,13 @@ id_type Tree::duplicate_children_no_rep(Tree const *src, id_type node, id_type p
10141014
}
10151015
else // yes, there is a repetition
10161016
{
1017-
if(after_pos != NONE && dstnode_dup_pos < after_pos)
1017+
if(after_pos != NONE && dstnode_dup_pos <= after_pos)
10181018
{
10191019
// the dst duplicate is located before the node which will be inserted,
10201020
// and will be overridden by the duplicate. So replace it.
10211021
_c4dbgpf("duplicate_no_dstnode_dup: replace {}/{} with {}/{}", parent, dstnode_dup, node, i);
1022+
if(prev == dstnode_dup)
1023+
prev = prev_sibling(dstnode_dup);
10221024
remove(dstnode_dup);
10231025
prev = duplicate(src, i, parent, prev);
10241026
}

test/test_anchor.cpp

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,84 @@ a5: &a5
730730
}
731731
}
732732

733+
TEST(simple_anchor, issue_484_0)
734+
{
735+
csubstr yaml = R"(
736+
base_1: &base_1
737+
a: 10
738+
b: 10
739+
base_2: &base_2
740+
b: 20
741+
k1:
742+
!!merge <<: *base_1
743+
!!merge <<: *base_2
744+
k2:
745+
!!merge <<: *base_2
746+
!!merge <<: *base_1
747+
)";
748+
Tree t = parse_in_arena(yaml);
749+
EXPECT_EQ(t["k1"][0].val(), "*base_1");
750+
EXPECT_EQ(t["k1"][1].val(), "*base_2");
751+
EXPECT_EQ(t["k2"][0].val(), "*base_2");
752+
EXPECT_EQ(t["k2"][1].val(), "*base_1");
753+
t.resolve();
754+
EXPECT_EQ(t["k1"]["a"].val(), "10");
755+
EXPECT_EQ(t["k1"]["b"].val(), "20");
756+
EXPECT_EQ(t["k2"]["a"].val(), "10");
757+
EXPECT_EQ(t["k2"]["b"].val(), "10");
758+
EXPECT_EQ(emitrs_yaml<std::string>(t), R"(base_1:
759+
a: 10
760+
b: 10
761+
base_2:
762+
b: 20
763+
k1:
764+
a: 10
765+
b: 20
766+
k2:
767+
a: 10
768+
b: 10
769+
)");
770+
}
771+
772+
TEST(simple_anchor, issue_484_1)
773+
{
774+
csubstr yaml = R"(
775+
base_1: &base_1
776+
a: 10
777+
b: 10
778+
base_2: &base_2
779+
a: 30
780+
k1:
781+
<<: *base_1
782+
<<: *base_2
783+
k2:
784+
<<: *base_2
785+
<<: *base_1
786+
)";
787+
Tree t = parse_in_arena(yaml);
788+
EXPECT_EQ(t["k1"][0].val(), "*base_1");
789+
EXPECT_EQ(t["k1"][1].val(), "*base_2");
790+
EXPECT_EQ(t["k2"][0].val(), "*base_2");
791+
EXPECT_EQ(t["k2"][1].val(), "*base_1");
792+
t.resolve();
793+
EXPECT_EQ(t["k1"]["a"].val(), "30");
794+
EXPECT_EQ(t["k1"]["b"].val(), "10");
795+
EXPECT_EQ(t["k2"]["a"].val(), "10");
796+
EXPECT_EQ(t["k2"]["b"].val(), "10");
797+
EXPECT_EQ(emitrs_yaml<std::string>(t), R"(base_1:
798+
a: 10
799+
b: 10
800+
base_2:
801+
a: 30
802+
k1:
803+
b: 10
804+
a: 30
805+
k2:
806+
a: 10
807+
b: 10
808+
)");
809+
}
810+
733811

734812
//-----------------------------------------------------------------------------
735813
//-----------------------------------------------------------------------------
@@ -1529,6 +1607,28 @@ N(MB, L{
15291607
})
15301608
);
15311609

1610+
ADD_CASE_TO_GROUP("github 484, resolved", RESOLVE_REFS,
1611+
R"(
1612+
base_1: &base_1
1613+
a: 10
1614+
b: 10
1615+
base_2: &base_2
1616+
b: 20
1617+
k1:
1618+
!!merge <<: *base_1
1619+
!!merge <<: *base_2
1620+
k2:
1621+
!!merge <<: *base_2
1622+
!!merge <<: *base_1
1623+
)",
1624+
N(MB, L{
1625+
N(KP|MB, "base_1", L{N(KP|VP, "a", "10"), N(KP|VP, "b", "10")}),
1626+
N(KP|MB, "base_2", L{/* */N(KP|VP, "b", "20")}),
1627+
N(KP|MB, "k1", L{N(KP|VP, "a", "10"), N(KP|VP, "b", "20")}),
1628+
N(KP|MB, "k2", L{N(KP|VP, "a", "10"), N(KP|VP, "b", "10")}),
1629+
})
1630+
);
1631+
15321632
}
15331633

15341634

test/test_merge.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,12 +63,23 @@ TEST(merge, basic)
6363
test_merge(
6464
{
6565
"{a: 0, b: 1}",
66-
"{a: 1, c: 20}"
66+
"{a: 1, c: 20}"
6767
},
6868
"{a: 1, b: 1, c: 20}"
6969
);
7070
}
7171

72+
TEST(merge, basic_inv)
73+
{
74+
test_merge(
75+
{
76+
"{a: 1, c: 20}",
77+
"{a: 0, b: 1}"
78+
},
79+
"{a: 0, c: 20, b: 1}"
80+
);
81+
}
82+
7283
TEST(merge, dst_scalar_keeps_style)
7384
{
7485
Tree dst = parse_in_arena("a: b");

0 commit comments

Comments
 (0)