• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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()40 void my_slot()
41 {
42 }
43 
my_connecting_slot(sig0_type & sig)44 void my_connecting_slot(sig0_type &sig)
45 {
46   sig.connect(&my_slot);
47 }
48 
slot_connect_test()49 void 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()66 void 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()93 void 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)104 BOOST_AUTO_TEST_CASE(test_main)
105 {
106   slot_connect_test();
107   scoped_connection_test();
108   reference_return_test();
109 }
110