Chris@16: // (C) Copyright Gennadiy Rozental 2005-2008. Chris@16: // Distributed under the Boost Software License, Version 1.0. Chris@16: // (See accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: // See http://www.boost.org/libs/test for the library home page. Chris@16: // Chris@16: // File : $RCSfile$ Chris@16: // Chris@101: // Version : $Revision$ Chris@16: // Chris@16: // Description : privides core implementation for Unit Test Framework. Chris@16: // Extensions can be provided in separate files Chris@16: // *************************************************************************** Chris@16: Chris@16: #ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER Chris@16: #define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER Chris@16: Chris@16: // Boost.Test Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Boost Chris@16: #include Chris@16: Chris@16: // STL Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \ Chris@16: BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \ Chris@16: /**/ Chris@16: using std::rand; // rand is in std and random_shuffle is in _STL Chris@16: #endif Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace unit_test { Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** test_unit ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: test_unit::test_unit( const_string name, test_unit_type t ) Chris@16: : p_type( t ) Chris@16: , p_type_name( t == tut_case ? "case" : "suite" ) Chris@16: , p_id( INV_TEST_UNIT_ID ) Chris@16: , p_name( std::string( name.begin(), name.size() ) ) Chris@16: , p_enabled( true ) Chris@16: { Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: test_unit::~test_unit() Chris@16: { Chris@16: framework::deregister_test_unit( this ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: test_unit::depends_on( test_unit* tu ) Chris@16: { Chris@16: m_dependencies.push_back( tu->p_id ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: bool Chris@16: test_unit::check_dependencies() const Chris@16: { Chris@16: BOOST_TEST_FOREACH( test_unit_id, tu_id, m_dependencies ) { Chris@16: if( !unit_test::results_collector.results( tu_id ).passed() ) Chris@16: return false; Chris@16: } Chris@16: Chris@16: return true; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: test_unit::increase_exp_fail( unsigned num ) Chris@16: { Chris@16: p_expected_failures.value += num; Chris@16: Chris@16: if( p_parent_id != 0 ) Chris@16: framework::get( p_parent_id ).increase_exp_fail( num ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** test_case ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: test_case::test_case( const_string name, callback0<> const& test_func ) Chris@16: : test_unit( name, static_cast(type) ) Chris@16: , m_test_func( test_func ) Chris@16: { Chris@16: // !! weirdest MSVC BUG; try to remove this statement; looks like it eats first token of next statement Chris@16: #if BOOST_WORKAROUND(BOOST_MSVC,<1300) Chris@16: 0; Chris@16: #endif Chris@16: framework::register_test_unit( this ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** test_suite ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: test_suite::test_suite( const_string name ) Chris@16: : test_unit( name, static_cast(type) ) Chris@16: { Chris@16: framework::register_test_unit( this ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout ) Chris@16: { Chris@16: if( timeout != 0 ) Chris@16: tu->p_timeout.value = timeout; Chris@16: Chris@16: m_members.push_back( tu->p_id ); Chris@16: tu->p_parent_id.value = p_id; Chris@16: Chris@16: if( tu->p_expected_failures ) Chris@16: increase_exp_fail( tu->p_expected_failures ); Chris@16: Chris@16: if( expected_failures ) Chris@16: tu->increase_exp_fail( expected_failures ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: test_suite::add( test_unit_generator const& gen, unsigned timeout ) Chris@16: { Chris@16: test_unit* tu; Chris@16: while((tu = gen.next(), tu)) Chris@16: add( tu, 0, timeout ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: test_suite::remove( test_unit_id id ) Chris@16: { Chris@16: std::vector::iterator it = std::find( m_members.begin(), m_members.end(), id ); Chris@16: Chris@16: if( it != m_members.end() ) Chris@16: m_members.erase( it ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: test_unit_id Chris@16: test_suite::get( const_string tu_name ) const Chris@16: { Chris@16: BOOST_TEST_FOREACH( test_unit_id, id, m_members ) { Chris@16: if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() ) Chris@16: return id; Chris@16: } Chris@16: Chris@16: return INV_TEST_UNIT_ID; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** traverse_test_tree ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: void Chris@16: traverse_test_tree( test_case const& tc, test_tree_visitor& V ) Chris@16: { Chris@16: if( tc.p_enabled ) Chris@16: V.visit( tc ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: traverse_test_tree( test_suite const& suite, test_tree_visitor& V ) Chris@16: { Chris@16: if( !suite.p_enabled || !V.test_suite_start( suite ) ) Chris@16: return; Chris@16: Chris@16: try { Chris@16: if( runtime_config::random_seed() == 0 ) { Chris@16: BOOST_TEST_FOREACH( test_unit_id, id, suite.m_members ) Chris@16: traverse_test_tree( id, V ); Chris@16: } Chris@16: else { Chris@16: std::vector members( suite.m_members ); Chris@16: std::random_shuffle( members.begin(), members.end() ); Chris@16: BOOST_TEST_FOREACH( test_unit_id, id, members ) Chris@16: traverse_test_tree( id, V ); Chris@16: } Chris@16: Chris@16: } catch( test_being_aborted const& ) { Chris@16: V.test_suite_finish( suite ); Chris@16: framework::test_unit_aborted( suite ); Chris@16: Chris@16: throw; Chris@16: } Chris@16: Chris@16: V.test_suite_finish( suite ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: void Chris@16: traverse_test_tree( test_unit_id id, test_tree_visitor& V ) Chris@16: { Chris@16: if( ut_detail::test_id_2_unit_type( id ) == tut_case ) Chris@16: traverse_test_tree( framework::get( id ), V ); Chris@16: else Chris@16: traverse_test_tree( framework::get( id ), V ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** test_case_counter ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: void Chris@16: test_case_counter::visit( test_case const& tc ) Chris@16: { Chris@16: if( tc.p_enabled ) Chris@16: ++p_count.value; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** object generators ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: namespace ut_detail { Chris@16: Chris@16: std::string Chris@16: normalize_test_case_name( const_string name ) Chris@16: { Chris@16: return ( name[0] == '&' Chris@16: ? std::string( name.begin()+1, name.size()-1 ) Chris@16: : std::string( name.begin(), name.size() ) ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** auto_test_unit_registrar ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, counter_t exp_fail ) Chris@16: { Chris@16: curr_ts_store().back()->add( tc, exp_fail ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name ) Chris@16: { Chris@16: test_unit_id id = curr_ts_store().back()->get( ts_name ); Chris@16: Chris@16: test_suite* ts; Chris@16: Chris@16: if( id != INV_TEST_UNIT_ID ) { Chris@16: ts = &framework::get( id ); // !! test for invalid tu type Chris@16: BOOST_ASSERT( ts->p_parent_id == curr_ts_store().back()->p_id ); Chris@16: } Chris@16: else { Chris@16: ts = new test_suite( ts_name ); Chris@16: curr_ts_store().back()->add( ts ); Chris@16: } Chris@16: Chris@16: curr_ts_store().push_back( ts ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen ) Chris@16: { Chris@16: curr_ts_store().back()->add( tc_gen ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: auto_test_unit_registrar::auto_test_unit_registrar( int ) Chris@16: { Chris@16: if( curr_ts_store().size() == 0 ) Chris@16: return; // report error? Chris@16: Chris@16: curr_ts_store().pop_back(); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: std::list& Chris@16: auto_test_unit_registrar::curr_ts_store() Chris@16: { Chris@16: static std::list inst( 1, &framework::master_test_suite() ); Chris@16: return inst; Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: } // namespace ut_detail Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** global_fixture ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: global_fixture::global_fixture() Chris@16: { Chris@16: framework::register_observer( *this ); Chris@16: } Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: } // namespace unit_test Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER