LCOV - code coverage report
Current view: top level - opt/homebrew/include/boost/test/impl - unit_test_main.ipp (source / functions) Hit Total Coverage
Test: test_dash_coverage.info Lines: 22 120 18.3 %
Date: 2026-06-25 07:23:51 Functions: 4 29 13.8 %

          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        : $RCSfile$
       9             : //
      10             : //  Version     : $Revision$
      11             : //
      12             : //  Description : main function implementation for Unit Test Framework
      13             : // ***************************************************************************
      14             : 
      15             : #ifndef BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
      16             : #define BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
      17             : 
      18             : // Boost.Test
      19             : #include <boost/test/framework.hpp>
      20             : #include <boost/test/results_collector.hpp>
      21             : #include <boost/test/results_reporter.hpp>
      22             : 
      23             : #include <boost/test/tree/visitor.hpp>
      24             : #include <boost/test/tree/test_unit.hpp>
      25             : #include <boost/test/tree/traverse.hpp>
      26             : 
      27             : #include <boost/test/unit_test_parameters.hpp>
      28             : 
      29             : #include <boost/test/utils/foreach.hpp>
      30             : #include <boost/test/utils/basic_cstring/io.hpp>
      31             : 
      32             : // Boost
      33             : #include <boost/core/ignore_unused.hpp>
      34             : #include <boost/cstdlib.hpp>
      35             : 
      36             : // STL
      37             : #include <cstdio>
      38             : #include <stdexcept>
      39             : #include <iostream>
      40             : #include <iomanip>
      41             : #include <iterator>
      42             : #include <set>
      43             : 
      44             : #include <boost/test/detail/suppress_warnings.hpp>
      45             : 
      46             : //____________________________________________________________________________//
      47             : 
      48             : namespace boost {
      49             : namespace unit_test {
      50             : 
      51             : namespace ut_detail {
      52             : 
      53             : // ************************************************************************** //
      54             : // **************             hrf_content_reporter             ************** //
      55             : // ************************************************************************** //
      56             : 
      57             : struct hrf_content_reporter : test_tree_visitor {
      58           0 :     explicit        hrf_content_reporter( std::ostream& os ) : m_os( os ), m_indent( -4 ) {} // skip master test suite
      59             : 
      60             : private:
      61           0 :     void            report_test_unit( test_unit const& tu )
      62             :     {
      63           0 :         m_os << std::setw( m_indent ) << "" << tu.p_name;
      64           0 :         m_os << (tu.p_default_status == test_unit::RS_ENABLED ? "*" : " ");
      65             :         //m_os << '[' << tu.p_sibling_rank << ']';
      66           0 :         if( !tu.p_description->empty() )
      67           0 :             m_os << ": " << tu.p_description;
      68             : 
      69           0 :         m_os << "\n";
      70           0 :     }
      71           0 :     void    visit( test_case const& tc ) BOOST_OVERRIDE { report_test_unit( tc ); }
      72           0 :     bool    test_suite_start( test_suite const& ts ) BOOST_OVERRIDE
      73             :     {
      74           0 :         if( m_indent >= 0 )
      75           0 :             report_test_unit( ts );
      76           0 :         m_indent += 4;
      77           0 :         return true;
      78             :     }
      79           0 :     void    test_suite_finish( test_suite const& ) BOOST_OVERRIDE
      80             :     {
      81           0 :         m_indent -= 4;
      82           0 :     }
      83             : 
      84             :     // Data members
      85             :     std::ostream&   m_os;
      86             :     int             m_indent;
      87             : };
      88             : 
      89             : // ************************************************************************** //
      90             : // **************             dot_content_reporter             ************** //
      91             : // ************************************************************************** //
      92             : 
      93             : struct dot_content_reporter : test_tree_visitor {
      94           0 :     explicit        dot_content_reporter( std::ostream& os ) : m_os( os ) {}
      95             : 
      96             : private:
      97           0 :     void            report_test_unit( test_unit const& tu )
      98             :     {
      99           0 :         bool master_ts = tu.p_parent_id == INV_TEST_UNIT_ID;
     100             : 
     101           0 :         m_os << "tu" << tu.p_id;
     102             : 
     103           0 :         m_os << (master_ts ? "[shape=ellipse,peripheries=2" : "[shape=Mrecord" );
     104             : 
     105           0 :         m_os << ",fontname=Helvetica";
     106             : 
     107           0 :         m_os << (tu.p_default_status == test_unit::RS_ENABLED ? ",color=green" : ",color=yellow");
     108             : 
     109           0 :         if( master_ts )
     110           0 :             m_os << ",label=\"" << tu.p_name << "\"];\n";
     111             :         else {
     112           0 :             m_os << ",label=\"" << tu.p_name << "|" << tu.p_file_name << "(" << tu.p_line_num << ")";
     113           0 :             if( tu.p_timeout > 0  )
     114           0 :                 m_os << "|timeout=" << tu.p_timeout;
     115           0 :             if( tu.p_expected_failures != 0  )
     116           0 :                 m_os << "|expected failures=" << tu.p_expected_failures;
     117           0 :             if( !tu.p_labels->empty() ) {
     118           0 :                 m_os << "|labels:";
     119             : 
     120           0 :                 BOOST_TEST_FOREACH( std::string const&, l, tu.p_labels.get() )
     121           0 :                     m_os << " @" << l;
     122           0 :             }
     123           0 :             m_os << "\"];\n";
     124             :         }
     125             : 
     126           0 :         if( !master_ts )
     127           0 :             m_os << "tu" << tu.p_parent_id << " -> " << "tu" << tu.p_id << ";\n";
     128             : 
     129           0 :         BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
     130           0 :             test_unit const& dep = framework::get( dep_id, TUT_ANY );
     131             : 
     132           0 :             m_os << "tu" << tu.p_id << " -> " << "tu" << dep.p_id << "[color=red,style=dotted,constraint=false];\n";
     133           0 :         }
     134             : 
     135           0 :     }
     136           0 :     void    visit( test_case const& tc ) BOOST_OVERRIDE
     137             :     { 
     138           0 :         report_test_unit( tc );
     139           0 :     }
     140           0 :     bool    test_suite_start( test_suite const& ts ) BOOST_OVERRIDE
     141             :     {
     142           0 :         if( ts.p_parent_id == INV_TEST_UNIT_ID )
     143           0 :             m_os << "digraph G {rankdir=LR;\n";
     144             : 
     145           0 :         report_test_unit( ts );
     146             : 
     147           0 :         m_os << "{\n";
     148             : 
     149           0 :         return true;
     150             :     }
     151           0 :     void    test_suite_finish( test_suite const& ts ) BOOST_OVERRIDE
     152             :     {
     153           0 :         m_os << "}\n";
     154           0 :         if( ts.p_parent_id == INV_TEST_UNIT_ID )
     155           0 :             m_os << "}\n";
     156           0 :     }
     157             : 
     158             :     std::ostream&   m_os;
     159             : };
     160             : 
     161             : // ************************************************************************** //
     162             : // **************               labels_collector               ************** //
     163             : // ************************************************************************** //
     164             : 
     165             : struct labels_collector : test_tree_visitor {
     166           0 :     std::set<std::string> const& labels() const { return m_labels; }
     167             : 
     168             : private:
     169           0 :     bool            visit( test_unit const& tu ) BOOST_OVERRIDE
     170             :     {
     171           0 :         m_labels.insert( tu.p_labels->begin(), tu.p_labels->end() );
     172           0 :         return true;
     173             :     }
     174             : 
     175             :     // Data members
     176             :     std::set<std::string>   m_labels;
     177             : };
     178             : 
     179             : struct framework_shutdown_helper {
     180         290 :     ~framework_shutdown_helper() {
     181             :         try {
     182         145 :             framework::shutdown();
     183         145 :         }
     184             :         catch(...) {
     185           0 :             std::cerr << "Boost.Test shutdown exception caught" << std::endl;
     186           0 :         }
     187         290 :     }
     188             : };
     189             : 
     190             : } // namespace ut_detail
     191             : 
     192             : // ************************************************************************** //
     193             : // **************                  unit_test_main              ************** //
     194             : // ************************************************************************** //
     195             : 
     196             : 
     197             : 
     198             : int BOOST_TEST_DECL
     199         147 : unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
     200             : {
     201         147 :     int result_code = 0;
     202             : 
     203             :     ut_detail::framework_shutdown_helper shutdown_helper;
     204         147 :     boost::ignore_unused(shutdown_helper);
     205             : 
     206             :     BOOST_TEST_I_TRY {
     207             :         
     208         147 :         framework::init( init_func, argc, argv );
     209             : 
     210         146 :         if( runtime_config::get<bool>( runtime_config::btrt_wait_for_debugger ) ) {
     211           0 :             results_reporter::get_stream() << "Press any key to continue..." << std::endl;
     212             : 
     213             :             // getchar is defined as a macro in uClibc. Use parenthesis to fix
     214             :             // gcc bug 58952 for gcc <= 4.8.2.
     215           0 :             (std::getchar)();
     216           0 :             results_reporter::get_stream() << "Continuing..." << std::endl;
     217           0 :         }
     218             : 
     219         146 :         framework::finalize_setup_phase();
     220             : 
     221         146 :         output_format list_cont = runtime_config::get<output_format>( runtime_config::btrt_list_content );
     222         146 :         if( list_cont != unit_test::OF_INVALID ) {
     223           0 :             if( list_cont == unit_test::OF_DOT ) {
     224           0 :                 ut_detail::dot_content_reporter reporter( results_reporter::get_stream() );
     225             : 
     226           0 :                 traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
     227           0 :             }
     228             :             else {
     229           0 :                 ut_detail::hrf_content_reporter reporter( results_reporter::get_stream() );
     230             : 
     231           0 :                 traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
     232           0 :             }
     233             : 
     234           0 :             return boost::exit_success;
     235             :         }
     236             : 
     237         146 :         if( runtime_config::get<bool>( runtime_config::btrt_list_labels ) ) {
     238           0 :             ut_detail::labels_collector collector;
     239             : 
     240           0 :             traverse_test_tree( framework::master_test_suite().p_id, collector, true );
     241             : 
     242           0 :             results_reporter::get_stream() << "Available labels:\n  ";
     243           0 :             std::copy( collector.labels().begin(), collector.labels().end(), 
     244           0 :                        std::ostream_iterator<std::string>( results_reporter::get_stream(), "\n  " ) );
     245           0 :             results_reporter::get_stream() << "\n";
     246             : 
     247           0 :             return boost::exit_success;
     248           0 :         }
     249             : 
     250         146 :         framework::run();
     251             : 
     252         290 :         result_code = !runtime_config::get<bool>( runtime_config::btrt_result_code )
     253             :                         ? boost::exit_success
     254         145 :                         : results_collector.results( framework::master_test_suite().p_id ).result_code();
     255         145 :     }
     256             :     BOOST_TEST_I_CATCH( framework::nothing_to_test, ex ) {
     257           0 :         result_code = ex.m_result_code;
     258           0 :     }
     259             :     BOOST_TEST_I_CATCH( framework::internal_error, ex ) {
     260           0 :         results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
     261             : 
     262           0 :         result_code = boost::exit_exception_failure;
     263           0 :     }
     264             :     BOOST_TEST_I_CATCH( framework::setup_error, ex ) {
     265           0 :         results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
     266             : 
     267           0 :         result_code = boost::exit_exception_failure;
     268           0 :     }
     269             :     BOOST_TEST_I_CATCH( std::logic_error, ex ) {
     270           0 :         results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
     271             : 
     272           0 :         result_code = boost::exit_exception_failure;
     273           0 :     }
     274             :     BOOST_TEST_I_CATCHALL() {
     275           0 :         results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
     276             : 
     277           0 :         result_code = boost::exit_exception_failure;
     278           0 :     }
     279             : 
     280         145 :     return result_code;
     281         147 : }
     282             : 
     283             : } // namespace unit_test
     284             : } // namespace boost
     285             : 
     286             : #if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
     287             : 
     288             : // ************************************************************************** //
     289             : // **************        main function for tests using lib     ************** //
     290             : // ************************************************************************** //
     291             : 
     292             : int BOOST_TEST_CALL_DECL
     293         146 : main( int argc, char* argv[] )
     294             : {
     295             :     // prototype for user's unit test init function
     296             : #ifdef BOOST_TEST_ALTERNATIVE_INIT_API
     297             :     extern bool init_unit_test();
     298             : 
     299             :     boost::unit_test::init_unit_test_func init_func = &init_unit_test;
     300             : #else
     301             :     extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
     302             : 
     303         146 :     boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
     304             : #endif
     305             : 
     306         146 :     return ::boost::unit_test::unit_test_main( init_func, argc, argv );
     307             : }
     308             : 
     309             : #endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
     310             : 
     311             : //____________________________________________________________________________//
     312             : 
     313             : #include <boost/test/detail/enable_warnings.hpp>
     314             : 
     315             : #endif // BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER

Generated by: LCOV version 1.16