Skip to content

Commit

Permalink
Add some more tests
Browse files Browse the repository at this point in the history
  • Loading branch information
dwd committed Jul 1, 2024
1 parent 9872a2f commit 4dd8694
Show file tree
Hide file tree
Showing 4 changed files with 141 additions and 20 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ add_executable(rapidxml-test
rapidxml_print.hpp
rapidxml_utils.hpp
rapidxml.hpp
test/manipulations.cpp
)
target_link_libraries(rapidxml-test
GTest::gtest_main
Expand Down
32 changes: 14 additions & 18 deletions rapidxml.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1260,31 +1260,27 @@ namespace rapidxml
//! Behaviour is undefined if node has no parent.
//! Use parent() to test if node has a parent.
//! \param name Name of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
//! \param xmlns Namespace of sibling to find, or 0 to return next sibling regardless of its name; this string doesn't have to be zero-terminated if name_size is non-zero
//! \param name_size Size of name, in characters, or 0 to have size calculated automatically from string
//! \param case_sensitive Should name comparison be case-sensitive; non case-sensitive comparison works properly only for ASCII characters
//! \return Pointer to found sibling, or 0 if not found.
xml_node<Ch> *next_sibling(const Ch *name = 0, const Ch *xmlns = 0, std::size_t name_size = 0, std::size_t xmlns_size = 0, bool case_sensitive = true) const
{
assert(this->m_parent); // Cannot query for siblings if node has no parent
if (name)
{
if (name_size == 0)
name_size = internal::measure(name);
if (xmlns && !xmlns_size) xmlns_size = internal::measure(xmlns);
if (!xmlns && name) {
// No XMLNS asked for, but a name is present.
// Assume "same XMLNS".
xmlns = this->xmlns();
xmlns_size = this->xmlns_size();
}
for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
if ((!name || internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
&& (!xmlns || internal::compare(sibling->xmlns(), sibling->xmlns_size(), xmlns, xmlns_size, case_sensitive)))
return sibling;
return 0;
if (name && name_size == 0)
name_size = internal::measure(name);
if (xmlns && !xmlns_size) xmlns_size = internal::measure(xmlns);
if (!xmlns && name) {
// No XMLNS asked for, but a name is present.
// Assume "same XMLNS".
xmlns = this->xmlns();
xmlns_size = this->xmlns_size();
}
else
return m_next_sibling;
for (xml_node<Ch> *sibling = m_next_sibling; sibling; sibling = sibling->m_next_sibling)
if ((!name || internal::compare(sibling->name(), sibling->name_size(), name, name_size, case_sensitive))
&& (!xmlns || internal::compare(sibling->xmlns(), sibling->xmlns_size(), xmlns, xmlns_size, case_sensitive)))
return sibling;
return 0;
}

//! Gets first attribute of node, optionally matching attribute name.
Expand Down
93 changes: 93 additions & 0 deletions test/manipulations.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
//
// Created by dwd on 01/07/24.
//

#include <gtest/gtest.h>

#include "rapidxml.hpp"
#include "rapidxml_print.hpp"

namespace {
auto print(rapidxml::xml_document<> & doc) {
std::string output;
rapidxml::print(std::back_inserter(output), *doc.first_node());
return output;
}
}

TEST(Create, Node) {
rapidxml::xml_document<> doc;
auto node = doc.allocate_node(rapidxml::node_element, "fish", "cakes");
doc.append_node(node);

EXPECT_EQ(
print(doc),
"<fish>cakes</fish>\n"
);
}

TEST(Create, NodeEmpty) {
rapidxml::xml_document<> doc;
auto node = doc.allocate_node(rapidxml::node_element, "fish");
doc.append_node(node);

EXPECT_EQ(
print(doc),
"<fish/>\n"
);
}

TEST(Create, Node2) {
rapidxml::xml_document<> doc;
auto node = doc.allocate_node(rapidxml::node_element, "fish", "cakes", 4, 5);
doc.append_node(node);

EXPECT_EQ(
print(doc),
"<fish>cakes</fish>\n"
);
}

TEST(Create, NodeAttr) {
rapidxml::xml_document<> doc;
auto node = doc.allocate_node(rapidxml::node_element, "fish", "cakes");
auto haddock = doc.allocate_attribute("id", "haddock");
node->append_attribute(haddock);
doc.append_node(node);

EXPECT_EQ(
print(doc),
"<fish id=\"haddock\">cakes</fish>\n"
);

auto tuna = doc.allocate_attribute("not-id", "tuna");
node->append_attribute(tuna);
EXPECT_EQ(haddock->next_attribute(), tuna);
EXPECT_EQ(tuna->parent(), node);
EXPECT_EQ(
print(doc),
"<fish id=\"haddock\" not-id=\"tuna\">cakes</fish>\n"
);
node->remove_attribute(tuna);
EXPECT_EQ(haddock->next_attribute(), nullptr);
EXPECT_EQ(tuna->parent(), nullptr);
EXPECT_EQ(
print(doc),
"<fish id=\"haddock\">cakes</fish>\n"
);
node->prepend_attribute(tuna);
EXPECT_EQ(
print(doc),
"<fish not-id=\"tuna\" id=\"haddock\">cakes</fish>\n"
);
node->value("pie");
EXPECT_EQ(
print(doc),
"<fish not-id=\"tuna\" id=\"haddock\">pie</fish>\n"
);
node->remove_all_attributes();
EXPECT_EQ(
print(doc),
"<fish>pie</fish>\n"
);
}
35 changes: 33 additions & 2 deletions test/parse-simple.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ TEST(Parser, Xmlns) {

TEST(Parser, ChildXmlns) {
rapidxml::xml_document<> doc;
char doc_text[] = "<pfx:single xmlns:pfx='urn:xmpp:example'><pfx:firstchild/><child xmlns='urn:potato'/><pfx:child/></pfx:single>";
char doc_text[] = "<pfx:single xmlns:pfx='urn:xmpp:example' foo='bar'><pfx:firstchild/><child xmlns='urn:potato'/><pfx:child/></pfx:single>";
doc.parse<0>(doc_text);

auto node = doc.first_node();
Expand All @@ -99,12 +99,44 @@ TEST(Parser, ChildXmlns) {
child = node->first_node();
EXPECT_STREQ("firstchild", child->name());
EXPECT_STREQ("urn:xmpp:example", child->xmlns());
child = child->next_sibling();
EXPECT_STREQ("child", child->name());
EXPECT_STREQ("urn:potato", child->xmlns());
child = child->next_sibling();
EXPECT_STREQ("child", child->name());
EXPECT_STREQ("urn:xmpp:example", child->xmlns());
child = node->first_node("child");
EXPECT_STREQ("child", child->name());
EXPECT_STREQ("urn:xmpp:example", child->xmlns());
child = node->first_node()->next_sibling(nullptr, "urn:xmpp:example");
EXPECT_STREQ("child", child->name());
EXPECT_STREQ("urn:xmpp:example", child->xmlns());
child = node->first_node()->next_sibling("child");
// This will default to the same namespace as the first child ndoe.
EXPECT_STREQ("child", child->name());
EXPECT_STREQ("urn:xmpp:example", child->xmlns());
auto attr = node->first_attribute();
EXPECT_STREQ(attr->xmlns(), "http://www.w3.org/2000/xmlns/");
EXPECT_STREQ(attr->local_name(), "pfx");
EXPECT_STREQ(attr->name(), "xmlns:pfx");
EXPECT_EQ(attr->value_str(), "urn:xmpp:example");
attr = attr->next_attribute();
EXPECT_STREQ(attr->xmlns(), "");
EXPECT_STREQ(attr->local_name(), "foo");
EXPECT_STREQ(attr->name(), "foo");
EXPECT_EQ(attr->value_str(), "bar");
doc.validate();
}

TEST(Parser, HandleEOF){
rapidxml::xml_document<> doc;
char doc_text[] = "<open_element>";
EXPECT_THROW(
doc.parse<0>(doc_text),
rapidxml::eof_error
);
}

TEST(ParseOptions, Fastest) {
rapidxml::xml_document<> doc;
char doc_text[] = "<pfx:single xmlns:pfx='urn:xmpp:example'><pfx:firstchild/><child xmlns='urn:potato'/><pfx:child/></pfx:single>";
Expand Down Expand Up @@ -226,4 +258,3 @@ TEST(ParseOptions, OpenOnlyFastest) {
subdoc.validate();
}
}

0 comments on commit 4dd8694

Please sign in to comment.