Skip to content

Commit 1dab263

Browse files
vvd170501SGSSGene
authored andcommitted
Add option to preserve node marks when cloning a node
1 parent 8a666a0 commit 1dab263

2 files changed

Lines changed: 88 additions & 4 deletions

File tree

src/nodeevents.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,19 +69,19 @@ void NodeEvents::Emit(const detail::node& node, EventHandler& handler,
6969
case NodeType::Undefined:
7070
break;
7171
case NodeType::Null:
72-
handler.OnNull(Mark(), anchor);
72+
handler.OnNull(node.mark(), anchor);
7373
break;
7474
case NodeType::Scalar:
75-
handler.OnScalar(Mark(), node.tag(), anchor, node.scalar());
75+
handler.OnScalar(node.mark(), node.tag(), anchor, node.scalar());
7676
break;
7777
case NodeType::Sequence:
78-
handler.OnSequenceStart(Mark(), node.tag(), anchor, node.style());
78+
handler.OnSequenceStart(node.mark(), node.tag(), anchor, node.style());
7979
for (auto element : node)
8080
Emit(*element, handler, am);
8181
handler.OnSequenceEnd();
8282
break;
8383
case NodeType::Map:
84-
handler.OnMapStart(Mark(), node.tag(), anchor, node.style());
84+
handler.OnMapStart(node.mark(), node.tag(), anchor, node.style());
8585
for (auto element : node) {
8686
Emit(*element.first, handler, am);
8787
Emit(*element.second, handler, am);
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#include "gmock/gmock.h"
2+
#include "gtest/gtest.h"
3+
#include <yaml-cpp/yaml.h>
4+
5+
struct ComparableMark {
6+
int pos;
7+
int line, column;
8+
9+
ComparableMark(int pos, int line, int column)
10+
: pos(pos), line(line), column(column) {}
11+
};
12+
13+
bool operator==(const YAML::Mark& a, const ComparableMark& b) {
14+
return a.pos == b.pos && a.line == b.line && a.column == b.column;
15+
}
16+
17+
template <typename Mark>
18+
void PrintMark(const Mark& mark, std::ostream* os) {
19+
*os << mark.line << ':' << mark.column << " (pos " << mark.pos << ')';
20+
}
21+
22+
void PrintTo(const ComparableMark& mark, std::ostream* os) {
23+
PrintMark(mark, os);
24+
}
25+
26+
namespace YAML {
27+
void PrintTo(const Mark& mark, std::ostream* os) { PrintMark(mark, os); }
28+
} // namespace YAML
29+
30+
TEST(CloneNodeTest, PreserveMark) {
31+
std::string yaml_str = R"(
32+
scalar: value
33+
sequence: [1, 2, 3]
34+
"null": null
35+
[1, 2, 3]: value # check non-scalar keys
36+
)";
37+
38+
auto checkMarks = [](const YAML::Node& root_node) {
39+
EXPECT_EQ(root_node.Mark(), ComparableMark(1, 1, 0));
40+
41+
const YAML::Node& scalar = root_node["scalar"];
42+
EXPECT_EQ(scalar.Mark(), ComparableMark(9, 1, 8));
43+
44+
const YAML::Node& sequence = root_node["sequence"];
45+
EXPECT_EQ(sequence.Mark(), ComparableMark(25, 2, 10));
46+
EXPECT_EQ(sequence[0].Mark(), ComparableMark(26, 2, 11));
47+
EXPECT_EQ(sequence[1].Mark(), ComparableMark(29, 2, 14));
48+
EXPECT_EQ(sequence[2].Mark(), ComparableMark(32, 2, 17));
49+
50+
const YAML::Node& null = root_node["null"];
51+
EXPECT_EQ(null.Mark(), ComparableMark(43, 3, 8));
52+
53+
YAML::Node sequence_key;
54+
std::vector<YAML::Mark> key_marks;
55+
for (auto it = root_node.begin(); it != root_node.end(); ++it) {
56+
// Not assuming any key order
57+
key_marks.emplace_back(it->first.Mark());
58+
if (it->first.IsSequence()) {
59+
sequence_key.reset(it->first);
60+
}
61+
}
62+
63+
EXPECT_THAT(key_marks,
64+
testing::UnorderedElementsAre(
65+
ComparableMark(1, 1, 0), ComparableMark(15, 2, 0),
66+
ComparableMark(35, 3, 0), ComparableMark(48, 4, 0)));
67+
68+
ASSERT_TRUE(sequence_key);
69+
EXPECT_EQ(sequence_key[0].Mark(), ComparableMark(49, 4, 1));
70+
EXPECT_EQ(sequence_key[1].Mark(), ComparableMark(52, 4, 4));
71+
EXPECT_EQ(sequence_key[2].Mark(), ComparableMark(55, 4, 7));
72+
};
73+
74+
YAML::Node root_node = YAML::Load(yaml_str);
75+
{
76+
SCOPED_TRACE("original node");
77+
checkMarks(root_node);
78+
}
79+
YAML::Node cloned_node = YAML::Clone(root_node);
80+
{
81+
SCOPED_TRACE("cloned node");
82+
checkMarks(cloned_node);
83+
}
84+
}

0 commit comments

Comments
 (0)