From e1a2d258479cd915e8c30c5c996b58da3da3e55d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Sat, 11 Jul 2009 17:27:08 +0200 Subject: PayloadParserFactoryCollection additions. Added the ability to set a default PayloadParserFactory. Check factories in reverse order. Add PayloadParserFactoryCollection unit test. diff --git a/Swiften/Parser/PayloadParserFactoryCollection.cpp b/Swiften/Parser/PayloadParserFactoryCollection.cpp index f361ce8..6d3a4cf 100644 --- a/Swiften/Parser/PayloadParserFactoryCollection.cpp +++ b/Swiften/Parser/PayloadParserFactoryCollection.cpp @@ -6,7 +6,7 @@ namespace Swift { -PayloadParserFactoryCollection::PayloadParserFactoryCollection() { +PayloadParserFactoryCollection::PayloadParserFactoryCollection() : defaultFactory_(NULL) { } void PayloadParserFactoryCollection::addFactory(PayloadParserFactory* factory) { @@ -17,11 +17,15 @@ void PayloadParserFactoryCollection::removeFactory(PayloadParserFactory* factory factories_.erase(remove(factories_.begin(), factories_.end(), factory), factories_.end()); } +void PayloadParserFactoryCollection::setDefaultFactory(PayloadParserFactory* factory) { + defaultFactory_ = factory; +} + PayloadParserFactory* PayloadParserFactoryCollection::getPayloadParserFactory(const String& element, const String& ns, const AttributeMap& attributes) { - std::vector::const_iterator i = std::find_if( - factories_.begin(), factories_.end(), + std::vector::reverse_iterator i = std::find_if( + factories_.rbegin(), factories_.rend(), boost::bind(&PayloadParserFactory::canParse, _1, element, ns, attributes)); - return (i != factories_.end() ? *i : NULL); + return (i != factories_.rend() ? *i : defaultFactory_); } } diff --git a/Swiften/Parser/PayloadParserFactoryCollection.h b/Swiften/Parser/PayloadParserFactoryCollection.h index fad94c3..80a763b 100644 --- a/Swiften/Parser/PayloadParserFactoryCollection.h +++ b/Swiften/Parser/PayloadParserFactoryCollection.h @@ -15,10 +15,13 @@ namespace Swift { void addFactory(PayloadParserFactory* factory); void removeFactory(PayloadParserFactory* factory); + void setDefaultFactory(PayloadParserFactory* factory); + PayloadParserFactory* getPayloadParserFactory(const String& element, const String& ns, const AttributeMap& attributes); private: std::vector factories_; + PayloadParserFactory* defaultFactory_; }; } diff --git a/Swiften/Parser/UnitTest/Makefile.inc b/Swiften/Parser/UnitTest/Makefile.inc index 4f9c59e..be570d2 100644 --- a/Swiften/Parser/UnitTest/Makefile.inc +++ b/Swiften/Parser/UnitTest/Makefile.inc @@ -1,4 +1,5 @@ UNITTEST_SOURCES += \ + Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp \ Swiften/Parser/UnitTest/XMPPParserTest.cpp \ Swiften/Parser/UnitTest/StanzaParserTest.cpp \ Swiften/Parser/UnitTest/MessageParserTest.cpp \ diff --git a/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp b/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp new file mode 100644 index 0000000..bfd2c2c --- /dev/null +++ b/Swiften/Parser/UnitTest/PayloadParserFactoryCollectionTest.cpp @@ -0,0 +1,97 @@ +#include +#include + +#include "Swiften/Parser/PayloadParserFactoryCollection.h" +#include "Swiften/Parser/PayloadParserFactory.h" + +using namespace Swift; + +class PayloadParserFactoryCollectionTest : public CppUnit::TestFixture +{ + CPPUNIT_TEST_SUITE(PayloadParserFactoryCollectionTest); + CPPUNIT_TEST(testGetPayloadParserFactory); + CPPUNIT_TEST(testGetPayloadParserFactory_NoMatchingFactory); + CPPUNIT_TEST(testGetPayloadParserFactory_TwoMatchingFactories); + CPPUNIT_TEST(testGetPayloadParserFactory_MatchWithDefaultFactory); + CPPUNIT_TEST(testGetPayloadParserFactory_NoMatchWithDefaultFactory); + CPPUNIT_TEST_SUITE_END(); + + public: + PayloadParserFactoryCollectionTest() {} + + void setUp() { + } + + void tearDown() { + } + + void testGetPayloadParserFactory() { + PayloadParserFactoryCollection testling; + DummyFactory factory1("foo"); + testling.addFactory(&factory1); + DummyFactory factory2("bar"); + testling.addFactory(&factory2); + DummyFactory factory3("baz"); + testling.addFactory(&factory3); + + PayloadParserFactory* factory = testling.getPayloadParserFactory("bar", "", AttributeMap()); + + CPPUNIT_ASSERT(factory == &factory2); + } + + void testGetPayloadParserFactory_NoMatchingFactory() { + PayloadParserFactoryCollection testling; + DummyFactory factory("foo"); + + CPPUNIT_ASSERT(!testling.getPayloadParserFactory("bar", "", AttributeMap())); + } + + void testGetPayloadParserFactory_TwoMatchingFactories() { + PayloadParserFactoryCollection testling; + DummyFactory factory1("foo"); + testling.addFactory(&factory1); + DummyFactory factory2("foo"); + testling.addFactory(&factory2); + + PayloadParserFactory* factory = testling.getPayloadParserFactory("foo", "", AttributeMap()); + + CPPUNIT_ASSERT(factory == &factory2); + } + + void testGetPayloadParserFactory_MatchWithDefaultFactory() { + PayloadParserFactoryCollection testling; + DummyFactory factory1("foo"); + testling.addFactory(&factory1); + DummyFactory factory2; + testling.setDefaultFactory(&factory2); + + PayloadParserFactory* factory = testling.getPayloadParserFactory("foo", "", AttributeMap()); + + CPPUNIT_ASSERT(factory == &factory1); + } + + void testGetPayloadParserFactory_NoMatchWithDefaultFactory() { + PayloadParserFactoryCollection testling; + DummyFactory factory1("foo"); + testling.addFactory(&factory1); + DummyFactory factory2; + testling.setDefaultFactory(&factory2); + + PayloadParserFactory* factory = testling.getPayloadParserFactory("baz", "", AttributeMap()); + + CPPUNIT_ASSERT(factory == &factory2); + } + + + private: + struct DummyFactory : public PayloadParserFactory { + DummyFactory(const String& element = "") : element(element) {} + virtual bool canParse(const String& e, const String&, const AttributeMap&) const { + return element.isEmpty() ? true : element == e; + } + virtual PayloadParser* createPayloadParser() { return NULL; } + String element; + }; +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(PayloadParserFactoryCollectionTest); -- cgit v0.10.2-6-g49f6