Chris@16: // (C) Copyright Gennadiy Rozental 2001-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 : main function implementation for Unit Test Framework Chris@16: // *************************************************************************** Chris@16: Chris@16: #ifndef BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER Chris@16: #define BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER Chris@16: Chris@16: // Boost.Test Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: #if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 ) Chris@16: #define BOOST_TEST_SUPPORT_RUN_BY_NAME Chris@16: #include Chris@16: #endif Chris@16: Chris@16: // Boost Chris@16: #include Chris@16: #include Chris@16: Chris@16: // STL Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: namespace boost { Chris@16: Chris@16: namespace unit_test { Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** test_case_filter ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: class test_case_filter : public test_tree_visitor { Chris@16: public: Chris@16: struct single_filter { Chris@16: single_filter( const_string in ) Chris@16: { Chris@16: if( in == "*" ) Chris@16: m_kind = SFK_ALL; Chris@16: else if( first_char( in ) == '*' && last_char( in ) == '*' ) { Chris@16: m_kind = SFK_SUBSTR; Chris@16: m_value = in.substr( 1, in.size()-1 ); Chris@16: } Chris@16: else if( first_char( in ) == '*' ) { Chris@16: m_kind = SFK_TRAILING; Chris@16: m_value = in.substr( 1 ); Chris@16: } Chris@16: else if( last_char( in ) == '*' ) { Chris@16: m_kind = SFK_LEADING; Chris@16: m_value = in.substr( 0, in.size()-1 ); Chris@16: } Chris@16: else { Chris@16: m_kind = SFK_MATCH; Chris@16: m_value = in; Chris@16: } Chris@16: }; Chris@16: Chris@16: bool pass( test_unit const& tu ) const Chris@16: { Chris@16: const_string name( tu.p_name ); Chris@16: Chris@16: switch( m_kind ) { Chris@16: default: Chris@16: case SFK_ALL: Chris@16: return true; Chris@16: Chris@16: case SFK_LEADING: Chris@16: return name.substr( 0, m_value.size() ) == m_value; Chris@16: Chris@16: case SFK_TRAILING: Chris@16: return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value; Chris@16: Chris@16: case SFK_SUBSTR: Chris@16: return name.find( m_value ) != const_string::npos; Chris@16: Chris@16: case SFK_MATCH: Chris@16: return m_value == tu.p_name.get(); Chris@16: } Chris@16: } Chris@16: enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH }; Chris@16: Chris@16: kind m_kind; Chris@16: const_string m_value; Chris@16: }; Chris@16: // Constructor Chris@16: #ifndef BOOST_TEST_SUPPORT_RUN_BY_NAME Chris@16: explicit test_case_filter( const_string ) : m_depth( 0 ) {} Chris@16: #else Chris@16: explicit test_case_filter( const_string tc_to_run ) Chris@16: : m_depth( 0 ) Chris@16: { Chris@16: string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) ); Chris@16: Chris@16: while( tit != string_token_iterator() ) { Chris@16: m_filters.push_back( Chris@16: std::vector( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ), Chris@16: string_token_iterator() ) ); Chris@16: Chris@16: ++tit; Chris@16: } Chris@16: } Chris@16: #endif Chris@16: Chris@16: void filter_unit( test_unit const& tu ) Chris@16: { Chris@16: if( (++m_depth - 1) > m_filters.size() ) { Chris@16: tu.p_enabled.value = true; Chris@16: return; Chris@16: } Chris@16: Chris@16: if( m_depth == 1 ) Chris@16: return; Chris@16: Chris@16: std::vector const& filters = m_filters[m_depth-2]; Chris@16: Chris@16: tu.p_enabled.value = Chris@16: std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end(); Chris@16: } Chris@16: Chris@16: // test tree visitor interface Chris@16: virtual void visit( test_case const& tc ) Chris@16: { Chris@16: if( m_depth < m_filters.size() ) { Chris@16: tc.p_enabled.value = false; Chris@16: return; Chris@16: } Chris@16: Chris@16: filter_unit( tc ); Chris@16: Chris@16: --m_depth; Chris@16: } Chris@16: Chris@16: virtual bool test_suite_start( test_suite const& ts ) Chris@16: { Chris@16: filter_unit( ts ); Chris@16: Chris@16: if( !ts.p_enabled ) Chris@16: --m_depth; Chris@16: Chris@16: return ts.p_enabled; Chris@16: } Chris@16: Chris@16: virtual void test_suite_finish( test_suite const& ) { --m_depth; } Chris@16: Chris@16: private: Chris@16: // Data members Chris@16: std::vector > m_filters; Chris@16: unsigned m_depth; Chris@16: }; Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** unit_test_main ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: int BOOST_TEST_DECL Chris@16: unit_test_main( init_unit_test_func init_func, int argc, char* argv[] ) Chris@16: { Chris@16: try { Chris@16: framework::init( init_func, argc, argv ); Chris@16: Chris@16: if( !runtime_config::test_to_run().is_empty() ) { Chris@16: test_case_filter filter( runtime_config::test_to_run() ); Chris@16: Chris@16: traverse_test_tree( framework::master_test_suite().p_id, filter ); Chris@16: } Chris@16: Chris@16: framework::run(); Chris@16: Chris@16: results_reporter::make_report(); Chris@16: Chris@16: return runtime_config::no_result_code() Chris@16: ? boost::exit_success Chris@16: : results_collector.results( framework::master_test_suite().p_id ).result_code(); Chris@16: } Chris@16: catch( framework::nothing_to_test const& ) { Chris@16: return boost::exit_success; Chris@16: } Chris@16: catch( framework::internal_error const& ex ) { Chris@16: results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl; Chris@16: Chris@16: return boost::exit_exception_failure; Chris@16: } Chris@16: catch( framework::setup_error const& ex ) { Chris@16: results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl; Chris@16: Chris@16: return boost::exit_exception_failure; Chris@16: } Chris@16: catch( ... ) { Chris@16: results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl; Chris@16: Chris@16: return boost::exit_exception_failure; Chris@16: } Chris@16: } Chris@16: Chris@16: } // namespace unit_test Chris@16: Chris@16: } // namespace boost Chris@16: Chris@16: #if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN) Chris@16: Chris@16: // ************************************************************************** // Chris@16: // ************** main function for tests using lib ************** // Chris@16: // ************************************************************************** // Chris@16: Chris@16: int BOOST_TEST_CALL_DECL Chris@16: main( int argc, char* argv[] ) Chris@16: { Chris@16: // prototype for user's unit test init function Chris@16: #ifdef BOOST_TEST_ALTERNATIVE_INIT_API Chris@16: extern bool init_unit_test(); Chris@16: Chris@16: boost::unit_test::init_unit_test_func init_func = &init_unit_test; Chris@16: #else Chris@16: extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ); Chris@16: Chris@16: boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite; Chris@16: #endif Chris@16: Chris@16: return ::boost::unit_test::unit_test_main( init_func, argc, argv ); Chris@16: } Chris@16: Chris@16: #endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN Chris@16: Chris@16: //____________________________________________________________________________// Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER