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