summaryrefslogtreecommitdiff
path: root/tests/test_dynamic_list.cc
diff options
context:
space:
mode:
authorDaniel Burrows <dburrows@debian.org>2010-04-30 22:39:42 -0700
committerDaniel Burrows <dburrows@debian.org>2010-04-30 22:39:42 -0700
commitf02d4ba078bea4763789329d09bd8475967941e9 (patch)
treee163c95de2db23528f2133dea864d80fcd3d9847 /tests/test_dynamic_list.cc
parent445b7bb89b548d1dc61f66e7912fb50850639ef6 (diff)
downloadaptitude-f02d4ba078bea4763789329d09bd8475967941e9.tar.gz
Add tests of the new dynamic_list class.
Diffstat (limited to 'tests/test_dynamic_list.cc')
-rw-r--r--tests/test_dynamic_list.cc310
1 files changed, 310 insertions, 0 deletions
diff --git a/tests/test_dynamic_list.cc b/tests/test_dynamic_list.cc
new file mode 100644
index 00000000..ca1483ed
--- /dev/null
+++ b/tests/test_dynamic_list.cc
@@ -0,0 +1,310 @@
+#include <generic/util/dynamic_list.h>
+#include <generic/util/dynamic_list_impl.h>
+
+#include <boost/test/unit_test.hpp>
+#include <boost/variant.hpp>
+
+using aptitude::util::dynamic_list;
+using aptitude::util::dynamic_list_impl;
+using aptitude::util::enumerator;
+
+namespace
+{
+ template<typename T>
+ class appended_call
+ {
+ T value;
+
+ public:
+ appended_call(const T &_value)
+ : value(_value)
+ {
+ }
+
+ const T get_value() const { return value; }
+ bool operator==(const appended_call &other) const
+ {
+ return value == other.value;
+ }
+
+ bool operator!=(const appended_call &other) const
+ {
+ return value != other.value;
+ }
+ };
+
+ template<typename T>
+ std::ostream &operator<<(std::ostream &out,
+ const appended_call<T> &call)
+ {
+ return out << "appended(" << call.get_value() << ")";
+ }
+
+ template<typename T>
+ class removed_call
+ {
+ T value;
+
+ public:
+ removed_call(const T &_value)
+ : value(_value)
+ {
+ }
+
+ const T get_value() const { return value; }
+ bool operator==(const removed_call &other) const
+ {
+ return value == other.value;
+ }
+ bool operator!=(const removed_call &other) const
+ {
+ return value != other.value;
+ }
+ };
+
+ template<typename T>
+ std::ostream &operator<<(std::ostream &out,
+ const removed_call<T> &call)
+ {
+ return out << "removed(" << call.get_value() << ")";
+ }
+
+ template<typename T>
+ class list_signal
+ {
+ public:
+ typedef boost::variant<appended_call<T>, removed_call<T> > value_type;
+
+ private:
+ value_type value;
+
+ public:
+ list_signal(const appended_call<T> &_value)
+ : value(_value)
+ {
+ }
+
+ list_signal(const removed_call<T> &_value)
+ : value(_value)
+ {
+ }
+
+ list_signal(const value_type &_value)
+ : value(_value)
+ {
+ }
+
+ const value_type &get_value() const { return value; }
+
+ bool operator==(const list_signal &other) const
+ {
+ return value == other.value;
+ }
+
+ bool operator!=(const list_signal &other) const
+ {
+ return !(value == other.value);
+ }
+ };
+
+ template<typename T>
+ std::ostream &operator<<(std::ostream &out, const list_signal<T> &signal)
+ {
+ return out << signal.get_value();
+ }
+
+ template<typename T>
+ class dynamic_list_signals
+ {
+ std::vector<list_signal<T> > calls;
+
+ void appended(const T &value)
+ {
+ calls.push_back(appended_call<T>(value));
+ }
+
+ void removed(const T &value)
+ {
+ calls.push_back(removed_call<T>(value));
+ }
+
+ dynamic_list_signals(const dynamic_list_signals &);
+
+ public:
+ dynamic_list_signals()
+ {
+ }
+
+ ~dynamic_list_signals()
+ {
+ }
+
+ void attach(dynamic_list<T> &list)
+ {
+ list.signal_appended.connect(sigc::mem_fun(*this, &dynamic_list_signals::appended));
+ list.signal_removed.connect(sigc::mem_fun(*this, &dynamic_list_signals::removed));
+
+ BOOST_REQUIRE(list.signal_appended.size() > 0);
+ }
+
+ /** \brief To be used only by test code. */
+ void push_back(const list_signal<T> &signal)
+ {
+ calls.push_back(signal);
+ }
+
+ typedef typename std::vector<list_signal<T> >::const_iterator const_iterator;
+ const_iterator begin() const { return calls.begin(); }
+ const_iterator end() const { return calls.end(); }
+
+ bool operator==(const dynamic_list_signals &other) const
+ {
+ return calls == other.calls;
+ }
+
+ bool operator!=(const dynamic_list_signals &other) const
+ {
+ return calls != other.calls;
+ }
+ };
+
+ template<typename T>
+ std::ostream &operator<<(std::ostream &out,
+ const dynamic_list_signals<T> &signals)
+ {
+ out << "[";
+ for(typename dynamic_list_signals<T>::const_iterator
+ it = signals.begin(); it != signals.end(); ++it)
+ {
+ if(it != signals.begin())
+ out << ", ";
+ out << *it;
+ }
+
+ out << "]";
+
+ return out;
+ }
+
+ struct list_test
+ {
+ boost::shared_ptr<dynamic_list_impl<int> > valuesPtr;
+ dynamic_list_impl<int> &values;
+ dynamic_list_signals<int> signals;
+
+ std::vector<int> expected;
+
+ list_test()
+ : valuesPtr(dynamic_list_impl<int>::create()),
+ values(*valuesPtr),
+ signals()
+ {
+ values.append(1);
+ values.append(2);
+ values.append(3);
+ signals.attach(values);
+
+ expected.push_back(1);
+ expected.push_back(2);
+ expected.push_back(3);
+ }
+
+ std::vector<int> as_vector() const
+ {
+ std::vector<int> rval;
+ boost::shared_ptr<enumerator<int> > e = values.enumerate();
+ while(e->advance())
+ rval.push_back(e->get_current());
+
+ return rval;
+ }
+ };
+}
+
+BOOST_AUTO_TEST_CASE(listSignals)
+{
+ dynamic_list_signals<int> signals1, signals2, signals3;
+
+ typedef appended_call<int> app;
+ typedef removed_call<int> rem;
+
+ signals1.push_back(app(1));
+ signals1.push_back(app(2));
+ signals1.push_back(app(3));
+
+ signals2.push_back(app(1));
+ signals2.push_back(rem(2));
+ signals2.push_back(app(3));
+
+ signals3.push_back(app(1));
+ signals3.push_back(app(2));
+ signals3.push_back(app(3));
+
+ BOOST_CHECK_EQUAL(signals1, signals3);
+ BOOST_CHECK_EQUAL(signals3, signals1);
+ BOOST_CHECK_EQUAL_COLLECTIONS(signals1.begin(), signals1.end(),
+ signals3.begin(), signals3.end());
+ BOOST_CHECK_EQUAL_COLLECTIONS(signals3.begin(), signals3.end(),
+ signals1.begin(), signals1.end());
+
+ BOOST_CHECK_NE(signals1, signals2);
+ BOOST_CHECK_NE(signals2, signals1);
+ BOOST_CHECK_NE(signals2, signals3);
+ BOOST_CHECK_NE(signals3, signals2);
+}
+
+BOOST_AUTO_TEST_CASE(listSignalsAttach)
+{
+ dynamic_list_signals<int> signals, expected;
+ dynamic_list_impl<int> list;
+ signals.attach(list);
+
+ typedef appended_call<int> app;
+ typedef removed_call<int> rem;
+
+ expected.push_back(app(5));
+ expected.push_back(app(2));
+ expected.push_back(rem(5));
+
+ // Note: call the signals directly so we test the attachment and not
+ // the dynamic list.
+ list.signal_appended(5);
+ list.signal_appended(2);
+ list.signal_removed(5);
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
+ signals.begin(), signals.end());
+}
+
+BOOST_FIXTURE_TEST_CASE(dynamicListEnumerate, list_test)
+{
+ // Enumerate over the entries of the list and ensure that they're
+ // all accounted for.
+
+ std::vector<int> values_vector = as_vector();
+ BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
+ values_vector.begin(), values_vector.end());
+}
+
+BOOST_FIXTURE_TEST_CASE(dynamicListAppend, list_test)
+{
+ // Append some values, check that the proper signals were emitted,
+ // and check that the values are visible in the list.
+ values.append(4);
+ values.append(5);
+ values.append(6);
+
+ std::vector<int> values_vector = as_vector();
+ dynamic_list_signals<int> expected_calls;
+ for(int i = 4; i <= 6; ++i)
+ {
+ expected.push_back(i);
+ expected_calls.push_back(appended_call<int>(i));
+ }
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(),
+ values_vector.begin(), values_vector.end());
+
+ BOOST_CHECK_EQUAL_COLLECTIONS(expected_calls.begin(), expected_calls.end(),
+ signals.begin(), signals.end());
+}