blob: 8b2ed5c390fbc2c536a5a814baf9e5f6538bdef9 [file] [log] [blame]
Alex Vakulenkobf71f702015-05-18 14:30:56 -07001// Copyright 2015 The Chromium OS Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "buffet/notification/xml_node.h"
6
7#include <memory>
8
9#include <gtest/gtest.h>
10
11#include "buffet/notification/xmpp_stream_parser.h"
12
13namespace buffet {
14namespace {
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 {
45 node_.reset(new XmlNode{"test_node",
46 {{"attr1", "val1"}, {"attr2", "val2"}}});
47 }
48
49 // Accessor helpers for private members of XmlNode.
50 static const XmlNode* GetParent(const XmlNode& node) {
51 return node.parent_;
52 }
53
54 static void SetText(XmlNode* node, const std::string& text) {
55 node->SetText(text);
56 }
57
58 static void AppendText(XmlNode* node, const std::string& text) {
59 node->AppendText(text);
60 }
61
62 void CreateNodeTree() {
63 node_ = XmlParser{}.Parse(R"(
64 <top>
65 <node1 id="1"><node2 id="2"><node3 id="3"/></node2></node1>
66 <node2 id="4"><node3 id="5"/></node2>
67 <node3 id="6"/>
68 <node2 id="7"><node4 id="8"><node3 id="9"/></node4></node2>
69 </top>
70 )");
71 }
72
73 std::unique_ptr<XmlNode> node_;
74};
75
76TEST_F(XmlNodeTest, DefaultConstruction) {
77 EXPECT_EQ("test_node", node_->name());
78 EXPECT_TRUE(node_->children().empty());
79 EXPECT_TRUE(node_->text().empty());
80}
81
82TEST_F(XmlNodeTest, SetText) {
83 SetText(node_.get(), "foobar");
84 EXPECT_EQ("foobar", node_->text());
85}
86
87TEST_F(XmlNodeTest, AppendText) {
88 SetText(node_.get(), "foobar");
89 AppendText(node_.get(), "-baz");
90 EXPECT_EQ("foobar-baz", node_->text());
91}
92
93TEST_F(XmlNodeTest, AddChild) {
94 std::unique_ptr<XmlNode> child{new XmlNode{"child", {}}};
95 node_->AddChild(std::move(child));
96 EXPECT_EQ(1u, node_->children().size());
97 EXPECT_EQ("child", node_->children().front()->name());
98 EXPECT_EQ(node_.get(), GetParent(*node_->children().front().get()));
99}
100
101TEST_F(XmlNodeTest, Attributes) {
102 const std::map<std::string, std::string> expected_attrs{
103 {"attr1", "val1"},
104 {"attr2", "val2"}
105 };
106 EXPECT_EQ(expected_attrs, node_->attributes());
107 std::string attr = "bar";
108 EXPECT_FALSE(node_->GetAttribute("foo", &attr));
109 EXPECT_EQ("bar", attr); // Shouldn't be changed by failed GetAttribute().
110 EXPECT_TRUE(node_->GetAttribute("attr1", &attr));
111 EXPECT_EQ("val1", attr);
112 EXPECT_TRUE(node_->GetAttribute("attr2", &attr));
113 EXPECT_EQ("val2", attr);
114
115 XmlNode new_node{"node", {}};
116 EXPECT_FALSE(new_node.GetAttribute("attr1", &attr));
117}
118
119TEST_F(XmlNodeTest, FindFirstChild_SingleNode) {
120 CreateNodeTree();
121 const XmlNode* node = node_->FindFirstChild("node3", false);
122 ASSERT_NE(nullptr, node);
123 EXPECT_EQ("node3", node->name());
124 EXPECT_EQ("6", node->GetAttributeOrEmpty("id"));
125
126 node = node_->FindFirstChild("node3", true);
127 ASSERT_NE(nullptr, node);
128 EXPECT_EQ("node3", node->name());
129 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
130
131 node = node_->FindFirstChild("foo", true);
132 ASSERT_EQ(nullptr, node);
133}
134
135TEST_F(XmlNodeTest, FindFirstChild_Path) {
136 CreateNodeTree();
137 const XmlNode* node = node_->FindFirstChild("node2/node3", false);
138 ASSERT_NE(nullptr, node);
139 EXPECT_EQ("node3", node->name());
140 EXPECT_EQ("5", node->GetAttributeOrEmpty("id"));
141
142 node = node_->FindFirstChild("node2/node3", true);
143 ASSERT_NE(nullptr, node);
144 EXPECT_EQ("node3", node->name());
145 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
146
147 node = node_->FindFirstChild("node1/node2/node3", false);
148 ASSERT_NE(nullptr, node);
149 EXPECT_EQ("node3", node->name());
150 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
151
152 node = node_->FindFirstChild("node1/node2/node3", true);
153 ASSERT_NE(nullptr, node);
154 EXPECT_EQ("node3", node->name());
155 EXPECT_EQ("3", node->GetAttributeOrEmpty("id"));
156
157 node = node_->FindFirstChild("foo/node3", true);
158 ASSERT_EQ(nullptr, node);
159}
160
161TEST_F(XmlNodeTest, FindChildren_SingleNode) {
162 CreateNodeTree();
163 auto children = node_->FindChildren("node3", false);
164 ASSERT_EQ(1u, children.size());
165 EXPECT_EQ("node3", children[0]->name());
166 EXPECT_EQ("6", children[0]->GetAttributeOrEmpty("id"));
167
168 children = node_->FindChildren("node3", true);
169 ASSERT_EQ(4u, children.size());
170 EXPECT_EQ("node3", children[0]->name());
171 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
172 EXPECT_EQ("node3", children[1]->name());
173 EXPECT_EQ("5", children[1]->GetAttributeOrEmpty("id"));
174 EXPECT_EQ("node3", children[2]->name());
175 EXPECT_EQ("6", children[2]->GetAttributeOrEmpty("id"));
176 EXPECT_EQ("node3", children[3]->name());
177 EXPECT_EQ("9", children[3]->GetAttributeOrEmpty("id"));
178}
179
180TEST_F(XmlNodeTest, FindChildren_Path) {
181 CreateNodeTree();
182 auto children = node_->FindChildren("node2/node3", false);
183 ASSERT_EQ(1u, children.size());
184 EXPECT_EQ("node3", children[0]->name());
185 EXPECT_EQ("5", children[0]->GetAttributeOrEmpty("id"));
186
187 children = node_->FindChildren("node2/node3", true);
188 ASSERT_EQ(2u, children.size());
189 EXPECT_EQ("node3", children[0]->name());
190 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
191 EXPECT_EQ("node3", children[1]->name());
192 EXPECT_EQ("5", children[1]->GetAttributeOrEmpty("id"));
193
194 children = node_->FindChildren("node1/node2/node3", false);
195 ASSERT_EQ(1u, children.size());
196 EXPECT_EQ("node3", children[0]->name());
197 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
198
199 children = node_->FindChildren("node1/node2/node3", true);
200 ASSERT_EQ(1u, children.size());
201 EXPECT_EQ("node3", children[0]->name());
202 EXPECT_EQ("3", children[0]->GetAttributeOrEmpty("id"));
203
204 children = node_->FindChildren("foo/bar", false);
205 ASSERT_EQ(0u, children.size());
206
207 children = node_->FindChildren("node2/baz", false);
208 ASSERT_EQ(0u, children.size());
209}
210
211} // namespace buffet