results_collector.ipp 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. // (C) Copyright Gennadiy Rozental 2005-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: 57992 $
  10. //
  11. // Description : implements Unit Test results collecting facility.
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
  14. #define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
  15. // Boost.Test
  16. #include <boost/test/unit_test_suite_impl.hpp>
  17. #include <boost/test/unit_test_log.hpp>
  18. #include <boost/test/results_collector.hpp>
  19. #include <boost/test/framework.hpp>
  20. // Boost
  21. #include <boost/cstdlib.hpp>
  22. // STL
  23. #include <map>
  24. #include <boost/test/detail/suppress_warnings.hpp>
  25. //____________________________________________________________________________//
  26. namespace boost {
  27. namespace unit_test {
  28. // ************************************************************************** //
  29. // ************** test_results ************** //
  30. // ************************************************************************** //
  31. test_results::test_results()
  32. {
  33. clear();
  34. }
  35. //____________________________________________________________________________//
  36. bool
  37. test_results::passed() const
  38. {
  39. return !p_skipped &&
  40. p_test_cases_failed == 0 &&
  41. p_assertions_failed <= p_expected_failures &&
  42. !p_aborted;
  43. }
  44. //____________________________________________________________________________//
  45. int
  46. test_results::result_code() const
  47. {
  48. return passed() ? exit_success
  49. : ( (p_assertions_failed > p_expected_failures || p_skipped )
  50. ? exit_test_failure
  51. : exit_exception_failure );
  52. }
  53. //____________________________________________________________________________//
  54. void
  55. test_results::operator+=( test_results const& tr )
  56. {
  57. p_assertions_passed.value += tr.p_assertions_passed;
  58. p_assertions_failed.value += tr.p_assertions_failed;
  59. p_test_cases_passed.value += tr.p_test_cases_passed;
  60. p_test_cases_failed.value += tr.p_test_cases_failed;
  61. p_test_cases_skipped.value += tr.p_test_cases_skipped;
  62. p_test_cases_aborted.value += tr.p_test_cases_aborted;
  63. }
  64. //____________________________________________________________________________//
  65. void
  66. test_results::clear()
  67. {
  68. p_assertions_passed.value = 0;
  69. p_assertions_failed.value = 0;
  70. p_expected_failures.value = 0;
  71. p_test_cases_passed.value = 0;
  72. p_test_cases_failed.value = 0;
  73. p_test_cases_skipped.value = 0;
  74. p_test_cases_aborted.value = 0;
  75. p_aborted.value = false;
  76. p_skipped.value = true;
  77. }
  78. //____________________________________________________________________________//
  79. // ************************************************************************** //
  80. // ************** results_collector ************** //
  81. // ************************************************************************** //
  82. #if !BOOST_WORKAROUND(BOOST_MSVC, <1300)
  83. namespace {
  84. struct results_collector_impl {
  85. std::map<test_unit_id,test_results> m_results_store;
  86. };
  87. results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
  88. } // local namespace
  89. #else
  90. struct results_collector_impl {
  91. std::map<test_unit_id,test_results> m_results_store;
  92. };
  93. static results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
  94. #endif
  95. //____________________________________________________________________________//
  96. void
  97. results_collector_t::test_start( counter_t )
  98. {
  99. s_rc_impl().m_results_store.clear();
  100. }
  101. //____________________________________________________________________________//
  102. void
  103. results_collector_t::test_finish()
  104. {
  105. // do nothing
  106. }
  107. //____________________________________________________________________________//
  108. void
  109. results_collector_t::test_aborted()
  110. {
  111. // do nothing
  112. }
  113. //____________________________________________________________________________//
  114. void
  115. results_collector_t::test_unit_start( test_unit const& tu )
  116. {
  117. // init test_results entry
  118. test_results& tr = s_rc_impl().m_results_store[tu.p_id];
  119. tr.clear();
  120. tr.p_expected_failures.value = tu.p_expected_failures;
  121. tr.p_skipped.value = false;
  122. }
  123. //____________________________________________________________________________//
  124. class results_collect_helper : public test_tree_visitor {
  125. public:
  126. explicit results_collect_helper( test_results& tr, test_unit const& ts ) : m_tr( tr ), m_ts( ts ) {}
  127. void visit( test_case const& tc )
  128. {
  129. test_results const& tr = results_collector.results( tc.p_id );
  130. m_tr += tr;
  131. if( tr.passed() )
  132. m_tr.p_test_cases_passed.value++;
  133. else if( tr.p_skipped )
  134. m_tr.p_test_cases_skipped.value++;
  135. else {
  136. if( tr.p_aborted )
  137. m_tr.p_test_cases_aborted.value++;
  138. m_tr.p_test_cases_failed.value++;
  139. }
  140. }
  141. bool test_suite_start( test_suite const& ts )
  142. {
  143. if( m_ts.p_id == ts.p_id )
  144. return true;
  145. else {
  146. m_tr += results_collector.results( ts.p_id );
  147. return false;
  148. }
  149. }
  150. private:
  151. // Data members
  152. test_results& m_tr;
  153. test_unit const& m_ts;
  154. };
  155. //____________________________________________________________________________//
  156. void
  157. results_collector_t::test_unit_finish( test_unit const& tu, unsigned long )
  158. {
  159. if( tu.p_type == tut_suite ) {
  160. results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
  161. traverse_test_tree( tu, ch );
  162. }
  163. else {
  164. test_results const& tr = s_rc_impl().m_results_store[tu.p_id];
  165. bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
  166. if( !num_failures_match )
  167. BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " has fewer failures than expected" );
  168. bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
  169. if( !check_any_assertions )
  170. BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " did not check any assertions" );
  171. }
  172. }
  173. //____________________________________________________________________________//
  174. void
  175. results_collector_t::test_unit_skipped( test_unit const& tu )
  176. {
  177. if( tu.p_type == tut_suite ) {
  178. test_case_counter tcc;
  179. traverse_test_tree( tu, tcc );
  180. test_results& tr = s_rc_impl().m_results_store[tu.p_id];
  181. tr.clear();
  182. tr.p_skipped.value = true;
  183. tr.p_test_cases_skipped.value = tcc.p_count;
  184. }
  185. }
  186. //____________________________________________________________________________//
  187. void
  188. results_collector_t::assertion_result( bool passed )
  189. {
  190. test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
  191. if( passed )
  192. tr.p_assertions_passed.value++;
  193. else
  194. tr.p_assertions_failed.value++;
  195. if( tr.p_assertions_failed == 1 )
  196. first_failed_assertion();
  197. }
  198. //____________________________________________________________________________//
  199. void
  200. results_collector_t::exception_caught( execution_exception const& )
  201. {
  202. test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
  203. tr.p_assertions_failed.value++;
  204. }
  205. //____________________________________________________________________________//
  206. void
  207. results_collector_t::test_unit_aborted( test_unit const& tu )
  208. {
  209. s_rc_impl().m_results_store[tu.p_id].p_aborted.value = true;
  210. }
  211. //____________________________________________________________________________//
  212. test_results const&
  213. results_collector_t::results( test_unit_id id ) const
  214. {
  215. return s_rc_impl().m_results_store[id];
  216. }
  217. //____________________________________________________________________________//
  218. } // namespace unit_test
  219. } // namespace boost
  220. //____________________________________________________________________________//
  221. #include <boost/test/detail/enable_warnings.hpp>
  222. #endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER