LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/test/impl - results_collector.ipp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 113 147 76.9 %
Date: 2026-06-25 07:23:51 Functions: 30 36 83.3 %

          Line data    Source code
       1             : //  (C) Copyright Gennadiy Rozental 2001.
       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             : 
       6             : //  See http://www.boost.org/libs/test for the library home page.
       7             : //
       8             : /// @file
       9             : /// Test results collecting facility.
      10             : ///
      11             : // ***************************************************************************
      12             : 
      13             : #ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
      14             : #define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
      15             : 
      16             : // Boost.Test
      17             : #include <boost/test/unit_test_log.hpp>
      18             : #include <boost/test/results_collector.hpp>
      19             : #include <boost/test/framework.hpp>
      20             : #include <boost/test/execution_monitor.hpp>
      21             : 
      22             : #include <boost/test/tree/test_unit.hpp>
      23             : #include <boost/test/tree/visitor.hpp>
      24             : #include <boost/test/tree/test_case_counter.hpp>
      25             : #include <boost/test/tree/traverse.hpp>
      26             : 
      27             : // Boost
      28             : #include <boost/cstdlib.hpp>
      29             : 
      30             : // STL
      31             : #include <map>
      32             : 
      33             : #include <boost/test/detail/suppress_warnings.hpp>
      34             : 
      35             : //____________________________________________________________________________//
      36             : 
      37             : namespace boost {
      38             : namespace unit_test {
      39             : 
      40             : // ************************************************************************** //
      41             : // **************                 test_results                 ************** //
      42             : // ************************************************************************** //
      43             : 
      44       44050 : test_results::test_results()
      45       22025 : {
      46       22025 :     clear();
      47       44050 : }
      48             : 
      49             : //____________________________________________________________________________//
      50             : 
      51             : bool
      52         987 : test_results::passed() const
      53             : {
      54             :     // if it is skipped, it is not passed. However, if any children is not failed/aborted
      55             :     // then their skipped status is not taken into account.
      56        1974 :     return  !p_skipped                                  &&
      57         987 :             p_test_cases_failed == 0                    &&
      58         987 :             p_assertions_failed <= p_expected_failures  &&
      59             :             // p_test_cases_skipped == 0                   &&
      60         987 :             !p_timed_out                                 &&
      61         987 :             p_test_cases_timed_out == 0                  &&
      62         987 :             !aborted();
      63             : }
      64             : 
      65             : //____________________________________________________________________________//
      66             : 
      67             : bool
      68         987 : test_results::aborted() const
      69             : {
      70         987 :     return  p_aborted;
      71             : }
      72             : 
      73             : //____________________________________________________________________________//
      74             : 
      75             : bool
      76           0 : test_results::skipped() const
      77             : {
      78           0 :     return  p_skipped;
      79             : }
      80             : 
      81             : //____________________________________________________________________________//
      82             : 
      83             : int
      84         145 : test_results::result_code() const
      85             : {
      86         145 :     return passed() ? exit_success
      87           0 :            : ( (p_assertions_failed > p_expected_failures || p_skipped || p_timed_out || p_test_cases_timed_out )
      88             :                     ? exit_test_failure
      89             :                     : exit_exception_failure );
      90             : }
      91             : 
      92             : //____________________________________________________________________________//
      93             : 
      94             : void
      95       21722 : test_results::operator+=( test_results const& tr )
      96             : {
      97       21722 :     p_test_suites.value         += tr.p_test_suites;
      98       21722 :     p_assertions_passed.value   += tr.p_assertions_passed;
      99       21722 :     p_assertions_failed.value   += tr.p_assertions_failed;
     100       21722 :     p_warnings_failed.value     += tr.p_warnings_failed;
     101       21722 :     p_test_cases_passed.value   += tr.p_test_cases_passed;
     102       21722 :     p_test_cases_warned.value   += tr.p_test_cases_warned;
     103       21722 :     p_test_cases_failed.value   += tr.p_test_cases_failed;
     104       21722 :     p_test_cases_skipped.value  += tr.p_test_cases_skipped;
     105       21722 :     p_test_cases_aborted.value  += tr.p_test_cases_aborted;
     106       21722 :     p_test_cases_timed_out.value += tr.p_test_cases_timed_out;
     107       21722 :     p_test_suites_timed_out.value += tr.p_test_suites_timed_out;
     108       21722 :     p_duration_microseconds.value += tr.p_duration_microseconds;
     109       21722 : }
     110             : 
     111             : //____________________________________________________________________________//
     112             : 
     113             : void
     114       44050 : test_results::clear()
     115             : {
     116       44050 :     p_test_suites.value         = 0;
     117       44050 :     p_assertions_passed.value   = 0;
     118       44050 :     p_assertions_failed.value   = 0;
     119       44050 :     p_warnings_failed.value     = 0;
     120       44050 :     p_expected_failures.value   = 0;
     121       44050 :     p_test_cases_passed.value   = 0;
     122       44050 :     p_test_cases_warned.value   = 0;
     123       44050 :     p_test_cases_failed.value   = 0;
     124       44050 :     p_test_cases_skipped.value  = 0;
     125       44050 :     p_test_cases_aborted.value  = 0;
     126       44050 :     p_test_cases_timed_out.value = 0;
     127       44050 :     p_test_suites_timed_out.value = 0;
     128       44050 :     p_duration_microseconds.value= 0;
     129       44050 :     p_aborted.value             = false;
     130       44050 :     p_skipped.value             = false;
     131       44050 :     p_timed_out.value           = false;
     132       44050 : }
     133             : 
     134             : //____________________________________________________________________________//
     135             : 
     136             : // ************************************************************************** //
     137             : // **************               results_collector              ************** //
     138             : // ************************************************************************** //
     139             : 
     140             : namespace {
     141             : 
     142             : struct results_collector_impl {
     143             :     std::map<test_unit_id,test_results> m_results_store;
     144             : };
     145             : 
     146     8882887 : results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
     147             : 
     148             : // deletes the entries of results_collector_impl
     149             : class clear_subtree_result : public test_tree_visitor {
     150             : public:
     151         292 :     clear_subtree_result(results_collector_impl& store)
     152         146 :     : m_store( store )
     153         438 :     {}
     154             : 
     155             : private:
     156        1041 :     bool visit( test_unit const& tu) BOOST_OVERRIDE
     157             :     {
     158             :       typedef std::map<test_unit_id,test_results>::iterator iterator;
     159        1041 :       iterator found = m_store.m_results_store.find(tu.p_id);
     160        1041 :       if(found != m_store.m_results_store.end()) {
     161           0 :         m_store.m_results_store.erase( found );
     162           0 :       }
     163        1041 :       return true;
     164             :     }
     165             : 
     166             :     results_collector_impl& m_store;
     167             : };
     168             : 
     169             : } // local namespace
     170             : 
     171             : //____________________________________________________________________________//
     172             : 
     173         146 : BOOST_TEST_SINGLETON_CONS_IMPL( results_collector_t )
     174             : 
     175             : //____________________________________________________________________________//
     176             : 
     177             : void
     178         146 : results_collector_t::test_start( counter_t, test_unit_id id )
     179             : {
     180             :     // deletes the results under id only
     181         146 :     clear_subtree_result tree_clear(s_rc_impl());
     182         146 :     traverse_test_tree( id, tree_clear );
     183         146 : }
     184             : 
     185             : //____________________________________________________________________________//
     186             : 
     187             : void
     188        1023 : results_collector_t::test_unit_start( test_unit const& tu )
     189             : {
     190             :     // init test_results entry
     191        1023 :     test_results& tr = s_rc_impl().m_results_store[tu.p_id];
     192             : 
     193        1023 :     tr.clear();
     194             : 
     195        1023 :     tr.p_expected_failures.value = tu.p_expected_failures;
     196        1023 : }
     197             : 
     198             : //____________________________________________________________________________//
     199             : 
     200             : class results_collect_helper : public test_tree_visitor {
     201             : public:
     202         580 :     explicit results_collect_helper( test_results& tr, test_unit const& ts ) : m_tr( tr ), m_ts( ts ) {}
     203             : 
     204         697 :     void    visit( test_case const& tc ) BOOST_OVERRIDE
     205             :     {
     206         697 :         test_results const& tr = results_collector.results( tc.p_id );
     207         697 :         m_tr += tr;
     208             : 
     209         697 :         if( tr.passed() ) {
     210         697 :             if( tr.p_warnings_failed )
     211           0 :                 m_tr.p_test_cases_warned.value++;
     212             :             else
     213         697 :                 m_tr.p_test_cases_passed.value++;
     214         697 :         }
     215           0 :         else if( tr.p_timed_out ) {
     216           0 :             m_tr.p_test_cases_timed_out.value++;
     217           0 :         }
     218           0 :         else if( tr.p_skipped || !tc.is_enabled() ) {
     219           0 :             m_tr.p_test_cases_skipped.value++;
     220           0 :         }
     221             :         else {
     222           0 :             if( tr.p_aborted )
     223           0 :                 m_tr.p_test_cases_aborted.value++;
     224             : 
     225           0 :             m_tr.p_test_cases_failed.value++;
     226             :         }
     227         697 :     }
     228       21315 :     bool    test_suite_start( test_suite const& ts ) BOOST_OVERRIDE
     229             :     {
     230       21315 :         if( m_ts.p_id == ts.p_id )
     231         290 :             return true;
     232             : 
     233       21025 :         m_tr += results_collector.results( ts.p_id );
     234       21025 :         m_tr.p_test_suites.value++;
     235             : 
     236       21025 :         if( results_collector.results( ts.p_id ).p_timed_out )
     237           0 :             m_tr.p_test_suites_timed_out.value++;
     238       21025 :         return false;
     239       21315 :     }
     240             : 
     241             : private:
     242             :     // Data members
     243             :     test_results&       m_tr;
     244             :     test_unit const&    m_ts;
     245             : };
     246             : 
     247             : //____________________________________________________________________________//
     248             : 
     249             : void
     250        1020 : results_collector_t::test_unit_finish( test_unit const& tu, unsigned long elapsed_in_microseconds )
     251             : {
     252        1020 :     test_results & tr = s_rc_impl().m_results_store[tu.p_id];
     253        1020 :     if( tu.p_type == TUT_SUITE ) {
     254         290 :         results_collect_helper ch( tr, tu );
     255         290 :         traverse_test_tree( tu, ch, true ); // true to ignore the status: we need to count the skipped/disabled tests
     256         290 :     }
     257             :     else {
     258         730 :         bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
     259         730 :         if( !num_failures_match )
     260           0 :             BOOST_TEST_FRAMEWORK_MESSAGE( "Test case " << tu.full_name() << " has fewer failures than expected" );
     261             : 
     262         730 :         bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
     263         730 :         if( !check_any_assertions )
     264           3 :             BOOST_TEST_FRAMEWORK_MESSAGE( "Test case " << tu.full_name() << " did not check any assertions" );
     265             :     }
     266        1020 :     tr.p_duration_microseconds.value = elapsed_in_microseconds;
     267        1020 : }
     268             : 
     269             : //____________________________________________________________________________//
     270             : 
     271             : void
     272       21002 : results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
     273             : {
     274       21002 :     test_results& tr = s_rc_impl().m_results_store[tu.p_id];
     275       21002 :     tr.clear();
     276             : 
     277       21002 :     tr.p_skipped.value = true;
     278             : 
     279       21002 :     if( tu.p_type == TUT_SUITE ) {
     280       21002 :         test_case_counter tcc(true);
     281       21002 :         traverse_test_tree( tu, tcc, true ); // true because need to count the disabled tests/units
     282             : 
     283       21002 :         tr.p_test_cases_skipped.value = tcc.p_count;
     284       21002 :     }
     285       21002 : }
     286             : 
     287             : //____________________________________________________________________________//
     288             : 
     289             : void
     290           0 : results_collector_t::test_unit_timed_out(test_unit const& tu)
     291             : {
     292           0 :     test_results& tr = s_rc_impl().m_results_store[tu.p_id];
     293           0 :     tr.p_timed_out.value = true;
     294           0 : }
     295             : 
     296             : //____________________________________________________________________________//
     297             : 
     298             : void
     299     8816659 : results_collector_t::assertion_result( unit_test::assertion_result ar )
     300             : {
     301     8816659 :     test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
     302             : 
     303     8816659 :     switch( ar ) {
     304     8816659 :     case AR_PASSED: tr.p_assertions_passed.value++; break;
     305           0 :     case AR_FAILED: tr.p_assertions_failed.value++; break;
     306           0 :     case AR_TRIGGERED: tr.p_warnings_failed.value++; break;
     307             :     }
     308             : 
     309     8816659 :     if( tr.p_assertions_failed == 1 )
     310           0 :         first_failed_assertion();
     311     8816659 : }
     312             : 
     313             : //____________________________________________________________________________//
     314             : 
     315             : void
     316           0 : results_collector_t::exception_caught( execution_exception const& ex)
     317             : {
     318           0 :     test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
     319             : 
     320           0 :     tr.p_assertions_failed.value++;
     321           0 :     if( ex.code() == execution_exception::timeout_error ) {
     322           0 :         tr.p_timed_out.value = true;
     323           0 :     }
     324           0 : }
     325             : 
     326             : //____________________________________________________________________________//
     327             : 
     328             : void
     329           0 : results_collector_t::test_unit_aborted( test_unit const& tu )
     330             : {
     331           0 :     s_rc_impl().m_results_store[tu.p_id].p_aborted.value = true;
     332           0 : }
     333             : 
     334             : //____________________________________________________________________________//
     335             : 
     336             : test_results const&
     337       43037 : results_collector_t::results( test_unit_id id ) const
     338             : {
     339       43037 :     return s_rc_impl().m_results_store[id];
     340             : }
     341             : 
     342             : //____________________________________________________________________________//
     343             : 
     344             : } // namespace unit_test
     345             : } // namespace boost
     346             : 
     347             : #include <boost/test/detail/enable_warnings.hpp>
     348             : 
     349             : #endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER

Generated by: LCOV version 1.16