296 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			296 lines
		
	
	
		
			9.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
| //  (C) Copyright Gennadiy Rozental 2001.
 | |
| //  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$
 | |
| //
 | |
| //  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/results_reporter.hpp>
 | |
| 
 | |
| #include <boost/test/tree/visitor.hpp>
 | |
| #include <boost/test/tree/test_unit.hpp>
 | |
| #include <boost/test/tree/traverse.hpp>
 | |
| 
 | |
| #include <boost/test/unit_test_parameters.hpp>
 | |
| 
 | |
| #include <boost/test/utils/foreach.hpp>
 | |
| #include <boost/test/utils/basic_cstring/io.hpp>
 | |
| 
 | |
| // Boost
 | |
| #include <boost/cstdlib.hpp>
 | |
| 
 | |
| // STL
 | |
| #include <cstdio>
 | |
| #include <stdexcept>
 | |
| #include <iostream>
 | |
| #include <iomanip>
 | |
| #include <set>
 | |
| 
 | |
| #include <boost/test/detail/suppress_warnings.hpp>
 | |
| 
 | |
| //____________________________________________________________________________//
 | |
| 
 | |
| namespace boost {
 | |
| namespace unit_test {
 | |
| 
 | |
| namespace ut_detail {
 | |
| 
 | |
| // ************************************************************************** //
 | |
| // **************             hrf_content_reporter             ************** //
 | |
| // ************************************************************************** //
 | |
| 
 | |
| struct hrf_content_reporter : test_tree_visitor {
 | |
|     explicit        hrf_content_reporter( std::ostream& os ) : m_os( os ), m_indent( -4 ) {} // skip master test suite
 | |
| 
 | |
| private:
 | |
|     void            report_test_unit( test_unit const& tu )
 | |
|     {
 | |
|         m_os << std::setw( m_indent ) << "" << tu.p_name;
 | |
|         m_os << (tu.p_default_status == test_unit::RS_ENABLED ? "*" : " ");
 | |
|         //m_os << '[' << tu.p_sibling_rank << ']';
 | |
|         if( !tu.p_description->empty() )
 | |
|             m_os << ": " << tu.p_description;
 | |
| 
 | |
|         m_os << "\n";
 | |
|     }
 | |
|     virtual void    visit( test_case const& tc ) { report_test_unit( tc ); }
 | |
|     virtual bool    test_suite_start( test_suite const& ts )
 | |
|     {
 | |
|         if( m_indent >= 0 )
 | |
|             report_test_unit( ts );
 | |
|         m_indent += 4;
 | |
|         return true;
 | |
|     }
 | |
|     virtual void    test_suite_finish( test_suite const& )
 | |
|     {
 | |
|         m_indent -= 4;
 | |
|     }
 | |
| 
 | |
|     // Data members
 | |
|     std::ostream&   m_os;
 | |
|     int             m_indent;
 | |
| };
 | |
| 
 | |
| // ************************************************************************** //
 | |
| // **************             dot_content_reporter             ************** //
 | |
| // ************************************************************************** //
 | |
| 
 | |
| struct dot_content_reporter : test_tree_visitor {
 | |
|     explicit        dot_content_reporter( std::ostream& os ) : m_os( os ) {}
 | |
| 
 | |
| private:
 | |
|     void            report_test_unit( test_unit const& tu )
 | |
|     {
 | |
|         bool master_ts = tu.p_parent_id == INV_TEST_UNIT_ID;
 | |
| 
 | |
|         m_os << "tu" << tu.p_id;
 | |
| 
 | |
|         m_os << (master_ts ? "[shape=ellipse,peripheries=2" : "[shape=Mrecord" );
 | |
| 
 | |
|         m_os << ",fontname=Helvetica";
 | |
| 
 | |
|         m_os << (tu.p_default_status == test_unit::RS_ENABLED ? ",color=green" : ",color=yellow");
 | |
| 
 | |
|         if( master_ts )
 | |
|             m_os << ",label=\"" << tu.p_name << "\"];\n";
 | |
|         else {
 | |
|             m_os << ",label=\"" << tu.p_name << "|" << tu.p_file_name << "(" << tu.p_line_num << ")";
 | |
|             if( tu.p_timeout > 0  )
 | |
|                 m_os << "|timeout=" << tu.p_timeout;
 | |
|             if( tu.p_expected_failures != 0  )
 | |
|                 m_os << "|expected failures=" << tu.p_expected_failures;
 | |
|             if( !tu.p_labels->empty() ) {
 | |
|                 m_os << "|labels:";
 | |
| 
 | |
|                 BOOST_TEST_FOREACH( std::string const&, l, tu.p_labels.get() )
 | |
|                     m_os << " @" << l;
 | |
|             }
 | |
|             m_os << "\"];\n";
 | |
|         }
 | |
| 
 | |
|         if( !master_ts )
 | |
|             m_os << "tu" << tu.p_parent_id << " -> " << "tu" << tu.p_id << ";\n";
 | |
| 
 | |
|         BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
 | |
|             test_unit const& dep = framework::get( dep_id, TUT_ANY );
 | |
| 
 | |
|             m_os << "tu" << tu.p_id << " -> " << "tu" << dep.p_id << "[color=red,style=dotted,constraint=false];\n";
 | |
|         }
 | |
| 
 | |
|     }
 | |
|     virtual void    visit( test_case const& tc )
 | |
|     { 
 | |
|         report_test_unit( tc );
 | |
|     }
 | |
|     virtual bool    test_suite_start( test_suite const& ts )
 | |
|     {
 | |
|         if( ts.p_parent_id == INV_TEST_UNIT_ID )
 | |
|             m_os << "digraph G {rankdir=LR;\n";
 | |
| 
 | |
|         report_test_unit( ts );
 | |
| 
 | |
|         m_os << "{\n";
 | |
| 
 | |
|         return true;
 | |
|     }
 | |
|     virtual void    test_suite_finish( test_suite const& ts )
 | |
|     {
 | |
|         m_os << "}\n";
 | |
|         if( ts.p_parent_id == INV_TEST_UNIT_ID )
 | |
|             m_os << "}\n";
 | |
|     }
 | |
| 
 | |
|     std::ostream&   m_os;
 | |
| };
 | |
| 
 | |
| // ************************************************************************** //
 | |
| // **************               labels_collector               ************** //
 | |
| // ************************************************************************** //
 | |
| 
 | |
| struct labels_collector : test_tree_visitor {
 | |
|     std::set<std::string> const& labels() const { return m_labels; }
 | |
| 
 | |
| private:
 | |
|     virtual bool            visit( test_unit const& tu ) 
 | |
|     {
 | |
|         m_labels.insert( tu.p_labels->begin(), tu.p_labels->end() );
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     // Data members
 | |
|     std::set<std::string>   m_labels;
 | |
| };
 | |
| 
 | |
| } // namespace ut_detail
 | |
| 
 | |
| // ************************************************************************** //
 | |
| // **************                  unit_test_main              ************** //
 | |
| // ************************************************************************** //
 | |
| 
 | |
| int BOOST_TEST_DECL
 | |
| unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
 | |
| {
 | |
|     int result_code = 0;
 | |
| 
 | |
|     BOOST_TEST_I_TRY {
 | |
|         framework::init( init_func, argc, argv );
 | |
| 
 | |
|         if( runtime_config::get<bool>( runtime_config::WAIT_FOR_DEBUGGER ) ) {
 | |
|             results_reporter::get_stream() << "Press any key to continue..." << std::endl;
 | |
| 
 | |
|             // getchar is defined as a macro in uClibc. Use parenthesis to fix
 | |
|             // gcc bug 58952 for gcc <= 4.8.2.
 | |
|             (std::getchar)();
 | |
|             results_reporter::get_stream() << "Continuing..." << std::endl;
 | |
|         }
 | |
| 
 | |
|         framework::finalize_setup_phase();
 | |
| 
 | |
|         output_format list_cont = runtime_config::get<output_format>( runtime_config::LIST_CONTENT );
 | |
|         if( list_cont != unit_test::OF_INVALID ) {
 | |
|             if( list_cont == unit_test::OF_DOT ) {
 | |
|                 ut_detail::dot_content_reporter reporter( results_reporter::get_stream() );
 | |
| 
 | |
|                 traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
 | |
|             }
 | |
|             else {
 | |
|                 ut_detail::hrf_content_reporter reporter( results_reporter::get_stream() );
 | |
| 
 | |
|                 traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
 | |
|             }
 | |
| 
 | |
|             return boost::exit_success;
 | |
|         }
 | |
| 
 | |
|         if( runtime_config::get<bool>( runtime_config::LIST_LABELS ) ) {
 | |
|             ut_detail::labels_collector collector;
 | |
| 
 | |
|             traverse_test_tree( framework::master_test_suite().p_id, collector, true );
 | |
| 
 | |
|             results_reporter::get_stream() << "Available labels:\n  ";
 | |
|             std::copy( collector.labels().begin(), collector.labels().end(), 
 | |
|                        std::ostream_iterator<std::string>( results_reporter::get_stream(), "\n  " ) );
 | |
|             results_reporter::get_stream() << "\n";
 | |
| 
 | |
|             return boost::exit_success;
 | |
|         }
 | |
| 
 | |
|         framework::run();
 | |
| 
 | |
|         results_reporter::make_report();
 | |
| 
 | |
|         result_code = !runtime_config::get<bool>( runtime_config::RESULT_CODE )
 | |
|                         ? boost::exit_success
 | |
|                         : results_collector.results( framework::master_test_suite().p_id ).result_code();
 | |
|     }
 | |
|     BOOST_TEST_I_CATCH( framework::nothing_to_test, ex ) {
 | |
|         result_code = ex.m_result_code;
 | |
|     }
 | |
|     BOOST_TEST_I_CATCH( framework::internal_error, ex ) {
 | |
|         results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
 | |
| 
 | |
|         result_code = boost::exit_exception_failure;
 | |
|     }
 | |
|     BOOST_TEST_I_CATCH( framework::setup_error, ex ) {
 | |
|         results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
 | |
| 
 | |
|         result_code = boost::exit_exception_failure;
 | |
|     }
 | |
|     BOOST_TEST_I_CATCHALL() {
 | |
|         results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
 | |
| 
 | |
|         result_code = boost::exit_exception_failure;
 | |
|     }
 | |
| 
 | |
|     framework::shutdown();
 | |
| 
 | |
|     return result_code;
 | |
| }
 | |
| 
 | |
| } // 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
 | 
