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