Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:01:00

0001 //  (C) Copyright Gennadiy Rozental 2001.
0002 //  Distributed under the Boost Software License, Version 1.0.
0003 //  (See accompanying file LICENSE_1_0.txt or copy at
0004 //  http://www.boost.org/LICENSE_1_0.txt)
0005 
0006 //  See http://www.boost.org/libs/test for the library home page.
0007 //
0008 /// @file
0009 /// Provides core implementation for Unit Test Framework.
0010 /// Extensions can be provided in separate files
0011 // ***************************************************************************
0012 
0013 #ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
0014 #define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
0015 
0016 // Boost.Test
0017 #include <boost/detail/workaround.hpp>
0018 
0019 #include <boost/test/framework.hpp>
0020 #include <boost/test/results_collector.hpp>
0021 
0022 #include <boost/test/tree/test_unit.hpp>
0023 #include <boost/test/tree/visitor.hpp>
0024 #include <boost/test/tree/traverse.hpp>
0025 #include <boost/test/tree/auto_registration.hpp>
0026 #include <boost/test/tree/global_fixture.hpp>
0027 
0028 #include <boost/test/utils/foreach.hpp>
0029 #include <boost/test/utils/basic_cstring/io.hpp>
0030 
0031 #include <boost/test/unit_test_parameters.hpp>
0032 
0033 // STL
0034 #include <algorithm>
0035 #include <vector>
0036 #include <set>
0037 
0038 #include <boost/test/detail/suppress_warnings.hpp>
0039 
0040 //____________________________________________________________________________//
0041 
0042 namespace boost {
0043 namespace unit_test {
0044 
0045 // ************************************************************************** //
0046 // **************                   test_unit                  ************** //
0047 // ************************************************************************** //
0048 
0049 test_unit::test_unit( const_string name, const_string file_name, std::size_t line_num, test_unit_type t )
0050 : p_type( t )
0051 , p_type_name( t == TUT_CASE ? "case" : "suite" )
0052 , p_file_name( file_name )
0053 , p_line_num( line_num )
0054 , p_id( INV_TEST_UNIT_ID )
0055 , p_parent_id( INV_TEST_UNIT_ID )
0056 , p_name( std::string( name.begin(), name.size() ) )
0057 , p_timeout( 0 )
0058 , p_expected_failures( 0 )
0059 , p_default_status( RS_INHERIT )
0060 , p_run_status( RS_INVALID )
0061 , p_sibling_rank(0)
0062 {
0063 }
0064 
0065 //____________________________________________________________________________//
0066 
0067 test_unit::test_unit( const_string module_name )
0068 : p_type( TUT_SUITE )
0069 , p_type_name( "module" )
0070 , p_line_num( 0 )
0071 , p_id( INV_TEST_UNIT_ID )
0072 , p_parent_id( INV_TEST_UNIT_ID )
0073 , p_name( std::string( module_name.begin(), module_name.size() ) )
0074 , p_timeout( 0 )
0075 , p_expected_failures( 0 )
0076 , p_default_status( RS_INHERIT )
0077 , p_run_status( RS_INVALID )
0078 , p_sibling_rank(0)
0079 {
0080 }
0081 
0082 //____________________________________________________________________________//
0083 
0084 test_unit::~test_unit()
0085 {
0086     framework::deregister_test_unit( this );
0087 }
0088 
0089 //____________________________________________________________________________//
0090 
0091 void
0092 test_unit::depends_on( test_unit* tu )
0093 {
0094     BOOST_TEST_SETUP_ASSERT( p_id != framework::master_test_suite().p_id, 
0095                              "Can't add dependency to the master test suite" );
0096 
0097     p_dependencies.value.push_back( tu->p_id );
0098 }
0099 
0100 //____________________________________________________________________________//
0101 
0102 void
0103 test_unit::add_precondition( precondition_t const& pc )
0104 {
0105     p_preconditions.value.push_back( pc );
0106 }
0107 
0108 //____________________________________________________________________________//
0109 
0110 test_tools::assertion_result
0111 test_unit::check_preconditions() const
0112 {
0113     BOOST_TEST_FOREACH( test_unit_id, dep_id, p_dependencies.get() ) {
0114         test_unit const& dep = framework::get( dep_id, TUT_ANY );
0115 
0116         if( !dep.is_enabled() ) {
0117             test_tools::assertion_result res(false);
0118             res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" is disabled";
0119             return res;
0120         }
0121 
0122         test_results const& test_rslt = unit_test::results_collector.results( dep_id );
0123         if( !test_rslt.passed() ) {
0124             test_tools::assertion_result res(false);
0125             res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << (test_rslt.skipped() ? "\" was skipped":"\" has failed");
0126             return res;
0127         }
0128 
0129         if( test_rslt.p_test_cases_skipped > 0 ) {
0130             test_tools::assertion_result res(false);
0131             res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has skipped test cases";
0132             return res;
0133         }
0134     }
0135 
0136     BOOST_TEST_FOREACH( precondition_t, precondition, p_preconditions.get() ) {
0137         test_tools::assertion_result res = precondition( p_id );
0138         if( !res ) {
0139             test_tools::assertion_result res_out(false);
0140             res_out.message() << "precondition failed";
0141             if( !res.has_empty_message() )
0142                 res_out.message() << ": " << res.message();
0143             return res_out;
0144         }
0145     }
0146 
0147     return true;
0148 }
0149 
0150 //____________________________________________________________________________//
0151 
0152 void
0153 test_unit::increase_exp_fail( counter_t num )
0154 {
0155     p_expected_failures.value += num;
0156 
0157     if( p_parent_id != INV_TEST_UNIT_ID )
0158         framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
0159 }
0160 
0161 //____________________________________________________________________________//
0162 
0163 std::string
0164 test_unit::full_name() const
0165 {
0166     if( p_parent_id == INV_TEST_UNIT_ID || p_parent_id == framework::master_test_suite().p_id )
0167         return p_name;
0168 
0169     std::string res = framework::get<test_suite>( p_parent_id ).full_name();
0170     res.append("/");
0171 
0172     res.append( p_name );
0173 
0174     return res;
0175 }
0176 
0177 //____________________________________________________________________________//
0178 
0179 void
0180 test_unit::add_label( const_string l )
0181 {
0182     p_labels.value.push_back( std::string() + l );
0183 }
0184 
0185 //____________________________________________________________________________//
0186 
0187 bool
0188 test_unit::has_label( const_string l ) const
0189 {
0190     return std::find( p_labels->begin(), p_labels->end(), l ) != p_labels->end();
0191 }
0192 
0193 //____________________________________________________________________________//
0194 
0195 // ************************************************************************** //
0196 // **************                   test_case                  ************** //
0197 // ************************************************************************** //
0198 
0199 test_case::test_case( const_string name, boost::function<void ()> const& test_func )
0200 : test_unit( name, "", 0, static_cast<test_unit_type>(type) )
0201 , p_test_func( test_func )
0202 {
0203     framework::register_test_unit( this );
0204 }
0205 
0206 //____________________________________________________________________________//
0207 
0208 test_case::test_case( const_string name, const_string file_name, std::size_t line_num, boost::function<void ()> const& test_func )
0209 : test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
0210 , p_test_func( test_func )
0211 {
0212     framework::register_test_unit( this );
0213 }
0214 
0215 //____________________________________________________________________________//
0216 
0217 // ************************************************************************** //
0218 // **************                  test_suite                  ************** //
0219 // ************************************************************************** //
0220 
0221 //____________________________________________________________________________//
0222 
0223 test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
0224 : test_unit( ut_detail::normalize_test_case_name( name ), file_name, line_num, static_cast<test_unit_type>(type) )
0225 {
0226     framework::register_test_unit( this );
0227 }
0228 
0229 //____________________________________________________________________________//
0230 
0231 test_suite::test_suite( const_string module_name )
0232 : test_unit( module_name )
0233 {
0234     framework::register_test_unit( this );
0235 }
0236 
0237 //____________________________________________________________________________//
0238 
0239 void
0240 test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
0241 {
0242     tu->p_timeout.value = timeout;
0243 
0244     m_children.push_back( tu->p_id );
0245     tu->p_parent_id.value = p_id;
0246 
0247     if( tu->p_expected_failures != 0 )
0248         increase_exp_fail( tu->p_expected_failures );
0249 
0250     if( expected_failures )
0251         tu->increase_exp_fail( expected_failures );
0252 }
0253 
0254 //____________________________________________________________________________//
0255 
0256 void
0257 test_suite::add( test_unit_generator const& gen, unsigned timeout )
0258 {
0259     test_unit* tu;
0260     while((tu = gen.next()) != 0)
0261         add( tu, 0, timeout );
0262 }
0263 
0264 //____________________________________________________________________________//
0265 
0266 void
0267 test_suite::add( test_unit_generator const& gen, decorator::collector_t& decorators )
0268 {
0269     test_unit* tu;
0270     while((tu = gen.next()) != 0) {
0271         decorators.store_in( *tu );
0272         add( tu, 0 );
0273     }
0274     decorators.reset();
0275 }
0276 
0277 //____________________________________________________________________________//
0278 
0279 void
0280 test_suite::add( boost::shared_ptr<test_unit_generator> gen_ptr, decorator::collector_t& decorators )
0281 {
0282     std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > tmp_p(gen_ptr, decorators.get_lazy_decorators() );
0283     m_generators.push_back(tmp_p);
0284     decorators.reset();
0285 }
0286 
0287 //____________________________________________________________________________//
0288 
0289 void
0290 test_suite::generate( )
0291 {
0292     typedef std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > element_t;
0293   
0294     for(std::vector<element_t>::iterator it(m_generators.begin()), ite(m_generators.end());
0295         it < ite;
0296         ++it)
0297     {
0298       test_unit* tu;
0299       while((tu = it->first->next()) != 0) {
0300           tu->p_decorators.value.insert( tu->p_decorators.value.end(), it->second.begin(), it->second.end() );
0301           //it->second.store_in( *tu );
0302           add( tu, 0 );
0303       }
0304 
0305     }
0306     m_generators.clear();
0307     
0308     #if 0
0309     test_unit* tu;
0310     while((tu = gen.next()) != 0) {
0311         decorators.store_in( *tu );
0312         add( tu, 0 );
0313     }
0314     #endif
0315 }
0316 
0317 //____________________________________________________________________________//
0318 
0319 void
0320 test_suite::check_for_duplicate_test_cases() {
0321     // check for clashing names #12597
0322     std::set<std::string> names;
0323     for( test_unit_id_list::const_iterator it(m_children.begin()), ite(m_children.end());
0324          it < ite;
0325          ++it) {
0326          std::string name = framework::get(*it, TUT_ANY).p_name;
0327          std::pair<std::set<std::string>::iterator, bool> ret = names.insert(name);
0328          BOOST_TEST_SETUP_ASSERT(ret.second,
0329             "test unit with name '"
0330             + name
0331             + std::string("' registered multiple times in the test suite '")
0332             + this->p_name.value
0333             + "'");
0334     }
0335 
0336     return;
0337 }
0338 
0339 //____________________________________________________________________________//
0340 
0341 void
0342 test_suite::remove( test_unit_id id )
0343 {
0344     test_unit_id_list::iterator it = std::find( m_children.begin(), m_children.end(), id );
0345 
0346     if( it != m_children.end() )
0347         m_children.erase( it );
0348 }
0349 
0350 //____________________________________________________________________________//
0351 
0352 test_unit_id
0353 test_suite::get( const_string tu_name ) const
0354 {
0355     BOOST_TEST_FOREACH( test_unit_id, id, m_children ) {
0356         if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
0357             return id;
0358     }
0359 
0360     return INV_TEST_UNIT_ID;
0361 }
0362 
0363 //____________________________________________________________________________//
0364 
0365 // ************************************************************************** //
0366 // **************               master_test_suite              ************** //
0367 // ************************************************************************** //
0368 
0369 master_test_suite_t::master_test_suite_t()
0370 : test_suite( "Master Test Suite" )
0371 , argc( 0 )
0372 , argv( 0 )
0373 {
0374     p_default_status.value = RS_ENABLED;
0375 }
0376 
0377 // ************************************************************************** //
0378 // **************               traverse_test_tree             ************** //
0379 // ************************************************************************** //
0380 
0381 void
0382 traverse_test_tree( test_case const& tc, test_tree_visitor& V, bool ignore_status )
0383 {
0384     if( tc.is_enabled() || ignore_status )
0385         V.visit( tc );
0386 }
0387 
0388 //____________________________________________________________________________//
0389 
0390 void
0391 traverse_test_tree( test_suite const& suite, test_tree_visitor& V, bool ignore_status )
0392 {
0393     // skip disabled test suite unless we asked to ignore this condition
0394     if( !ignore_status && !suite.is_enabled() )
0395         return;
0396 
0397     // Invoke test_suite_start callback
0398     if( !V.test_suite_start( suite ) )
0399         return;
0400 
0401     // Recurse into children
0402     std::size_t total_children = suite.m_children.size();
0403     for( std::size_t i=0; i < total_children; ) {
0404         // this statement can remove the test unit from this list
0405         traverse_test_tree( suite.m_children[i], V, ignore_status );
0406         if( total_children > suite.m_children.size() )
0407             total_children = suite.m_children.size();
0408         else
0409             ++i;
0410     }
0411 
0412     // Invoke test_suite_finish callback
0413     V.test_suite_finish( suite );
0414 }
0415 
0416 //____________________________________________________________________________//
0417 
0418 void
0419 traverse_test_tree( test_unit_id id, test_tree_visitor& V, bool ignore_status )
0420 {
0421     if( ut_detail::test_id_2_unit_type( id ) == TUT_CASE )
0422         traverse_test_tree( framework::get<test_case>( id ), V, ignore_status );
0423     else
0424         traverse_test_tree( framework::get<test_suite>( id ), V, ignore_status );
0425 }
0426 
0427 //____________________________________________________________________________//
0428 
0429 // ************************************************************************** //
0430 // **************               object generators              ************** //
0431 // ************************************************************************** //
0432 
0433 namespace ut_detail {
0434 
0435 std::string
0436 normalize_test_case_name( const_string name )
0437 {
0438     std::string norm_name( name.begin(), name.end() );
0439 
0440     if( name[0] == '&' )
0441         norm_name = norm_name.substr( 1 );
0442 
0443     // trim spaces
0444     std::size_t first_not_space = norm_name.find_first_not_of(' ');
0445     if( first_not_space ) {
0446         norm_name.erase(0, first_not_space);
0447     }
0448 
0449     std::size_t last_not_space = norm_name.find_last_not_of(' ');
0450     if( last_not_space !=std::string::npos ) {
0451         norm_name.erase(last_not_space + 1);
0452     }
0453 
0454     // sanitize all chars that might be used in runtime filters
0455     static const char to_replace[] = { ':', '*', '@', '+', '!', '/', ',' };
0456     for(std::size_t index = 0;
0457         index < sizeof(to_replace)/sizeof(to_replace[0]);
0458         index++) {
0459         std::replace(norm_name.begin(), norm_name.end(), to_replace[index], '_');
0460     }
0461 
0462     return norm_name;
0463 }
0464 
0465 //____________________________________________________________________________//
0466 
0467 // ************************************************************************** //
0468 // **************           auto_test_unit_registrar           ************** //
0469 // ************************************************************************** //
0470 
0471 auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector_t& decorators, counter_t exp_fail )
0472 {
0473     framework::current_auto_test_suite().add( tc, exp_fail );
0474 
0475     decorators.store_in( *tc );
0476     decorators.reset();
0477 }
0478 
0479 //____________________________________________________________________________//
0480 
0481 auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector_t& decorators )
0482 {
0483     test_unit_id id = framework::current_auto_test_suite().get( ts_name );
0484 
0485     test_suite* ts;
0486 
0487     if( id != INV_TEST_UNIT_ID ) {
0488         ts = &framework::get<test_suite>( id );
0489         BOOST_ASSERT( ts->p_parent_id == framework::current_auto_test_suite().p_id );
0490     }
0491     else {
0492         ts = new test_suite( ts_name, ts_file, ts_line );
0493         framework::current_auto_test_suite().add( ts );
0494     }
0495 
0496     decorators.store_in( *ts );
0497     decorators.reset();
0498 
0499     framework::current_auto_test_suite( ts );
0500 }
0501 
0502 //____________________________________________________________________________//
0503 
0504 auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector_t& decorators )
0505 {
0506     framework::current_auto_test_suite().add( tc_gen, decorators );
0507 }
0508 
0509 //____________________________________________________________________________//
0510 
0511 auto_test_unit_registrar::auto_test_unit_registrar( boost::shared_ptr<test_unit_generator> tc_gen, decorator::collector_t& decorators )
0512 {
0513     framework::current_auto_test_suite().add( tc_gen, decorators );
0514 }
0515 
0516 
0517 //____________________________________________________________________________//
0518 
0519 auto_test_unit_registrar::auto_test_unit_registrar( int )
0520 {
0521     framework::current_auto_test_suite( 0, false );
0522 }
0523 
0524 //____________________________________________________________________________//
0525 
0526 } // namespace ut_detail
0527 
0528 // ************************************************************************** //
0529 // **************                global_fixture                ************** //
0530 // ************************************************************************** //
0531 
0532 global_fixture::global_fixture(): registered(false)
0533 {
0534     framework::register_global_fixture( *this );
0535     registered = true;
0536 }
0537 
0538 void global_fixture::unregister_from_framework() {
0539     // not accessing the framework singleton after deregistering -> release
0540     // of the observer from the framework
0541     if(registered) {
0542         framework::deregister_global_fixture( *this );
0543     }
0544     registered = false;
0545 }
0546 
0547 global_fixture::~global_fixture()
0548 {
0549     this->unregister_from_framework();
0550 }
0551 
0552 // ************************************************************************** //
0553 // **************            global_configuration              ************** //
0554 // ************************************************************************** //
0555 
0556 global_configuration::global_configuration(): registered(false)
0557 {
0558     framework::register_observer( *this );
0559     registered = true;
0560 }
0561 
0562 void global_configuration::unregister_from_framework()
0563 {
0564     // not accessing the framework singleton after deregistering -> release
0565     // of the observer from the framework
0566     if(registered) {
0567         framework::deregister_observer( *this );
0568     }
0569     registered = false;
0570 }
0571 
0572 global_configuration::~global_configuration()
0573 {
0574     this->unregister_from_framework();
0575 }
0576 
0577 //____________________________________________________________________________//
0578 
0579 } // namespace unit_test
0580 } // namespace boost
0581 
0582 #include <boost/test/detail/enable_warnings.hpp>
0583 
0584 #endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER