summaryrefslogtreecommitdiff
path: root/boost/test/impl/unit_test_main.ipp
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test/impl/unit_test_main.ipp')
-rw-r--r--boost/test/impl/unit_test_main.ipp288
1 files changed, 167 insertions, 121 deletions
diff --git a/boost/test/impl/unit_test_main.ipp b/boost/test/impl/unit_test_main.ipp
index adedf35180..327e14de30 100644
--- a/boost/test/impl/unit_test_main.ipp
+++ b/boost/test/impl/unit_test_main.ipp
@@ -1,4 +1,4 @@
-// (C) Copyright Gennadiy Rozental 2001-2008.
+// (C) Copyright Gennadiy Rozental 2001-2014.
// 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)
@@ -18,154 +18,164 @@
// Boost.Test
#include <boost/test/framework.hpp>
#include <boost/test/results_collector.hpp>
-#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/results_reporter.hpp>
-#include <boost/test/detail/unit_test_parameters.hpp>
+#include <boost/test/tree/visitor.hpp>
+#include <boost/test/tree/test_unit.hpp>
+#include <boost/test/tree/traverse.hpp>
-#if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
-#define BOOST_TEST_SUPPORT_RUN_BY_NAME
-#include <boost/test/utils/iterator/token_iterator.hpp>
-#endif
+#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>
-#include <boost/bind.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 {
+
// ************************************************************************** //
-// ************** test_case_filter ************** //
+// ************** hrf_content_reporter ************** //
// ************************************************************************** //
-class test_case_filter : public test_tree_visitor {
-public:
- struct single_filter {
- single_filter( const_string in )
- {
- if( in == "*" )
- m_kind = SFK_ALL;
- else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
- m_kind = SFK_SUBSTR;
- m_value = in.substr( 1, in.size()-1 );
- }
- else if( first_char( in ) == '*' ) {
- m_kind = SFK_TRAILING;
- m_value = in.substr( 1 );
- }
- else if( last_char( in ) == '*' ) {
- m_kind = SFK_LEADING;
- m_value = in.substr( 0, in.size()-1 );
- }
- else {
- m_kind = SFK_MATCH;
- m_value = in;
- }
- };
+struct hrf_content_reporter : test_tree_visitor {
+ explicit hrf_content_reporter( std::ostream& os ) : m_os( os ), m_indent( -4 ) {} // skip master test suite
- bool pass( test_unit const& tu ) const
- {
- const_string name( tu.p_name );
-
- switch( m_kind ) {
- default:
- case SFK_ALL:
- return true;
+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;
- case SFK_LEADING:
- return name.substr( 0, m_value.size() ) == m_value;
+ 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;
+ }
- case SFK_TRAILING:
- return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
+ // Data members
+ std::ostream& m_os;
+ int m_indent;
+};
- case SFK_SUBSTR:
- return name.find( m_value ) != const_string::npos;
+// ************************************************************************** //
+// ************** dot_content_reporter ************** //
+// ************************************************************************** //
- case SFK_MATCH:
- return m_value == tu.p_name.get();
- }
- }
- enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
-
- kind m_kind;
- const_string m_value;
- };
- // Constructor
-#ifndef BOOST_TEST_SUPPORT_RUN_BY_NAME
- explicit test_case_filter( const_string ) : m_depth( 0 ) {}
-#else
- explicit test_case_filter( const_string tc_to_run )
- : m_depth( 0 )
+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 )
{
- string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
+ bool master_ts = tu.p_parent_id == INV_TEST_UNIT_ID;
- while( tit != string_token_iterator() ) {
- m_filters.push_back(
- std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
- string_token_iterator() ) );
+ m_os << "tu" << tu.p_id;
- ++tit;
- }
- }
-#endif
-
- void filter_unit( test_unit const& tu )
- {
- if( (++m_depth - 1) > m_filters.size() ) {
- tu.p_enabled.value = true;
- return;
- }
+ m_os << (master_ts ? "[shape=ellipse,peripheries=2" : "[shape=Mrecord" );
- if( m_depth == 1 )
- return;
+ m_os << ",fontname=Helvetica";
- std::vector<single_filter> const& filters = m_filters[m_depth-2];
+ m_os << (tu.is_enabled() ? ",color=green" : ",color=yellow");
- tu.p_enabled.value =
- std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end();
- }
+ 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:";
- // test tree visitor interface
- virtual void visit( test_case const& tc )
- {
- if( m_depth < m_filters.size() ) {
- tc.p_enabled.value = false;
- return;
+ BOOST_TEST_FOREACH( std::string const&, l, tu.p_labels.get() )
+ m_os << " @" << l;
+ }
+ m_os << "\"];\n";
}
- filter_unit( tc );
+ if( !master_ts )
+ m_os << "tu" << tu.p_parent_id << " -> " << "tu" << tu.p_id << ";\n";
- --m_depth;
- }
+ BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
+ test_unit const& dep = framework::get( dep_id, TUT_ANY );
- virtual bool test_suite_start( test_suite const& ts )
+ m_os << "tu" << tu.p_id << " -> " << "tu" << dep.p_id << "[color=red,style=dotted,constraint=false];\n";
+ }
+
+ }
+ virtual void visit( test_case const& tc )
{
- filter_unit( ts );
+ 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";
- if( !ts.p_enabled )
- --m_depth;
+ report_test_unit( ts );
- return ts.p_enabled;
+ 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";
}
- virtual void test_suite_finish( test_suite const& ) { --m_depth; }
+ 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::vector<std::vector<single_filter> > m_filters;
- unsigned m_depth;
+ std::set<std::string> m_labels;
};
+} // namespace ut_detail
+
// ************************************************************************** //
// ************** unit_test_main ************** //
// ************************************************************************** //
@@ -173,45 +183,81 @@ private:
int BOOST_TEST_DECL
unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
{
- try {
+ int result_code = 0;
+
+ BOOST_TEST_IMPL_TRY {
framework::init( init_func, argc, argv );
- if( !runtime_config::test_to_run().is_empty() ) {
- test_case_filter filter( runtime_config::test_to_run() );
+ if( runtime_config::wait_for_debugger() ) {
+ results_reporter::get_stream() << "Press any key to continue..." << std::endl;
+
+ std::getchar();
+ results_reporter::get_stream() << "Continuing..." << std::endl;
+ }
+
+ framework::finalize_setup_phase();
+
+ if( runtime_config::list_content() != unit_test::OF_INVALID ) {
+ if( runtime_config::list_content() == 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 );
+ }
- traverse_test_tree( framework::master_test_suite().p_id, filter );
+ return boost::exit_success;
+ }
+
+ if( 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();
- return runtime_config::no_result_code()
- ? boost::exit_success
- : results_collector.results( framework::master_test_suite().p_id ).result_code();
+ result_code = runtime_config::no_result_code()
+ ? boost::exit_success
+ : results_collector.results( framework::master_test_suite().p_id ).result_code();
}
- catch( framework::nothing_to_test const& ) {
- return boost::exit_success;
+ BOOST_TEST_IMPL_CATCH0( framework::nothing_to_test ) {
+ result_code = boost::exit_success;
}
- catch( framework::internal_error const& ex ) {
+ BOOST_TEST_IMPL_CATCH( framework::internal_error, ex ) {
results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
-
- return boost::exit_exception_failure;
+
+ result_code = boost::exit_exception_failure;
}
- catch( framework::setup_error const& ex ) {
+ BOOST_TEST_IMPL_CATCH( framework::setup_error, ex ) {
results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
-
- return boost::exit_exception_failure;
+
+ result_code = boost::exit_exception_failure;
}
- catch( ... ) {
+ BOOST_TEST_IMPL_CATCHALL() {
results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
-
- return boost::exit_exception_failure;
+
+ 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)