1 // thread_safe_signals library 2 // Some assorted tests to expose various bugs that existed at some point, 3 // to make sure they stay fixed 4 5 // Copyright Frank Mori Hess 2008 6 // Use, modification and 7 // distribution is subject to the Boost Software License, Version 8 // 1.0. (See accompanying file LICENSE_1_0.txt or copy at 9 // http://www.boost.org/LICENSE_1_0.txt) 10 11 // For more information, see http://www.boost.org 12 13 #include <boost/signals2.hpp> 14 #define BOOST_TEST_MODULE regression_test 15 #include <boost/test/included/unit_test.hpp> 16 17 typedef boost::signals2::signal<void ()> sig0_type; 18 19 // combiner that returns the number of slots invoked 20 struct slot_counter { 21 typedef unsigned result_type; 22 template<typename InputIterator> operator ()slot_counter23 unsigned operator()(InputIterator first, InputIterator last) const 24 { 25 unsigned count = 0; 26 for (; first != last; ++first) 27 { 28 try 29 { 30 *first; 31 ++count; 32 } 33 catch(const boost::bad_weak_ptr &) 34 {} 35 } 36 return count; 37 } 38 }; 39 my_slot()40void my_slot() 41 { 42 } 43 my_connecting_slot(sig0_type & sig)44void my_connecting_slot(sig0_type &sig) 45 { 46 sig.connect(&my_slot); 47 } 48 slot_connect_test()49void slot_connect_test() 50 { 51 sig0_type sig; 52 sig.connect(sig0_type::slot_type(&my_connecting_slot, boost::ref(sig)).track(sig)); 53 /* 2008-02-28: the following signal invocation triggered a (bogus) failed assertion of _shared_state.unique() 54 at detail/signal_template.hpp:285 */ 55 sig(); 56 BOOST_CHECK(sig.num_slots() == 2); 57 sig.disconnect(&my_slot); 58 BOOST_CHECK(sig.num_slots() == 1); 59 /* 2008-03-11: checked iterator barfed on next line, due to bad semantics of copy construction 60 for boost::signals2::detail::grouped_list */ 61 sig(); 62 BOOST_CHECK(sig.num_slots() == 2); 63 } 64 65 /* 2008-03-10: we weren't disconnecting old connection in scoped_connection assignment operator */ scoped_connection_test()66void scoped_connection_test() 67 { 68 typedef boost::signals2::signal<void (), slot_counter> signal_type; 69 signal_type sig; 70 { 71 boost::signals2::scoped_connection conn(sig.connect(&my_slot)); 72 BOOST_CHECK(sig() == 1); 73 conn = sig.connect(&my_slot); 74 BOOST_CHECK(sig() == 1); 75 } 76 BOOST_CHECK(sig() == 0); 77 } 78 79 // testsignal that returns a reference type 80 81 struct ref_returner 82 { 83 static int i; 84 ref_return_slotref_returner85 int& ref_return_slot() 86 { 87 return i; 88 } 89 }; 90 91 int ref_returner::i = 0; 92 reference_return_test()93void reference_return_test() 94 { 95 boost::signals2::signal<int& ()> rTest; 96 ref_returner rr; 97 rTest.connect(boost::bind(&ref_returner::ref_return_slot, &rr)); 98 int& r = *rTest(); 99 BOOST_CHECK(ref_returner::i == 0); 100 r = 1; 101 BOOST_CHECK(ref_returner::i == 1); 102 } 103 BOOST_AUTO_TEST_CASE(test_main)104BOOST_AUTO_TEST_CASE(test_main) 105 { 106 slot_connect_test(); 107 scoped_connection_test(); 108 reference_return_test(); 109 } 110