diff options
author | Joanna Hulboj <joanna.hulboj@isode.com> | 2019-09-19 19:48:44 (GMT) |
---|---|---|
committer | Joanna Hulboj <joanna.hulboj@isode.com> | 2019-09-24 10:08:15 (GMT) |
commit | 23e2766dab6d4a3f6158eca7649cd36b644634d3 (patch) | |
tree | 1faa4b741b03704e7a70918196310a4453e699a7 /Swiften/Parser/UnitTest | |
parent | e58cf7d5d7d3bab330bccf6a098dd476fbf4dc86 (diff) | |
download | swift-23e2766dab6d4a3f6158eca7649cd36b644634d3.zip swift-23e2766dab6d4a3f6158eca7649cd36b644634d3.tar.bz2 |
Process attribute and element prefixes
XML (Expat/LibXML) parsing modified to process prefix information.
Prefixes for attributes stored within attributes.
Prefixes for elements passed in additional callback
(only if prefix present).
Test-information:
Unit tests pass on Windows 10 and Ubuntu 18.04.1 LTS.
Change-Id: Ib6b5087feed758c31895f426df6a3c7ea975f248
Diffstat (limited to 'Swiften/Parser/UnitTest')
-rw-r--r-- | Swiften/Parser/UnitTest/AttributeMapTest.cpp | 17 | ||||
-rw-r--r-- | Swiften/Parser/UnitTest/XMLParserTest.cpp | 59 |
2 files changed, 73 insertions, 3 deletions
diff --git a/Swiften/Parser/UnitTest/AttributeMapTest.cpp b/Swiften/Parser/UnitTest/AttributeMapTest.cpp index 4529eac..d9335c1 100644 --- a/Swiften/Parser/UnitTest/AttributeMapTest.cpp +++ b/Swiften/Parser/UnitTest/AttributeMapTest.cpp @@ -15,6 +15,7 @@ class AttributeMapTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(AttributeMapTest); CPPUNIT_TEST(testGetAttribute_Namespaced); + CPPUNIT_TEST(testGetAttribute_Namespaced_Prefix); CPPUNIT_TEST(testGetBoolAttribute_True); CPPUNIT_TEST(testGetBoolAttribute_1); CPPUNIT_TEST(testGetBoolAttribute_False); @@ -34,6 +35,22 @@ class AttributeMapTest : public CppUnit::TestFixture CPPUNIT_ASSERT_EQUAL(std::string("en"), testling.getAttribute("lang", "http://www.w3.org/XML/1998/namespace")); } + void testGetAttribute_Namespaced_Prefix() { + AttributeMap testling; + testling.addAttribute("lang", "", "prefix", "nl"); + testling.addAttribute("lang", "http://www.w3.org/XML/1998/namespace", "prefix", "en"); + testling.addAttribute("lang", "", "prefix", "fr"); + + CPPUNIT_ASSERT_EQUAL(std::string("en"), testling.getAttribute("lang", "http://www.w3.org/XML/1998/namespace")); + const auto& entries = testling.getEntries(); + auto it = std::find_if(entries.begin(), entries.end(), [](const AttributeMap::Entry& e) { + return e.getValue() == "en"; + }); + const bool found = it != entries.end(); + CPPUNIT_ASSERT_EQUAL(true, found); + CPPUNIT_ASSERT_EQUAL(std::string("prefix"), it->getAttribute().getPrefix()); + } + void testGetBoolAttribute_True() { AttributeMap testling; testling.addAttribute("foo", "", "true"); diff --git a/Swiften/Parser/UnitTest/XMLParserTest.cpp b/Swiften/Parser/UnitTest/XMLParserTest.cpp index 63d30ea..4db694e 100644 --- a/Swiften/Parser/UnitTest/XMLParserTest.cpp +++ b/Swiften/Parser/UnitTest/XMLParserTest.cpp @@ -35,6 +35,7 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_WhitespaceInAttribute); CPPUNIT_TEST(testParse_AttributeWithoutNamespace); CPPUNIT_TEST(testParse_AttributeWithNamespace); + CPPUNIT_TEST(testParse_AttributeWithNamespaceNoPrefix); CPPUNIT_TEST(testParse_BillionLaughs); CPPUNIT_TEST(testParse_InternalEntity); //CPPUNIT_TEST(testParse_UndefinedPrefix); @@ -43,6 +44,7 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_TEST(testParse_DisallowCommentsInXML); CPPUNIT_TEST(testParse_Doctype); CPPUNIT_TEST(testParse_ProcessingInstructions); + CPPUNIT_TEST(testParse_ProcessingPrefixedElement); CPPUNIT_TEST_SUITE_END(); public: @@ -264,6 +266,7 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); CPPUNIT_ASSERT_EQUAL(std::string("attr"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].attributes.getEntries()[0].getAttribute().getNamespace()); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].attributes.getEntries()[0].getAttribute().getPrefix()); } void testParse_AttributeWithNamespace() { @@ -275,6 +278,22 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); CPPUNIT_ASSERT_EQUAL(std::string("attr"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im/f"), client_.events[0].attributes.getEntries()[0].getAttribute().getNamespace()); + CPPUNIT_ASSERT_EQUAL(std::string("f"), client_.events[0].attributes.getEntries()[0].getAttribute().getPrefix()); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), client_.events[0].namespaces.size()); + CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im"), client_.events[0].namespaces[""]); + CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im/f"), client_.events[0].namespaces["f"]); + } + + void testParse_AttributeWithNamespaceNoPrefix() { + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse( + "<query xmlns='http://swift.im' xmlns:f='http://swift.im/f' attr='3'/>")); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), client_.events[0].attributes.getEntries().size()); + CPPUNIT_ASSERT_EQUAL(std::string("attr"), client_.events[0].attributes.getEntries()[0].getAttribute().getName()); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].attributes.getEntries()[0].getAttribute().getNamespace()); + CPPUNIT_ASSERT_EQUAL(std::string(""), client_.events[0].attributes.getEntries()[0].getAttribute().getPrefix()); CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), client_.events[0].namespaces.size()); CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im"), client_.events[0].namespaces[""]); CPPUNIT_ASSERT_EQUAL(std::string("http://swift.im/f"), client_.events[0].namespaces["f"]); @@ -373,25 +392,52 @@ class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_ASSERT(!testling.parse("<?xml-stylesheet type=\"text/xsl\" href=\"Sample.xsl\"?>")); } + void testParse_ProcessingPrefixedElement() { + client_.testingStartElementPrefix = true; + ParserType testling(&client_); + + CPPUNIT_ASSERT(testling.parse("<prefix:message xmlns='uri' xmlns:prefix='uriPrefix'/>")); + + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), client_.events.size()); + + CPPUNIT_ASSERT_EQUAL(Client::StartElementPrefix, client_.events[0].type); + CPPUNIT_ASSERT_EQUAL(std::string("message"), client_.events[0].data); + CPPUNIT_ASSERT_EQUAL(std::string("uriPrefix"), client_.events[0].ns); + CPPUNIT_ASSERT_EQUAL(std::string("prefix"), client_.events[0].prefix); + + CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[1].type); + CPPUNIT_ASSERT_EQUAL(std::string("message"), client_.events[1].data); + CPPUNIT_ASSERT_EQUAL(std::string("uriPrefix"), client_.events[1].ns); + } + private: class Client : public XMLParserClient { public: using NamespaceMap = std::unordered_map<std::string /* prefix */, std::string /* uri */>; - enum Type { StartElement, EndElement, CharacterData, NamespaceDefined }; + enum Type { StartElement, StartElementPrefix, EndElement, CharacterData, NamespaceDefined }; struct Event { Event( Type type, const std::string& data, const std::string& ns, + const std::string& prefix, + const AttributeMap& attributes, + NamespaceMap namespaces) + : type(type), data(data), ns(ns), prefix(prefix), attributes(attributes), namespaces(std::move(namespaces)) {} + Event( + Type type, + const std::string& data, + const std::string& ns, const AttributeMap& attributes, NamespaceMap namespaces = {}) - : type(type), data(data), ns(ns), attributes(attributes), namespaces(std::move(namespaces)) {} + : Event(type, data, ns, {}, attributes, std::move(namespaces)) {} Event(Type type, const std::string& data, const std::string& ns = std::string()) - : type(type), data(data), ns(ns) {} + : Event(type, data, ns, "", AttributeMap(), NamespaceMap()) {} Type type; std::string data; std::string ns; + std::string prefix; AttributeMap attributes; NamespaceMap namespaces; }; @@ -399,9 +445,15 @@ class XMLParserTest : public CppUnit::TestFixture { Client() {} void handleStartElement(const std::string& element, const std::string& ns, const AttributeMap& attributes) override { + if (testingStartElementPrefix) return; events.push_back(Event(StartElement, element, ns, attributes, std::move(namespaces_))); } + void handleStartElementPrefix(const std::string& prefix, const std::string& uri, const std::string& name, const std::string&, const std::string&, const AttributeMap&) override { + if (!testingStartElementPrefix) return; + events.push_back(Event(StartElementPrefix, name, uri, prefix, AttributeMap(), NamespaceMap())); + } + void handleEndElement(const std::string& element, const std::string& ns) override { events.push_back(Event(EndElement, element, ns)); } @@ -415,6 +467,7 @@ class XMLParserTest : public CppUnit::TestFixture { } std::vector<Event> events; + bool testingStartElementPrefix = false; private: NamespaceMap namespaces_; } client_; |