/* * Copyright (c) 2010 Remko Tronçon * Licensed under the GNU General Public License v3. * See Documentation/Licenses/GPLv3.txt for more information. */ #include #include #include #include "Swiften/Base/String.h" #include "Swiften/Parser/XMLParserClient.h" #ifdef HAVE_EXPAT #include "Swiften/Parser/ExpatParser.h" #endif #ifdef HAVE_LIBXML #include "Swiften/Parser/LibXMLParser.h" #endif using namespace Swift; template class XMLParserTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE(XMLParserTest); CPPUNIT_TEST(testParse_NestedElements); CPPUNIT_TEST(testParse_ElementInNamespacedElement); CPPUNIT_TEST(testParse_CharacterData); CPPUNIT_TEST(testParse_NamespacePrefix); CPPUNIT_TEST(testParse_UnhandledXML); CPPUNIT_TEST(testParse_InvalidXML); CPPUNIT_TEST(testParse_InErrorState); CPPUNIT_TEST(testParse_Incremental); CPPUNIT_TEST(testParse_WhitespaceInAttribute); CPPUNIT_TEST_SUITE_END(); public: void testParse_NestedElements() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse( "" "" "")); CPPUNIT_ASSERT_EQUAL(static_cast(4), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(static_cast(1), client_.events[0].attributes.size()); CPPUNIT_ASSERT_EQUAL(String("get"), client_.events[0].attributes["type"]); CPPUNIT_ASSERT_EQUAL(String(), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[1].data); CPPUNIT_ASSERT_EQUAL(static_cast(0), client_.events[1].attributes.size()); CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[1].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[2].data); CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[2].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[3].data); CPPUNIT_ASSERT_EQUAL(String(), client_.events[3].ns); } void testParse_ElementInNamespacedElement() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse( "" "Swift" "")); CPPUNIT_ASSERT_EQUAL(static_cast(5), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(static_cast(0), client_.events[0].attributes.size()); CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("name"), client_.events[1].data); CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[1].ns); CPPUNIT_ASSERT_EQUAL(Client::CharacterData, client_.events[2].type); CPPUNIT_ASSERT_EQUAL(String("Swift"), client_.events[2].data); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); CPPUNIT_ASSERT_EQUAL(String("name"), client_.events[3].data); CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[3].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[4].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[4].data); CPPUNIT_ASSERT_EQUAL(String("jabber:iq:version"), client_.events[4].ns); } void testParse_CharacterData() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse("blabliblo")); CPPUNIT_ASSERT_EQUAL(static_cast(7), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("html"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(Client::CharacterData, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[1].data); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[2].type); CPPUNIT_ASSERT_EQUAL(String("i"), client_.events[2].data); CPPUNIT_ASSERT_EQUAL(Client::CharacterData, client_.events[3].type); CPPUNIT_ASSERT_EQUAL(String("bli"), client_.events[3].data); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[4].type); CPPUNIT_ASSERT_EQUAL(String("i"), client_.events[4].data); CPPUNIT_ASSERT_EQUAL(Client::CharacterData, client_.events[5].type); CPPUNIT_ASSERT_EQUAL(String("blo"), client_.events[5].data); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[6].type); CPPUNIT_ASSERT_EQUAL(String("html"), client_.events[6].data); } void testParse_NamespacePrefix() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse("")); CPPUNIT_ASSERT_EQUAL(static_cast(4), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("x"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[0].ns); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("y"), client_.events[1].data); CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[1].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); CPPUNIT_ASSERT_EQUAL(String("y"), client_.events[2].data); CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[2].ns); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[3].type); CPPUNIT_ASSERT_EQUAL(String("x"), client_.events[3].data); CPPUNIT_ASSERT_EQUAL(String("bla"), client_.events[3].ns); } void testParse_UnhandledXML() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse("")); CPPUNIT_ASSERT_EQUAL(static_cast(2), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[1].data); } void testParse_InvalidXML() { ParserType testling(&client_); CPPUNIT_ASSERT(!testling.parse("")); } void testParse_InErrorState() { ParserType testling(&client_); CPPUNIT_ASSERT(!testling.parse("")); CPPUNIT_ASSERT(!testling.parse("")); } void testParse_Incremental() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse("")); CPPUNIT_ASSERT_EQUAL(static_cast(2), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("iq"), client_.events[1].data); } void testParse_WhitespaceInAttribute() { ParserType testling(&client_); CPPUNIT_ASSERT(testling.parse( "")); CPPUNIT_ASSERT(testling.parse( "")); CPPUNIT_ASSERT_EQUAL(static_cast(3), client_.events.size()); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[0].type); CPPUNIT_ASSERT_EQUAL(String("query"), client_.events[0].data); CPPUNIT_ASSERT_EQUAL(Client::StartElement, client_.events[1].type); CPPUNIT_ASSERT_EQUAL(String("presence"), client_.events[1].data); CPPUNIT_ASSERT_EQUAL(Client::EndElement, client_.events[2].type); CPPUNIT_ASSERT_EQUAL(String("presence"), client_.events[2].data); } private: class Client : public XMLParserClient { public: enum Type { StartElement, EndElement, CharacterData }; struct Event { Event( Type type, const String& data, const String& ns, const AttributeMap& attributes) : type(type), data(data), ns(ns), attributes(attributes) {} Event(Type type, const String& data, const String& ns = String()) : type(type), data(data), ns(ns) {} Type type; String data; String ns; AttributeMap attributes; }; Client() {} virtual void handleStartElement(const String& element, const String& ns, const AttributeMap& attributes) { events.push_back(Event(StartElement, element, ns, attributes)); } virtual void handleEndElement(const String& element, const String& ns) { events.push_back(Event(EndElement, element, ns)); } virtual void handleCharacterData(const String& data) { events.push_back(Event(CharacterData, data)); } std::vector events; } client_; }; #ifdef HAVE_EXPAT CPPUNIT_TEST_SUITE_REGISTRATION(XMLParserTest); #endif #ifdef HAVE_LIBXML CPPUNIT_TEST_SUITE_REGISTRATION(XMLParserTest); #endif