unit_test_main.ipp 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // (C) Copyright Gennadiy Rozental 2001-2008.
  2. // Distributed under the Boost Software License, Version 1.0.
  3. // (See accompanying file LICENSE_1_0.txt or copy at
  4. // http://www.boost.org/LICENSE_1_0.txt)
  5. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. // File : $RCSfile$
  8. //
  9. // Version : $Revision: 54633 $
  10. //
  11. // Description : main function implementation for Unit Test Framework
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
  14. #define BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
  15. // Boost.Test
  16. #include <boost/test/framework.hpp>
  17. #include <boost/test/results_collector.hpp>
  18. #include <boost/test/unit_test_suite_impl.hpp>
  19. #include <boost/test/results_reporter.hpp>
  20. #include <boost/test/detail/unit_test_parameters.hpp>
  21. #if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
  22. #define BOOST_TEST_SUPPORT_RUN_BY_NAME
  23. #include <boost/test/utils/iterator/token_iterator.hpp>
  24. #endif
  25. // Boost
  26. #include <boost/cstdlib.hpp>
  27. #include <boost/bind.hpp>
  28. // STL
  29. #include <stdexcept>
  30. #include <iostream>
  31. #include <boost/test/detail/suppress_warnings.hpp>
  32. //____________________________________________________________________________//
  33. namespace boost {
  34. namespace unit_test {
  35. // ************************************************************************** //
  36. // ************** test_case_filter ************** //
  37. // ************************************************************************** //
  38. class test_case_filter : public test_tree_visitor {
  39. public:
  40. struct single_filter {
  41. single_filter( const_string in )
  42. {
  43. if( in == "*" )
  44. m_kind = SFK_ALL;
  45. else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
  46. m_kind = SFK_SUBSTR;
  47. m_value = in.substr( 1, in.size()-1 );
  48. }
  49. else if( first_char( in ) == '*' ) {
  50. m_kind = SFK_TRAILING;
  51. m_value = in.substr( 1 );
  52. }
  53. else if( last_char( in ) == '*' ) {
  54. m_kind = SFK_LEADING;
  55. m_value = in.substr( 0, in.size()-1 );
  56. }
  57. else {
  58. m_kind = SFK_MATCH;
  59. m_value = in;
  60. }
  61. };
  62. bool pass( test_unit const& tu ) const
  63. {
  64. const_string name( tu.p_name );
  65. switch( m_kind ) {
  66. default:
  67. case SFK_ALL:
  68. return true;
  69. case SFK_LEADING:
  70. return name.substr( 0, m_value.size() ) == m_value;
  71. case SFK_TRAILING:
  72. return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
  73. case SFK_SUBSTR:
  74. return name.find( m_value ) != const_string::npos;
  75. case SFK_MATCH:
  76. return m_value == tu.p_name.get();
  77. }
  78. }
  79. enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
  80. kind m_kind;
  81. const_string m_value;
  82. };
  83. // Constructor
  84. #ifndef BOOST_TEST_SUPPORT_RUN_BY_NAME
  85. explicit test_case_filter( const_string ) : m_depth( 0 ) {}
  86. #else
  87. explicit test_case_filter( const_string tc_to_run )
  88. : m_depth( 0 )
  89. {
  90. string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
  91. while( tit != string_token_iterator() ) {
  92. m_filters.push_back(
  93. std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
  94. string_token_iterator() ) );
  95. ++tit;
  96. }
  97. }
  98. #endif
  99. void filter_unit( test_unit const& tu )
  100. {
  101. if( (++m_depth - 1) > m_filters.size() ) {
  102. tu.p_enabled.value = true;
  103. return;
  104. }
  105. if( m_depth == 1 )
  106. return;
  107. std::vector<single_filter> const& filters = m_filters[m_depth-2];
  108. tu.p_enabled.value =
  109. std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end();
  110. }
  111. // test tree visitor interface
  112. virtual void visit( test_case const& tc )
  113. {
  114. if( m_depth < m_filters.size() ) {
  115. tc.p_enabled.value = false;
  116. return;
  117. }
  118. filter_unit( tc );
  119. --m_depth;
  120. }
  121. virtual bool test_suite_start( test_suite const& ts )
  122. {
  123. filter_unit( ts );
  124. if( !ts.p_enabled )
  125. --m_depth;
  126. return ts.p_enabled;
  127. }
  128. virtual void test_suite_finish( test_suite const& ) { --m_depth; }
  129. private:
  130. // Data members
  131. std::vector<std::vector<single_filter> > m_filters;
  132. unsigned m_depth;
  133. };
  134. // ************************************************************************** //
  135. // ************** unit_test_main ************** //
  136. // ************************************************************************** //
  137. int BOOST_TEST_DECL
  138. unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
  139. {
  140. try {
  141. framework::init( init_func, argc, argv );
  142. if( !runtime_config::test_to_run().is_empty() ) {
  143. test_case_filter filter( runtime_config::test_to_run() );
  144. traverse_test_tree( framework::master_test_suite().p_id, filter );
  145. }
  146. framework::run();
  147. results_reporter::make_report();
  148. return runtime_config::no_result_code()
  149. ? boost::exit_success
  150. : results_collector.results( framework::master_test_suite().p_id ).result_code();
  151. }
  152. catch( framework::nothing_to_test const& ) {
  153. return boost::exit_success;
  154. }
  155. catch( framework::internal_error const& ex ) {
  156. results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
  157. return boost::exit_exception_failure;
  158. }
  159. catch( framework::setup_error const& ex ) {
  160. results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
  161. return boost::exit_exception_failure;
  162. }
  163. catch( ... ) {
  164. results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
  165. return boost::exit_exception_failure;
  166. }
  167. }
  168. } // namespace unit_test
  169. } // namespace boost
  170. #if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
  171. // ************************************************************************** //
  172. // ************** main function for tests using lib ************** //
  173. // ************************************************************************** //
  174. int BOOST_TEST_CALL_DECL
  175. main( int argc, char* argv[] )
  176. {
  177. // prototype for user's unit test init function
  178. #ifdef BOOST_TEST_ALTERNATIVE_INIT_API
  179. extern bool init_unit_test();
  180. boost::unit_test::init_unit_test_func init_func = &init_unit_test;
  181. #else
  182. extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
  183. boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
  184. #endif
  185. return ::boost::unit_test::unit_test_main( init_func, argc, argv );
  186. }
  187. #endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
  188. //____________________________________________________________________________//
  189. #include <boost/test/detail/enable_warnings.hpp>
  190. #endif // BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER