Skip to content

Commit 5f1bcee

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

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
@@ -750,6 +750,84 @@ a5: &a5
750750
}
751751
}
752752

753+
TEST(simple_anchor, issue_484_0)
754+
{
755+
csubstr yaml = R"(
756+
base_1: &base_1
757+
a: 10
758+
b: 10
759+
base_2: &base_2
760+
b: 20
761+
k1:
762+
!!merge <<: *base_1
763+
!!merge <<: *base_2
764+
k2:
765+
!!merge <<: *base_2
766+
!!merge <<: *base_1
767+
)";
768+
Tree t = parse_in_arena(yaml);
769+
EXPECT_EQ(t["k1"][0].val(), "*base_1");
770+
EXPECT_EQ(t["k1"][1].val(), "*base_2");
771+
EXPECT_EQ(t["k2"][0].val(), "*base_2");
772+
EXPECT_EQ(t["k2"][1].val(), "*base_1");
773+
t.resolve();
774+
EXPECT_EQ(t["k1"]["a"].val(), "10");
775+
EXPECT_EQ(t["k1"]["b"].val(), "20");
776+
EXPECT_EQ(t["k2"]["a"].val(), "10");
777+
EXPECT_EQ(t["k2"]["b"].val(), "10");
778+
EXPECT_EQ(emitrs_yaml<std::string>(t), R"(base_1:
779+
a: 10
780+
b: 10
781+
base_2:
782+
b: 20
783+
k1:
784+
a: 10
785+
b: 20
786+
k2:
787+
a: 10
788+
b: 10
789+
)");
790+
}
791+
792+
TEST(simple_anchor, issue_484_1)
793+
{
794+
csubstr yaml = R"(
795+
base_1: &base_1
796+
a: 10
797+
b: 10
798+
base_2: &base_2
799+
a: 30
800+
k1:
801+
<<: *base_1
802+
<<: *base_2
803+
k2:
804+
<<: *base_2
805+
<<: *base_1
806+
)";
807+
Tree t = parse_in_arena(yaml);
808+
EXPECT_EQ(t["k1"][0].val(), "*base_1");
809+
EXPECT_EQ(t["k1"][1].val(), "*base_2");
810+
EXPECT_EQ(t["k2"][0].val(), "*base_2");
811+
EXPECT_EQ(t["k2"][1].val(), "*base_1");
812+
t.resolve();
813+
EXPECT_EQ(t["k1"]["a"].val(), "30");
814+
EXPECT_EQ(t["k1"]["b"].val(), "10");
815+
EXPECT_EQ(t["k2"]["a"].val(), "10");
816+
EXPECT_EQ(t["k2"]["b"].val(), "10");
817+
EXPECT_EQ(emitrs_yaml<std::string>(t), R"(base_1:
818+
a: 10
819+
b: 10
820+
base_2:
821+
a: 30
822+
k1:
823+
b: 10
824+
a: 30
825+
k2:
826+
a: 10
827+
b: 10
828+
)");
829+
}
830+
753831

754832
//-----------------------------------------------------------------------------
755833
//-----------------------------------------------------------------------------
@@ -1549,6 +1627,28 @@ N(MB, L{
15491627
})
15501628
);
15511629

1630+
ADD_CASE_TO_GROUP("github 484, resolved", RESOLVE_REFS,
1631+
R"(
1632+
base_1: &base_1
1633+
a: 10
1634+
b: 10
1635+
base_2: &base_2
1636+
b: 20
1637+
k1:
1638+
!!merge <<: *base_1
1639+
!!merge <<: *base_2
1640+
k2:
1641+
!!merge <<: *base_2
1642+
!!merge <<: *base_1
1643+
)",
1644+
N(MB, L{
1645+
N(KP|MB, "base_1", L{N(KP|VP, "a", "10"), N(KP|VP, "b", "10")}),
1646+
N(KP|MB, "base_2", L{/* */N(KP|VP, "b", "20")}),
1647+
N(KP|MB, "k1", L{N(KP|VP, "a", "10"), N(KP|VP, "b", "20")}),
1648+
N(KP|MB, "k2", L{N(KP|VP, "a", "10"), N(KP|VP, "b", "10")}),
1649+
})
1650+
);
1651+
15521652
}
15531653

15541654

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)