blob: 34ccfb03b5b37c4d21be3e9fc6b5675fc0174271 [file] [log] [blame]
Vitaly Buka4615e0d2015-10-14 15:35:12 -07001// Copyright 2015 The Weave Authors. All rights reserved.
Alex Vakulenkobf71f702015-05-18 14:30:56 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
Stefan Sauer2d16dfa2015-09-25 17:08:35 +02005#include "src/notification/xml_node.h"
Alex Vakulenkobf71f702015-05-18 14:30:56 -07006
7#include <memory>
8
9#include <gtest/gtest.h>
10
Stefan Sauer2d16dfa2015-09-25 17:08:35 +020011#include "src/notification/xmpp_stream_parser.h"
Alex Vakulenkobf71f702015-05-18 14:30:56 -070012
Vitaly Bukab6f015a2015-07-09 14:59:23 -070013namespace weave {
Alex Vakulenkobf71f702015-05-18 14:30:56 -070014namespace {
15
16class XmlParser : public XmppStreamParser::Delegate {
17 public:
18 std::unique_ptr<XmlNode> Parse(const std::string& xml) {
19 parser_.ParseData(xml);
20 return std::move(node_);
21 }
22
23 private:
24 // Overrides from XmppStreamParser::Delegate.
25 void OnStreamStart(const std::string& node_name,
26 std::map<std::string, std::string> attributes) override {
27 node_.reset(new XmlNode{node_name, std::move(attributes)});
28 }
29
30 void OnStreamEnd(const std::string& node_name) override {}
31
32 void OnStanza(std::unique_ptr<XmlNode> stanza) override {
33 node_->AddChild(std::move(stanza));
34 }
35
36 std::unique_ptr<XmlNode> node_;
37 XmppStreamParser parser_{this};
38};
39
40} // anonymous namespace
41
42class XmlNodeTest : public testing::Test {
43 public:
44 void SetUp() override {
Vitaly Bukaa647c852015-07-06 14:51:01 -070045 node_.reset(
46 new XmlNode{"test_node", {{"attr1", "val1"}, {"attr2", "val2"}}});
Alex Vakulenkobf71f702015-05-18 14:30:56 -070047 }
48
49 // Accessor helpers for private members of XmlNode.
Vitaly Bukaa647c852015-07-06 14:51:01 -070050 static const XmlNode* GetParent(const XmlNode& node) { return node.parent_; }
Alex Vakulenkobf71f702015-05-18 14:30:56 -070051
52 static void SetText(XmlNode* node, const std::string& text) {
53 node->SetText(text);
54 }
55
56 static void AppendText(XmlNode* node, const std::string& text) {
57 node->AppendText(text);
58 }
59
60 void CreateNodeTree() {
61 node_ = XmlParser{}.Parse(R"(
62 <top>
63 <node1 id="1"><node2 id="2"><node3 id="3"/></node2></node1>
64 <node2 id="4"><node3 id="5"/></node2>
65 <node3 id="6"/>
66 <node2 id="7"><node4 id="8"><node3 id="9"/></node4></node2>
67 </top>
68 )");
69 }
70
71 std::unique_ptr<XmlNode> node_;
72};
73
74TEST_F(XmlNodeTest, DefaultConstruction) {
75 EXPECT_EQ("test_node", node_->name());
76 EXPECT_TRUE(node_->children().empty());
77 EXPECT_TRUE(node_->text().empty());
78}
79
80TEST_F(XmlNodeTest, SetText) {
81 SetText(node_.get(), "foobar");
82 EXPECT_EQ("foobar", node_->text());
83}
84
85TEST_F(XmlNodeTest, AppendText) {
86 SetText(node_.get(), "foobar");
87 AppendText(node_.get(), "-baz");
88 EXPECT_EQ("foobar-baz", node_->text());
89}
90
91TEST_F(XmlNodeTest, AddChild) {
92 std::unique_ptr<XmlNode> child{new XmlNode{"child", {}}};
93 node_->AddChild(std::move(child));
94 EXPECT_EQ(1u, node_->children().size());
95 EXPECT_EQ("child", node_->children().front()->name());
96 EXPECT_EQ(node_.get(), GetParent(*node_->children().front().get()));
97}
98
99TEST_F(XmlNodeTest, Attributes) {
Vitaly Bukaa647c852015-07-06 14:51:01 -0700100 const std::map<std::string, std::string> expected_attrs{{"attr1", "val1"},
101 {"attr2", "val2"}};
Alex Vakulenkobf71f702015-05-18 14:30:56 -0700102 EXPECT_EQ(expected_attrs, node_->attributes());
103 std::string attr = "bar";
104 EXPECT_FALSE(node_->GetAttribute("foo", &attr));
105 EXPECT_EQ("bar", attr); // Shouldn't be changed by failed GetAttribute().
106 EXPECT_TRUE(node_->GetAttribute("attr1", &attr));
107 EXPECT_EQ("val1", attr);
108 EXPECT_TRUE(node_->GetAttribute("attr2", &attr));
109 EXPECT_EQ("val2", attr);
110
111 XmlNode new_node{"node", {}};
112 EXPECT_FALSE(new_node.GetAttribute("attr1", &attr));
113}
114
115TEST_F(XmlNodeTest, FindFirstChild_SingleNode) {
116 CreateNodeTree();
117 const XmlNode* node = node_->FindFirstChild("node3", false);
118 ASSERT_NE(nullptr, node);
119 EXPECT_EQ("node3", node->name());
120 EXPECT_EQ("6", node->GetAttributeOrEmpty("id"));
121
122 node = node_->FindFirstChild("node3", true);
123 ASSERT_NE(nullptr, node);
124 EXPECT_EQ("node3", node->name());
125 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
126
127 node = node_->FindFirstChild("foo", true);
128 ASSERT_EQ(nullptr, node);
129}
130
131TEST_F(XmlNodeTest, FindFirstChild_Path) {
132 CreateNodeTree();
133 const XmlNode* node = node_->FindFirstChild("node2/node3", false);
134 ASSERT_NE(nullptr, node);
135 EXPECT_EQ("node3", node->name());
136 EXPECT_EQ("5", node->GetAttributeOrEmpty("id"));
137
138 node = node_->FindFirstChild("node2/node3", true);
139 ASSERT_NE(nullptr, node);
140 EXPECT_EQ("node3", node->name());
141 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
142
143 node = node_->FindFirstChild("node1/node2/node3", false);
144 ASSERT_NE(nullptr, node);
145 EXPECT_EQ("node3", node->name());
146 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
147
148 node = node_->FindFirstChild("node1/node2/node3", true);
149 ASSERT_NE(nullptr, node);
150 EXPECT_EQ("node3", node->name());
151 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
152
153 node = node_->FindFirstChild("foo/node3", true);
154 ASSERT_EQ(nullptr, node);
155}
156
157TEST_F(XmlNodeTest, FindChildren_SingleNode) {
158 CreateNodeTree();
159 auto children = node_->FindChildren("node3", false);
160 ASSERT_EQ(1u, children.size());
161 EXPECT_EQ("node3", children[0]->name());
162 EXPECT_EQ("6", children[0]->GetAttributeOrEmpty("id"));
163
164 children = node_->FindChildren("node3", true);
165 ASSERT_EQ(4u, children.size());
166 EXPECT_EQ("node3", children[0]->name());
167 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
168 EXPECT_EQ("node3", children[1]->name());
169 EXPECT_EQ("5", children[1]->GetAttributeOrEmpty("id"));
170 EXPECT_EQ("node3", children[2]->name());
171 EXPECT_EQ("6", children[2]->GetAttributeOrEmpty("id"));
172 EXPECT_EQ("node3", children[3]->name());
173 EXPECT_EQ("9", children[3]->GetAttributeOrEmpty("id"));
174}
175
176TEST_F(XmlNodeTest, FindChildren_Path) {
177 CreateNodeTree();
178 auto children = node_->FindChildren("node2/node3", false);
179 ASSERT_EQ(1u, children.size());
180 EXPECT_EQ("node3", children[0]->name());
181 EXPECT_EQ("5", children[0]->GetAttributeOrEmpty("id"));
182
183 children = node_->FindChildren("node2/node3", true);
184 ASSERT_EQ(2u, children.size());
185 EXPECT_EQ("node3", children[0]->name());
186 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
187 EXPECT_EQ("node3", children[1]->name());
188 EXPECT_EQ("5", children[1]->GetAttributeOrEmpty("id"));
189
190 children = node_->FindChildren("node1/node2/node3", false);
191 ASSERT_EQ(1u, children.size());
192 EXPECT_EQ("node3", children[0]->name());
193 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
194
195 children = node_->FindChildren("node1/node2/node3", true);
196 ASSERT_EQ(1u, children.size());
197 EXPECT_EQ("node3", children[0]->name());
198 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
199
200 children = node_->FindChildren("foo/bar", false);
201 ASSERT_EQ(0u, children.size());
202
203 children = node_->FindChildren("node2/baz", false);
204 ASSERT_EQ(0u, children.size());
205}
206
Vitaly Bukab6f015a2015-07-09 14:59:23 -0700207} // namespace weave