diff options
Diffstat (limited to 'contrib/native/client/src/test/CollectionsTest.cpp')
-rw-r--r-- | contrib/native/client/src/test/CollectionsTest.cpp | 215 |
1 files changed, 215 insertions, 0 deletions
diff --git a/contrib/native/client/src/test/CollectionsTest.cpp b/contrib/native/client/src/test/CollectionsTest.cpp new file mode 100644 index 000000000..ebac941c7 --- /dev/null +++ b/contrib/native/client/src/test/CollectionsTest.cpp @@ -0,0 +1,215 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <string> +#include <vector> + +#include <boost/assign.hpp> +#include <boost/shared_ptr.hpp> + +#include <cppunit/TestFixture.h> +#include <cppunit/extensions/HelperMacros.h> + +#include "drill/collections.hpp" +#include "collectionsImpl.hpp" + +namespace { +template<typename T, typename Iter> +class DrillVectorIteratorImpl: public Drill::impl::DrillIteratorImpl<T> { +public: + typedef DrillVectorIteratorImpl<T, Iter> type; + typedef Drill::impl::DrillIteratorImpl<T> supertype; + + DrillVectorIteratorImpl(const Iter& it): m_it(it) {}; + + T& operator*() const { return m_it.operator *();} + T* operator->() const { return m_it.operator->(); } + + operator typename Drill::impl::DrillIteratorImpl<const T>::iterator_ptr() const { return typename Drill::impl::DrillIteratorImpl<const T>::iterator_ptr(new DrillVectorIteratorImpl<const T, Iter>(m_it)); } + + DrillVectorIteratorImpl& operator++() { + m_it++; return *this; + } + + bool operator==(const supertype& x) const { + const type& other(dynamic_cast<const type&>(x)); + return m_it == other.m_it; + } + + bool operator!=(const supertype& x) const { return !(*this==x); } + +private: + Iter m_it; +}; + +template<typename T> +class DrillVectorImpl: public Drill::impl::DrillCollectionImpl<T> { +public: + typedef Drill::impl::DrillCollectionImpl<T> supertype; + + typedef typename supertype::iterator_ptr iterator_ptr; + typedef typename supertype::const_iterator_ptr const_iterator_ptr; + + DrillVectorImpl() {} + DrillVectorImpl(const std::vector<T>& v): m_vector(v) {}; + + iterator_ptr begin() { return iterator_ptr(new IteratorImpl(m_vector.begin()));} + const_iterator_ptr begin() const { return const_iterator_ptr(new ConstIteratorImpl(m_vector.begin()));} + iterator_ptr end() { return iterator_ptr(new IteratorImpl(m_vector.end()));} + const_iterator_ptr end() const { return const_iterator_ptr(new ConstIteratorImpl(m_vector.end()));} + +private: + typedef DrillVectorIteratorImpl<T, typename std::vector<T>::iterator> IteratorImpl; + typedef DrillVectorIteratorImpl<const T, typename std::vector<T>::const_iterator> ConstIteratorImpl; + std::vector<T> m_vector; +}; + +template<typename T> +class DrillVector: public Drill::DrillCollection<T> { +public: + DrillVector(const std::vector<T>& v): Drill::DrillCollection<T>(typename Drill::DrillCollection<T>::ImplPtr(new DrillVectorImpl<T>(v))) {} +}; + + +struct SimpleInterface { + virtual ~SimpleInterface() {} + virtual const std::string& foo() const = 0; + virtual std::string bar() = 0; +}; + +class SimpleImplementation: public SimpleInterface { +public: + SimpleImplementation(const std::string& foo, const std::string& bar): m_foo(foo), m_bar(bar) {} + + const std::string& foo() const { return m_foo; } + std::string bar() { return m_bar; } + +private: + std::string m_foo; + std::string m_bar; +}; + +} // anonymous namespace + +class CollectionsTest: public CppUnit::TestFixture { +public: + CollectionsTest() {} + + + CPPUNIT_TEST_SUITE( CollectionsTest ); + CPPUNIT_TEST( testSimpleCollection ); + CPPUNIT_TEST( testSimpleConstCollection ); + CPPUNIT_TEST( testDrillVectorConstIterator ); + CPPUNIT_TEST( testDrillVectorIterator ); + CPPUNIT_TEST( testDrillVectorConstPointer ); + CPPUNIT_TEST_SUITE_END(); + + void testSimpleCollection() { + // basic test/proof of concept for collections.hpp + + std::vector<std::string> v = boost::assign::list_of("foo")("bar"); + + DrillVector<std::string> drillCollection(v); + std::vector<std::string> result; + for(DrillVector<std::string>::const_iterator it = drillCollection.begin(); it != drillCollection.end(); ++it) { + result.push_back(*it); + } + + CPPUNIT_ASSERT(result == v); + } + + void testSimpleConstCollection() { + std::vector<std::string> v = boost::assign::list_of("foo")("bar"); + + const DrillVector<std::string> drillCollection(v); + std::vector<std::string> result; + for(DrillVector<std::string>::const_iterator it = drillCollection.begin(); it != drillCollection.end(); ++it) { + result.push_back(*it); + } + + CPPUNIT_ASSERT(result == v); + } + + void testDrillVectorConstIterator() { + typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector; + SimpleInterfaceVector v; + + v.push_back(SimpleImplementation("foo1", "bar1")); + v.push_back(SimpleImplementation("foo2", "bar2")); + + std::vector<std::string> resultFoo; + SimpleInterfaceVector::const_iterator it(v.begin()); + for(; it != v.end(); ++it) { + resultFoo.push_back(it->foo()); + // const-correctness: The following line does not compile if uncommented! + // resultBar.push_back(it->bar()); + } + + std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2"); + + CPPUNIT_ASSERT(resultFoo == expectedFoo); + } + + void testDrillVectorIterator() { + typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector; + SimpleInterfaceVector v; + + v.push_back(SimpleImplementation("foo1", "bar1")); + v.push_back(SimpleImplementation("foo2", "bar2")); + + std::vector<std::string> resultFoo; + std::vector<std::string> resultBar; + SimpleInterfaceVector::iterator it; + for(it = v.begin(); it != v.end(); ++it) { + resultFoo.push_back(it->foo()); + resultBar.push_back(it->bar()); + } + + std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2"); + std::vector<std::string> expectedBar = boost::assign::list_of("bar1")("bar2"); + + CPPUNIT_ASSERT(resultFoo == expectedFoo); + CPPUNIT_ASSERT(resultBar == expectedBar); + } + + // Check some const-correctness issues + // by getting iterators of a const collection + void testDrillVectorConstPointer() { + typedef Drill::DrillVector<SimpleInterface, SimpleImplementation> SimpleInterfaceVector; + boost::shared_ptr<SimpleInterfaceVector> v(new SimpleInterfaceVector); + + const SimpleInterfaceVector* vv(v.get()); + + v->push_back(SimpleImplementation("foo1", "bar1")); + v->push_back(SimpleImplementation("foo2", "bar2")); + + std::vector<std::string> resultFoo; + std::vector<std::string> resultBar; + SimpleInterfaceVector::const_iterator it; + for(it = vv->begin(); it != vv->end(); ++it) { + resultFoo.push_back(it->foo()); + } + + std::vector<std::string> expectedFoo = boost::assign::list_of("foo1")("foo2"); + + CPPUNIT_ASSERT(resultFoo == expectedFoo); + } + +}; + +CPPUNIT_TEST_SUITE_REGISTRATION( CollectionsTest ); |