Chris@16
|
1 // (C) Copyright Gennadiy Rozental 2005-2008.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 // See http://www.boost.org/libs/test for the library home page.
|
Chris@16
|
7 //
|
Chris@16
|
8 // File : $RCSfile$
|
Chris@16
|
9 //
|
Chris@101
|
10 // Version : $Revision$
|
Chris@16
|
11 //
|
Chris@16
|
12 // Description : privides core implementation for Unit Test Framework.
|
Chris@16
|
13 // Extensions can be provided in separate files
|
Chris@16
|
14 // ***************************************************************************
|
Chris@16
|
15
|
Chris@16
|
16 #ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|
Chris@16
|
17 #define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|
Chris@16
|
18
|
Chris@16
|
19 // Boost.Test
|
Chris@16
|
20 #include <boost/detail/workaround.hpp>
|
Chris@16
|
21 #include <boost/test/unit_test_suite_impl.hpp>
|
Chris@16
|
22 #include <boost/test/framework.hpp>
|
Chris@16
|
23 #include <boost/test/utils/foreach.hpp>
|
Chris@16
|
24 #include <boost/test/results_collector.hpp>
|
Chris@16
|
25 #include <boost/test/detail/unit_test_parameters.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 // Boost
|
Chris@16
|
28 #include <boost/timer.hpp>
|
Chris@16
|
29
|
Chris@16
|
30 // STL
|
Chris@16
|
31 #include <algorithm>
|
Chris@16
|
32 #include <vector>
|
Chris@16
|
33
|
Chris@16
|
34 #include <boost/test/detail/suppress_warnings.hpp>
|
Chris@16
|
35
|
Chris@16
|
36 #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
|
Chris@16
|
37 BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \
|
Chris@16
|
38 /**/
|
Chris@16
|
39 using std::rand; // rand is in std and random_shuffle is in _STL
|
Chris@16
|
40 #endif
|
Chris@16
|
41
|
Chris@16
|
42 //____________________________________________________________________________//
|
Chris@16
|
43
|
Chris@16
|
44 namespace boost {
|
Chris@16
|
45
|
Chris@16
|
46 namespace unit_test {
|
Chris@16
|
47
|
Chris@16
|
48 // ************************************************************************** //
|
Chris@16
|
49 // ************** test_unit ************** //
|
Chris@16
|
50 // ************************************************************************** //
|
Chris@16
|
51
|
Chris@16
|
52 test_unit::test_unit( const_string name, test_unit_type t )
|
Chris@16
|
53 : p_type( t )
|
Chris@16
|
54 , p_type_name( t == tut_case ? "case" : "suite" )
|
Chris@16
|
55 , p_id( INV_TEST_UNIT_ID )
|
Chris@16
|
56 , p_name( std::string( name.begin(), name.size() ) )
|
Chris@16
|
57 , p_enabled( true )
|
Chris@16
|
58 {
|
Chris@16
|
59 }
|
Chris@16
|
60
|
Chris@16
|
61 //____________________________________________________________________________//
|
Chris@16
|
62
|
Chris@16
|
63 test_unit::~test_unit()
|
Chris@16
|
64 {
|
Chris@16
|
65 framework::deregister_test_unit( this );
|
Chris@16
|
66 }
|
Chris@16
|
67
|
Chris@16
|
68 //____________________________________________________________________________//
|
Chris@16
|
69
|
Chris@16
|
70 void
|
Chris@16
|
71 test_unit::depends_on( test_unit* tu )
|
Chris@16
|
72 {
|
Chris@16
|
73 m_dependencies.push_back( tu->p_id );
|
Chris@16
|
74 }
|
Chris@16
|
75
|
Chris@16
|
76 //____________________________________________________________________________//
|
Chris@16
|
77
|
Chris@16
|
78 bool
|
Chris@16
|
79 test_unit::check_dependencies() const
|
Chris@16
|
80 {
|
Chris@16
|
81 BOOST_TEST_FOREACH( test_unit_id, tu_id, m_dependencies ) {
|
Chris@16
|
82 if( !unit_test::results_collector.results( tu_id ).passed() )
|
Chris@16
|
83 return false;
|
Chris@16
|
84 }
|
Chris@16
|
85
|
Chris@16
|
86 return true;
|
Chris@16
|
87 }
|
Chris@16
|
88
|
Chris@16
|
89 //____________________________________________________________________________//
|
Chris@16
|
90
|
Chris@16
|
91 void
|
Chris@16
|
92 test_unit::increase_exp_fail( unsigned num )
|
Chris@16
|
93 {
|
Chris@16
|
94 p_expected_failures.value += num;
|
Chris@16
|
95
|
Chris@16
|
96 if( p_parent_id != 0 )
|
Chris@16
|
97 framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
|
Chris@16
|
98 }
|
Chris@16
|
99
|
Chris@16
|
100 //____________________________________________________________________________//
|
Chris@16
|
101
|
Chris@16
|
102 // ************************************************************************** //
|
Chris@16
|
103 // ************** test_case ************** //
|
Chris@16
|
104 // ************************************************************************** //
|
Chris@16
|
105
|
Chris@16
|
106 test_case::test_case( const_string name, callback0<> const& test_func )
|
Chris@16
|
107 : test_unit( name, static_cast<test_unit_type>(type) )
|
Chris@16
|
108 , m_test_func( test_func )
|
Chris@16
|
109 {
|
Chris@16
|
110 // !! weirdest MSVC BUG; try to remove this statement; looks like it eats first token of next statement
|
Chris@16
|
111 #if BOOST_WORKAROUND(BOOST_MSVC,<1300)
|
Chris@16
|
112 0;
|
Chris@16
|
113 #endif
|
Chris@16
|
114 framework::register_test_unit( this );
|
Chris@16
|
115 }
|
Chris@16
|
116
|
Chris@16
|
117 //____________________________________________________________________________//
|
Chris@16
|
118
|
Chris@16
|
119 // ************************************************************************** //
|
Chris@16
|
120 // ************** test_suite ************** //
|
Chris@16
|
121 // ************************************************************************** //
|
Chris@16
|
122
|
Chris@16
|
123 //____________________________________________________________________________//
|
Chris@16
|
124
|
Chris@16
|
125 test_suite::test_suite( const_string name )
|
Chris@16
|
126 : test_unit( name, static_cast<test_unit_type>(type) )
|
Chris@16
|
127 {
|
Chris@16
|
128 framework::register_test_unit( this );
|
Chris@16
|
129 }
|
Chris@16
|
130
|
Chris@16
|
131 //____________________________________________________________________________//
|
Chris@16
|
132
|
Chris@16
|
133 void
|
Chris@16
|
134 test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
|
Chris@16
|
135 {
|
Chris@16
|
136 if( timeout != 0 )
|
Chris@16
|
137 tu->p_timeout.value = timeout;
|
Chris@16
|
138
|
Chris@16
|
139 m_members.push_back( tu->p_id );
|
Chris@16
|
140 tu->p_parent_id.value = p_id;
|
Chris@16
|
141
|
Chris@16
|
142 if( tu->p_expected_failures )
|
Chris@16
|
143 increase_exp_fail( tu->p_expected_failures );
|
Chris@16
|
144
|
Chris@16
|
145 if( expected_failures )
|
Chris@16
|
146 tu->increase_exp_fail( expected_failures );
|
Chris@16
|
147 }
|
Chris@16
|
148
|
Chris@16
|
149 //____________________________________________________________________________//
|
Chris@16
|
150
|
Chris@16
|
151 void
|
Chris@16
|
152 test_suite::add( test_unit_generator const& gen, unsigned timeout )
|
Chris@16
|
153 {
|
Chris@16
|
154 test_unit* tu;
|
Chris@16
|
155 while((tu = gen.next(), tu))
|
Chris@16
|
156 add( tu, 0, timeout );
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 //____________________________________________________________________________//
|
Chris@16
|
160
|
Chris@16
|
161 void
|
Chris@16
|
162 test_suite::remove( test_unit_id id )
|
Chris@16
|
163 {
|
Chris@16
|
164 std::vector<test_unit_id>::iterator it = std::find( m_members.begin(), m_members.end(), id );
|
Chris@16
|
165
|
Chris@16
|
166 if( it != m_members.end() )
|
Chris@16
|
167 m_members.erase( it );
|
Chris@16
|
168 }
|
Chris@16
|
169
|
Chris@16
|
170 //____________________________________________________________________________//
|
Chris@16
|
171
|
Chris@16
|
172 test_unit_id
|
Chris@16
|
173 test_suite::get( const_string tu_name ) const
|
Chris@16
|
174 {
|
Chris@16
|
175 BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
|
Chris@16
|
176 if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
|
Chris@16
|
177 return id;
|
Chris@16
|
178 }
|
Chris@16
|
179
|
Chris@16
|
180 return INV_TEST_UNIT_ID;
|
Chris@16
|
181 }
|
Chris@16
|
182
|
Chris@16
|
183 //____________________________________________________________________________//
|
Chris@16
|
184
|
Chris@16
|
185 // ************************************************************************** //
|
Chris@16
|
186 // ************** traverse_test_tree ************** //
|
Chris@16
|
187 // ************************************************************************** //
|
Chris@16
|
188
|
Chris@16
|
189 void
|
Chris@16
|
190 traverse_test_tree( test_case const& tc, test_tree_visitor& V )
|
Chris@16
|
191 {
|
Chris@16
|
192 if( tc.p_enabled )
|
Chris@16
|
193 V.visit( tc );
|
Chris@16
|
194 }
|
Chris@16
|
195
|
Chris@16
|
196 //____________________________________________________________________________//
|
Chris@16
|
197
|
Chris@16
|
198 void
|
Chris@16
|
199 traverse_test_tree( test_suite const& suite, test_tree_visitor& V )
|
Chris@16
|
200 {
|
Chris@16
|
201 if( !suite.p_enabled || !V.test_suite_start( suite ) )
|
Chris@16
|
202 return;
|
Chris@16
|
203
|
Chris@16
|
204 try {
|
Chris@16
|
205 if( runtime_config::random_seed() == 0 ) {
|
Chris@16
|
206 BOOST_TEST_FOREACH( test_unit_id, id, suite.m_members )
|
Chris@16
|
207 traverse_test_tree( id, V );
|
Chris@16
|
208 }
|
Chris@16
|
209 else {
|
Chris@16
|
210 std::vector<test_unit_id> members( suite.m_members );
|
Chris@16
|
211 std::random_shuffle( members.begin(), members.end() );
|
Chris@16
|
212 BOOST_TEST_FOREACH( test_unit_id, id, members )
|
Chris@16
|
213 traverse_test_tree( id, V );
|
Chris@16
|
214 }
|
Chris@16
|
215
|
Chris@16
|
216 } catch( test_being_aborted const& ) {
|
Chris@16
|
217 V.test_suite_finish( suite );
|
Chris@16
|
218 framework::test_unit_aborted( suite );
|
Chris@16
|
219
|
Chris@16
|
220 throw;
|
Chris@16
|
221 }
|
Chris@16
|
222
|
Chris@16
|
223 V.test_suite_finish( suite );
|
Chris@16
|
224 }
|
Chris@16
|
225
|
Chris@16
|
226 //____________________________________________________________________________//
|
Chris@16
|
227
|
Chris@16
|
228 void
|
Chris@16
|
229 traverse_test_tree( test_unit_id id, test_tree_visitor& V )
|
Chris@16
|
230 {
|
Chris@16
|
231 if( ut_detail::test_id_2_unit_type( id ) == tut_case )
|
Chris@16
|
232 traverse_test_tree( framework::get<test_case>( id ), V );
|
Chris@16
|
233 else
|
Chris@16
|
234 traverse_test_tree( framework::get<test_suite>( id ), V );
|
Chris@16
|
235 }
|
Chris@16
|
236
|
Chris@16
|
237 //____________________________________________________________________________//
|
Chris@16
|
238
|
Chris@16
|
239 // ************************************************************************** //
|
Chris@16
|
240 // ************** test_case_counter ************** //
|
Chris@16
|
241 // ************************************************************************** //
|
Chris@16
|
242
|
Chris@16
|
243 void
|
Chris@16
|
244 test_case_counter::visit( test_case const& tc )
|
Chris@16
|
245 {
|
Chris@16
|
246 if( tc.p_enabled )
|
Chris@16
|
247 ++p_count.value;
|
Chris@16
|
248 }
|
Chris@16
|
249
|
Chris@16
|
250 //____________________________________________________________________________//
|
Chris@16
|
251
|
Chris@16
|
252 // ************************************************************************** //
|
Chris@16
|
253 // ************** object generators ************** //
|
Chris@16
|
254 // ************************************************************************** //
|
Chris@16
|
255
|
Chris@16
|
256 namespace ut_detail {
|
Chris@16
|
257
|
Chris@16
|
258 std::string
|
Chris@16
|
259 normalize_test_case_name( const_string name )
|
Chris@16
|
260 {
|
Chris@16
|
261 return ( name[0] == '&'
|
Chris@16
|
262 ? std::string( name.begin()+1, name.size()-1 )
|
Chris@16
|
263 : std::string( name.begin(), name.size() ) );
|
Chris@16
|
264 }
|
Chris@16
|
265
|
Chris@16
|
266 //____________________________________________________________________________//
|
Chris@16
|
267
|
Chris@16
|
268 // ************************************************************************** //
|
Chris@16
|
269 // ************** auto_test_unit_registrar ************** //
|
Chris@16
|
270 // ************************************************************************** //
|
Chris@16
|
271
|
Chris@16
|
272 auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, counter_t exp_fail )
|
Chris@16
|
273 {
|
Chris@16
|
274 curr_ts_store().back()->add( tc, exp_fail );
|
Chris@16
|
275 }
|
Chris@16
|
276
|
Chris@16
|
277 //____________________________________________________________________________//
|
Chris@16
|
278
|
Chris@16
|
279 auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name )
|
Chris@16
|
280 {
|
Chris@16
|
281 test_unit_id id = curr_ts_store().back()->get( ts_name );
|
Chris@16
|
282
|
Chris@16
|
283 test_suite* ts;
|
Chris@16
|
284
|
Chris@16
|
285 if( id != INV_TEST_UNIT_ID ) {
|
Chris@16
|
286 ts = &framework::get<test_suite>( id ); // !! test for invalid tu type
|
Chris@16
|
287 BOOST_ASSERT( ts->p_parent_id == curr_ts_store().back()->p_id );
|
Chris@16
|
288 }
|
Chris@16
|
289 else {
|
Chris@16
|
290 ts = new test_suite( ts_name );
|
Chris@16
|
291 curr_ts_store().back()->add( ts );
|
Chris@16
|
292 }
|
Chris@16
|
293
|
Chris@16
|
294 curr_ts_store().push_back( ts );
|
Chris@16
|
295 }
|
Chris@16
|
296
|
Chris@16
|
297 //____________________________________________________________________________//
|
Chris@16
|
298
|
Chris@16
|
299 auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen )
|
Chris@16
|
300 {
|
Chris@16
|
301 curr_ts_store().back()->add( tc_gen );
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 //____________________________________________________________________________//
|
Chris@16
|
305
|
Chris@16
|
306 auto_test_unit_registrar::auto_test_unit_registrar( int )
|
Chris@16
|
307 {
|
Chris@16
|
308 if( curr_ts_store().size() == 0 )
|
Chris@16
|
309 return; // report error?
|
Chris@16
|
310
|
Chris@16
|
311 curr_ts_store().pop_back();
|
Chris@16
|
312 }
|
Chris@16
|
313
|
Chris@16
|
314 //____________________________________________________________________________//
|
Chris@16
|
315
|
Chris@16
|
316 std::list<test_suite*>&
|
Chris@16
|
317 auto_test_unit_registrar::curr_ts_store()
|
Chris@16
|
318 {
|
Chris@16
|
319 static std::list<test_suite*> inst( 1, &framework::master_test_suite() );
|
Chris@16
|
320 return inst;
|
Chris@16
|
321 }
|
Chris@16
|
322
|
Chris@16
|
323 //____________________________________________________________________________//
|
Chris@16
|
324
|
Chris@16
|
325 } // namespace ut_detail
|
Chris@16
|
326
|
Chris@16
|
327 // ************************************************************************** //
|
Chris@16
|
328 // ************** global_fixture ************** //
|
Chris@16
|
329 // ************************************************************************** //
|
Chris@16
|
330
|
Chris@16
|
331 global_fixture::global_fixture()
|
Chris@16
|
332 {
|
Chris@16
|
333 framework::register_observer( *this );
|
Chris@16
|
334 }
|
Chris@16
|
335
|
Chris@16
|
336 //____________________________________________________________________________//
|
Chris@16
|
337
|
Chris@16
|
338 } // namespace unit_test
|
Chris@16
|
339
|
Chris@16
|
340 } // namespace boost
|
Chris@16
|
341
|
Chris@16
|
342 //____________________________________________________________________________//
|
Chris@16
|
343
|
Chris@16
|
344 #include <boost/test/detail/enable_warnings.hpp>
|
Chris@16
|
345
|
Chris@16
|
346 #endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|