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