|
From: Frank M. H. <fm...@us...> - 2007-02-28 19:16:06
|
Update of /cvsroot/boost-sandbox/boost-sandbox/libs/thread_safe_signals/test In directory sc8-pr-cvs3.sourceforge.net:/tmp/cvs-serv30354 Added Files: dead_slot_test.cpp deletion_test.cpp ordering_test.cpp signal_n_test.cpp signal_test.cpp Log Message: Added test programs from boost/libs/signals/test --- NEW FILE: signal_test.cpp --- // Boost.Signals library // Copyright Douglas Gregor 2001-2003. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include <boost/test/minimal.hpp> #include <boost/signal.hpp> #include <functional> #include <iostream> template<typename T> struct max_or_default { typedef T result_type; template<typename InputIterator> typename InputIterator::value_type operator()(InputIterator first, InputIterator last) const { if (first == last) return T(); T max = *first++; for (; first != last; ++first) max = (*first > max)? *first : max; return max; } }; struct make_int { make_int(int n, int cn) : N(n), CN(cn) {} int operator()() { return N; } int operator()() const { return CN; } int N; int CN; }; template<int N> struct make_increasing_int { make_increasing_int() : n(N) {} int operator()() const { return n++; } mutable int n; }; static void test_zero_args() { make_int i42(42, 41); make_int i2(2, 1); make_int i72(72, 71); make_int i63(63, 63); make_int i62(62, 61); { boost::signal<int (), max_or_default<int> > s0; std::cout << "sizeof(signal) = " << sizeof(s0) << std::endl; boost::BOOST_SIGNALS_NAMESPACE::connection c2 = s0.connect(i2); boost::BOOST_SIGNALS_NAMESPACE::connection c72 = s0.connect(72, i72); boost::BOOST_SIGNALS_NAMESPACE::connection c62 = s0.connect(60, i62); boost::BOOST_SIGNALS_NAMESPACE::connection c42 = s0.connect(i42); BOOST_CHECK(s0() == 72); s0.disconnect(72); BOOST_CHECK(s0() == 62); c72.disconnect(); // Double-disconnect should be safe BOOST_CHECK(s0() == 62); s0.disconnect(72); // Triple-disconect should be safe BOOST_CHECK(s0() == 62); // Also connect 63 in the same group as 62 s0.connect(60, i63); BOOST_CHECK(s0() == 63); // Disconnect all of the 60's s0.disconnect(60); BOOST_CHECK(s0() == 42); c42.disconnect(); BOOST_CHECK(s0() == 2); c2.disconnect(); BOOST_CHECK(s0() == 0); } { boost::signal<int (), max_or_default<int> > s0; boost::BOOST_SIGNALS_NAMESPACE::connection c2 = s0.connect(i2); boost::BOOST_SIGNALS_NAMESPACE::connection c72 = s0.connect(i72); boost::BOOST_SIGNALS_NAMESPACE::connection c62 = s0.connect(i62); boost::BOOST_SIGNALS_NAMESPACE::connection c42 = s0.connect(i42); const boost::signal<int (), max_or_default<int> >& cs0 = s0; BOOST_CHECK(cs0() == 72); } { make_increasing_int<7> i7; make_increasing_int<10> i10; boost::signal<int (), max_or_default<int> > s0; boost::BOOST_SIGNALS_NAMESPACE::connection c7 = s0.connect(i7); boost::BOOST_SIGNALS_NAMESPACE::connection c10 = s0.connect(i10); BOOST_CHECK(s0() == 10); BOOST_CHECK(s0() == 11); } } static void test_one_arg() { boost::signal<int (int value), max_or_default<int> > s1; s1.connect(std::negate<int>()); s1.connect(std::bind1st(std::multiplies<int>(), 2)); BOOST_CHECK(s1(1) == 2); BOOST_CHECK(s1(-1) == 1); } static void test_signal_signal_connect() { boost::signal<int (int value), max_or_default<int> > s1; s1.connect(std::negate<int>()); BOOST_CHECK(s1(3) == -3); { boost::signal<int (int value), max_or_default<int> > s2; s1.connect(s2); s2.connect(std::bind1st(std::multiplies<int>(), 2)); s2.connect(std::bind1st(std::multiplies<int>(), -3)); BOOST_CHECK(s2(-3) == 9); BOOST_CHECK(s1(3) == 6); } // s2 goes out of scope and disconnects BOOST_CHECK(s1(3) == -3); } int test_main(int, char* []) { test_zero_args(); test_one_arg(); test_signal_signal_connect(); return 0; } --- NEW FILE: signal_n_test.cpp --- // Boost.Signals library // Copyright Douglas Gregor 2001-2003. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include <boost/test/minimal.hpp> #include <boost/signal.hpp> #include <functional> template<typename T> struct max_or_default { typedef T result_type; template<typename InputIterator> typename InputIterator::value_type operator()(InputIterator first, InputIterator last) const { if (first == last) return T(); T max = *first++; for (; first != last; ++first) max = (*first > max)? *first : max; return max; } }; struct make_int { make_int(int n, int cn) : N(n), CN(n) {} int operator()() { return N; } int operator()() const { return CN; } int N; int CN; }; template<int N> struct make_increasing_int { make_increasing_int() : n(N) {} int operator()() const { return n++; } mutable int n; }; int get_37() { return 37; } static void test_zero_args() { make_int i42(42, 41); make_int i2(2, 1); make_int i72(72, 71); make_int i63(63, 63); make_int i62(62, 61); { boost::signal0<int, max_or_default<int>, std::string> s0; boost::BOOST_SIGNALS_NAMESPACE::connection c2 = s0.connect(i2); boost::BOOST_SIGNALS_NAMESPACE::connection c72 = s0.connect("72", i72); boost::BOOST_SIGNALS_NAMESPACE::connection c62 = s0.connect("6x", i62); boost::BOOST_SIGNALS_NAMESPACE::connection c42 = s0.connect(i42); boost::BOOST_SIGNALS_NAMESPACE::connection c37 = s0.connect(&get_37); BOOST_CHECK(s0() == 72); s0.disconnect("72"); BOOST_CHECK(s0() == 62); c72.disconnect(); // Double-disconnect should be safe BOOST_CHECK(s0() == 62); s0.disconnect("72"); // Triple-disconect should be safe BOOST_CHECK(s0() == 62); // Also connect 63 in the same group as 62 s0.connect("6x", i63); BOOST_CHECK(s0() == 63); // Disconnect all of the 60's s0.disconnect("6x"); BOOST_CHECK(s0() == 42); c42.disconnect(); BOOST_CHECK(s0() == 37); c37.disconnect(); BOOST_CHECK(s0() == 2); c2.disconnect(); BOOST_CHECK(s0() == 0); } { boost::signal0<int, max_or_default<int> > s0; boost::BOOST_SIGNALS_NAMESPACE::connection c2 = s0.connect(i2); boost::BOOST_SIGNALS_NAMESPACE::connection c72 = s0.connect(i72); boost::BOOST_SIGNALS_NAMESPACE::connection c62 = s0.connect(i62); boost::BOOST_SIGNALS_NAMESPACE::connection c42 = s0.connect(i42); const boost::signal0<int, max_or_default<int> >& cs0 = s0; BOOST_CHECK(cs0() == 72); } { make_increasing_int<7> i7; make_increasing_int<10> i10; boost::signal0<int, max_or_default<int> > s0; boost::BOOST_SIGNALS_NAMESPACE::connection c7 = s0.connect(i7); boost::BOOST_SIGNALS_NAMESPACE::connection c10 = s0.connect(i10); BOOST_CHECK(s0() == 10); BOOST_CHECK(s0() == 11); } } static void test_one_arg() { boost::signal1<int, int, max_or_default<int> > s1; s1.connect(std::negate<int>()); s1.connect(std::bind1st(std::multiplies<int>(), 2)); BOOST_CHECK(s1(1) == 2); BOOST_CHECK(s1(-1) == 1); } static void test_signal_signal_connect() { boost::signal1<int, int, max_or_default<int> > s1; s1.connect(std::negate<int>()); BOOST_CHECK(s1(3) == -3); { boost::signal1<int, int, max_or_default<int> > s2; s1.connect(s2); s2.connect(std::bind1st(std::multiplies<int>(), 2)); s2.connect(std::bind1st(std::multiplies<int>(), -3)); BOOST_CHECK(s2(-3) == 9); BOOST_CHECK(s1(3) == 6); } // s2 goes out of scope and disconnects BOOST_CHECK(s1(3) == -3); } struct EventCounter { EventCounter() : count(0) {} void operator()() { ++count; } int count; }; static void test_ref() { EventCounter ec; boost::signal0<void> s; { boost::BOOST_SIGNALS_NAMESPACE::scoped_connection c = s.connect(boost::ref(ec)); BOOST_CHECK(ec.count == 0); s(); BOOST_CHECK(ec.count == 1); } s(); BOOST_CHECK(ec.count == 1); } int test_main(int, char* []) { test_zero_args(); test_one_arg(); test_signal_signal_connect(); test_ref(); return 0; } --- NEW FILE: ordering_test.cpp --- // Boost.Signals library // Copyright Douglas Gregor 2002-2004. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include <boost/test/minimal.hpp> #include <boost/signal.hpp> #include <iostream> #include <vector> #include <algorithm> #include <cstdlib> #include <ctime> std::vector<int> valuesOutput; bool ungrouped1 = false; bool ungrouped2 = false; bool ungrouped3 = false; struct emit_int { emit_int(int v) : value(v) {} void operator()() const { BOOST_CHECK(value == 42 || (!ungrouped1 && !ungrouped2 && !ungrouped3)); valuesOutput.push_back(value); std::cout << value << ' '; } private: int value; }; struct write_ungrouped1 { void operator()() const { BOOST_CHECK(!ungrouped1); ungrouped1 = true; std::cout << "(Ungrouped #1)" << ' '; } }; struct write_ungrouped2 { void operator()() const { BOOST_CHECK(!ungrouped2); ungrouped2 = true; std::cout << "(Ungrouped #2)" << ' '; } }; struct write_ungrouped3 { void operator()() const { BOOST_CHECK(!ungrouped3); ungrouped3 = true; std::cout << "(Ungrouped #3)" << ' '; } }; int test_main(int, char* []) { using namespace std; srand(time(0)); std::vector<int> sortedValues; boost::signal0<void> sig; sig.connect(write_ungrouped1()); for (int i = 0; i < 100; ++i) { #ifdef BOOST_NO_STDC_NAMESPACE int v = rand() % 100; #else int v = std::rand() % 100; #endif sortedValues.push_back(v); sig.connect(v, emit_int(v)); if (i == 50) { sig.connect(write_ungrouped2()); } } sig.connect(write_ungrouped3()); std::sort(sortedValues.begin(), sortedValues.end()); // 17 at beginning, 42 at end sortedValues.insert(sortedValues.begin(), 17); sig.connect(emit_int(17), boost::BOOST_SIGNALS_NAMESPACE::at_front); sortedValues.push_back(42); sig.connect(emit_int(42)); sig(); std::cout << std::endl; BOOST_CHECK(valuesOutput == sortedValues); BOOST_CHECK(ungrouped1); BOOST_CHECK(ungrouped2); BOOST_CHECK(ungrouped3); return 0; } --- NEW FILE: deletion_test.cpp --- // Boost.Signals library // Copyright Douglas Gregor 2001-2003. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include <boost/test/minimal.hpp> #include <boost/signal.hpp> #include <iostream> #include <string> static boost::BOOST_SIGNALS_NAMESPACE::connection connections[5]; static std::string test_output; struct remove_connection { explicit remove_connection(int v = 0, int i = -1) : value(v), idx(i) {} void operator()() const { if (idx >= 0) connections[idx].disconnect(); //return value; std::cout << value << " "; test_output += static_cast<char>(value + '0'); } int value; int idx; }; bool operator==(const remove_connection& x, const remove_connection& y) { return x.value == y.value && x.idx == y.idx; } static void test_remove_self() { boost::signal0<void> s0; connections[0] = s0.connect(remove_connection(0)); connections[1] = s0.connect(remove_connection(1)); connections[2] = s0.connect(remove_connection(2, 2)); connections[3] = s0.connect(remove_connection(3)); std::cout << "Deleting 2" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "013"); s0.disconnect_all_slots(); BOOST_CHECK(s0.empty()); connections[0] = s0.connect(remove_connection(0)); connections[1] = s0.connect(remove_connection(1)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3, 3)); std::cout << "Deleting 3" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "012"); s0.disconnect_all_slots(); BOOST_CHECK(s0.num_slots() == 0); connections[0] = s0.connect(remove_connection(0, 0)); connections[1] = s0.connect(remove_connection(1)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3)); std::cout << "Deleting 0" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "123"); std::cout << "Blocking 2" << std::endl; connections[2].block(); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "13"); std::cout << "Unblocking 2" << std::endl; connections[2].unblock(); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "123"); s0.disconnect_all_slots(); BOOST_CHECK(s0.empty()); connections[0] = s0.connect(remove_connection(0, 0)); connections[1] = s0.connect(remove_connection(1, 1)); connections[2] = s0.connect(remove_connection(2, 2)); connections[3] = s0.connect(remove_connection(3, 3)); std::cout << "Mass suicide" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == ""); } static void test_remove_prior() { boost::signal0<void> s0; connections[0] = s0.connect(remove_connection(0)); connections[1] = s0.connect(remove_connection(1, 0)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3)); std::cout << "1 removes 0" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "123"); s0.disconnect_all_slots(); BOOST_CHECK(s0.empty()); connections[0] = s0.connect(remove_connection(0)); connections[1] = s0.connect(remove_connection(1)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3, 2)); std::cout << "3 removes 2" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "013"); } static void test_remove_after() { boost::signal0<void> s0; connections[0] = s0.connect(remove_connection(0, 1)); connections[1] = s0.connect(remove_connection(1)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3)); std::cout << "0 removes 1" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "023"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "023"); s0.disconnect_all_slots(); BOOST_CHECK(s0.empty()); connections[0] = s0.connect(remove_connection(0)); connections[1] = s0.connect(remove_connection(1, 3)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3)); std::cout << "1 removes 3" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "012"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "012"); } static void test_bloodbath() { boost::signal0<void> s0; connections[0] = s0.connect(remove_connection(0, 1)); connections[1] = s0.connect(remove_connection(1, 1)); connections[2] = s0.connect(remove_connection(2, 0)); connections[3] = s0.connect(remove_connection(3, 2)); std::cout << "0 removes 1, 2 removes 0, 3 removes 2" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "023"); test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "3"); } static void test_disconnect_equal() { boost::signal0<void> s0; connections[0] = s0.connect(remove_connection(0)); connections[1] = s0.connect(remove_connection(1)); connections[2] = s0.connect(remove_connection(2)); connections[3] = s0.connect(remove_connection(3)); std::cout << "Deleting 2" << std::endl; test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "0123"); #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) connections[2].disconnect(); #else s0.disconnect(remove_connection(2)); #endif test_output = ""; s0(); std::cout << std::endl; BOOST_CHECK(test_output == "013"); } int test_main(int, char* []) { test_remove_self(); test_remove_prior(); test_remove_after(); test_bloodbath(); test_disconnect_equal(); return 0; } --- NEW FILE: dead_slot_test.cpp --- // Boost.Signals library // Copyright (C) Douglas Gregor 2001-2006. Use, modification and // distribution is subject to the Boost Software License, Version // 1.0. (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // For more information, see http://www.boost.org #include <boost/test/minimal.hpp> #include <boost/thread_safe_signal.hpp> #include <boost/bind.hpp> typedef boost::signal1<int, int> sig_type; class with_constant : public boost::BOOST_SIGNALS_NAMESPACE::trackable { public: with_constant(int c) : constant(c) {} int add(int i) { return i + constant; } private: int constant; }; void do_delayed_connect(with_constant* wc, sig_type& sig, sig_type::slot_type slot) { // Should invalidate the slot, so that we cannot connect to it delete wc; boost::BOOST_SIGNALS_NAMESPACE::connection c = sig.connect(slot); BOOST_CHECK(!c.connected()); } int test_main(int, char*[]) { sig_type s1; with_constant* wc1 = new with_constant(7); do_delayed_connect(wc1, s1, boost::bind(&with_constant::add, wc1, _1)); return 0; } |