1 // (C) Copyright Gennadiy Rozental 2005.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 // File : $RCSfile: unit_test_suite.hpp,v $
9 //
10 // Version : $Revision: 1.1.1.1 $
11 //
12 // Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
13 // ***************************************************************************
14
15 #ifndef BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
16 #define BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
17
18 // Boost.Test
19 #include <boost/test/detail/config.hpp>
20 #include <boost/test/detail/global_typedef.hpp>
21 #include <boost/test/utils/class_properties.hpp>
22 #include <boost/test/utils/callback.hpp>
23 #include <boost/test/detail/fwd_decl.hpp>
24 #include <boost/test/detail/workaround.hpp>
25
26 // Boost
27 #include <boost/shared_ptr.hpp>
28
29 // STL
30 #include <string> // for std::string
31 #include <list> // for std::list
32 #include <vector> // for std::list
33
34 #include <boost/test/detail/suppress_warnings.hpp>
35
36 //____________________________________________________________________________//
37
38 #define BOOST_TEST_CASE( function ) \
39 boost::unit_test::make_test_case( boost::unit_test::callback0<>(function), BOOST_TEST_STRINGIZE( function ) )
40 #define BOOST_CLASS_TEST_CASE( function, tc_instance ) \
41 boost::unit_test::make_test_case((function), BOOST_TEST_STRINGIZE( function ), tc_instance )
42 #define BOOST_TEST_SUITE( testsuite_name ) \
43 ( new boost::unit_test::test_suite( testsuite_name ) )
44
45 namespace boost {
46
47 namespace unit_test {
48
49 // ************************************************************************** //
50 // ************** test_unit ************** //
51 // ************************************************************************** //
52
53 class test_unit {
54 public:
55 enum { type = tut_any };
56
57 // Constructor
58 test_unit( const_string tu_name, test_unit_type t );
59
60 // dependencies management
61 void depends_on( test_unit* tu );
62 bool check_dependencies() const;
63
64 // Public r/o properties
65 typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl)) id_t;
66 readonly_property<test_unit_type> p_type; // type for this test unit
67 readonly_property<const_string> p_type_name; // "case"/"suite"
68 id_t p_id; // unique id for this test unit
69
70 // Public r/w properties
71 readwrite_property<std::string> p_name; // name for this test unit
72 readwrite_property<unsigned> p_timeout; // timeout for the test unit execution
73 readwrite_property<counter_t> p_expected_failures; // number of expected failured in this test unit
74
75 private:
76 // Data members
77 std::list<test_unit_id> m_dependencies;
78 };
79
80 // ************************************************************************** //
81 // ************** test_case_generator ************** //
82 // ************************************************************************** //
83
84 class test_unit_generator {
85 public:
86 virtual test_unit* next() const = 0;
87
88 protected:
~test_unit_generator()89 BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
90 };
91
92 // ************************************************************************** //
93 // ************** test_case ************** //
94 // ************************************************************************** //
95
96 class test_case : public test_unit {
97 public:
98 enum { type = tut_case };
99
100 // Constructor
101 test_case( const_string tc_name, callback0<> const& test_func );
102
103 // Access methods
test_func() const104 callback0<> const& test_func() const { return m_test_func; }
105
106 private:
107 friend class framework_impl;
~test_case()108 ~test_case() {}
109
110 // BOOST_MSVC <= 1200 have problems with callback as property
111 // Data members
112 callback0<> m_test_func;
113 };
114
115 // ************************************************************************** //
116 // ************** test_suite ************** //
117 // ************************************************************************** //
118
119 class test_suite : public test_unit {
120 public:
121 enum { type = tut_suite };
122
123 // Constructor
124 explicit test_suite( const_string ts_name = "Master" );
125
126 // test case list management
127 void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
128 void add( test_unit_generator const& gen, unsigned timeout = 0 );
129
130 protected:
131 friend void traverse_test_tree( test_suite const&, test_tree_visitor& );
132 friend class framework_impl;
~test_suite()133 virtual ~test_suite() {}
134
135 private:
136 // Data members
137 std::vector<test_unit_id> m_members;
138 };
139
140 // ************************************************************************** //
141 // ************** test_tree_visitor ************** //
142 // ************************************************************************** //
143
144 class test_tree_visitor {
145 public:
146 // test tree visitor interface
visit(test_case const &)147 virtual void visit( test_case const& ) {}
test_suite_start(test_suite const &)148 virtual bool test_suite_start( test_suite const& ) { return true; }
test_suite_finish(test_suite const &)149 virtual void test_suite_finish( test_suite const& ) {}
150
151 protected:
~test_tree_visitor()152 BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
153 };
154
155 // ************************************************************************** //
156 // ************** traverse_test_tree ************** //
157 // ************************************************************************** //
158
159 void traverse_test_tree( test_case const&, test_tree_visitor& );
160 void traverse_test_tree( test_suite const&, test_tree_visitor& );
161 void traverse_test_tree( test_unit_id id, test_tree_visitor& );
162
163 //____________________________________________________________________________//
164
165 inline void
traverse_test_tree(test_unit const & tu,test_tree_visitor & V)166 traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
167 {
168 if( tu.p_type == tut_case )
169 traverse_test_tree( static_cast<test_case const&>( tu ), V );
170 else
171 traverse_test_tree( static_cast<test_suite const&>( tu ), V );
172 }
173
174 //____________________________________________________________________________//
175
176 // ************************************************************************** //
177 // ************** test_case_counter ************** //
178 // ************************************************************************** //
179
180 struct test_case_counter : test_tree_visitor {
test_case_counterboost::unit_test::test_case_counter181 test_case_counter() : m_count( 0 ) {}
182
visitboost::unit_test::test_case_counter183 void visit( test_case const& ) { m_count++; }
184
185 counter_t m_count;
186 };
187
188 // ************************************************************************** //
189 // ************** test_aborted ************** //
190 // ************************************************************************** //
191
192 struct test_aborted {};
193
194 // ************************************************************************** //
195 // ************** object generators ************** //
196 // ************************************************************************** //
197
198 namespace ut_detail {
199
200 std::string normalize_test_case_name( const_string tu_name );
201
202 template<typename UserTestCase>
203 struct user_tc_method_invoker {
204 typedef void (UserTestCase::*test_method )();
205
user_tc_method_invokerboost::unit_test::ut_detail::user_tc_method_invoker206 user_tc_method_invoker( shared_ptr<UserTestCase> inst, test_method tm )
207 : m_inst( inst ), m_test_method( tm ) {}
208
operator ()boost::unit_test::ut_detail::user_tc_method_invoker209 void operator()() { ((*m_inst).*m_test_method)(); }
210
211 shared_ptr<UserTestCase> m_inst;
212 test_method m_test_method;
213 };
214
215 } // namespace ut_detail
216
217 //____________________________________________________________________________//
218
219 inline test_case*
make_test_case(callback0<> const & test_func,const_string tc_name)220 make_test_case( callback0<> const& test_func, const_string tc_name )
221 {
222 return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
223 }
224
225 //____________________________________________________________________________//
226
227 template<typename UserTestCase>
228 inline test_case*
make_test_case(void (UserTestCase::* test_method)(),const_string tc_name,boost::shared_ptr<UserTestCase> const & user_test_case)229 make_test_case( void (UserTestCase::*test_method )(),
230 const_string tc_name,
231 boost::shared_ptr<UserTestCase> const& user_test_case )
232 {
233 return new test_case( ut_detail::normalize_test_case_name( tc_name ),
234 ut_detail::user_tc_method_invoker<UserTestCase>( user_test_case, test_method ) );
235 }
236
237 //____________________________________________________________________________//
238
239 } // unit_test
240
241 } // namespace boost
242
243 //____________________________________________________________________________//
244
245 #include <boost/test/detail/enable_warnings.hpp>
246
247 // ***************************************************************************
248 // Revision History :
249 //
250 // $Log: unit_test_suite.hpp,v $
251 // Revision 1.1.1.1 2006/03/20 20:15:27 ewalkup
252 // boost libraries
253 //
254 // Revision 1.32 2005/05/02 06:00:10 rogeeff
255 // restore a parameterized user case method based testing
256 //
257 // Revision 1.31 2005/04/18 04:55:30 rogeeff
258 // test unit name made read/write
259 //
260 // Revision 1.30 2005/03/22 06:57:29 rogeeff
261 // allow to inherit test_suite
262 //
263 // Revision 1.29 2005/02/21 10:25:54 rogeeff
264 // use std::vector so we could employ random_shuffle
265 //
266 // Revision 1.28 2005/02/20 08:27:06 rogeeff
267 // This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
268 //
269 // Revision 1.27 2005/02/01 06:40:06 rogeeff
270 // copyright update
271 // old log entries removed
272 // minor stylistic changes
273 // deprecated tools removed
274 //
275 // Revision 1.26 2005/01/30 03:22:07 rogeeff
276 // interface changed to use const_string
277 // use BOOST_TEST_STRINGIZE
278 //
279 // Revision 1.25 2005/01/22 19:22:12 rogeeff
280 // implementation moved into headers section to eliminate dependency of included/minimal component on src directory
281 //
282 // ***************************************************************************
283
284 #endif // BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
285
286