summaryrefslogtreecommitdiff
path: root/boost/test
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test')
-rw-r--r--boost/test/data/test_case.hpp12
-rw-r--r--boost/test/impl/compiler_log_formatter.ipp2
-rw-r--r--boost/test/impl/debug.ipp2
-rw-r--r--boost/test/impl/execution_monitor.ipp12
-rw-r--r--boost/test/impl/framework.ipp74
-rw-r--r--boost/test/impl/junit_log_formatter.ipp12
-rw-r--r--boost/test/impl/test_tools.ipp8
-rw-r--r--boost/test/impl/test_tree.ipp32
-rw-r--r--boost/test/impl/unit_test_log.ipp11
-rw-r--r--boost/test/impl/unit_test_main.ipp2
-rw-r--r--boost/test/impl/unit_test_parameters.ipp121
-rw-r--r--boost/test/parameterized_test.hpp6
-rw-r--r--boost/test/tools/detail/print_helper.hpp7
-rw-r--r--boost/test/tree/test_case_template.hpp71
-rw-r--r--boost/test/unit_test_log.hpp7
-rw-r--r--boost/test/unit_test_parameters.hpp39
-rw-r--r--boost/test/utils/basic_cstring/basic_cstring.hpp4
-rw-r--r--boost/test/utils/is_forward_iterable.hpp42
-rw-r--r--boost/test/utils/named_params.hpp4
-rw-r--r--boost/test/utils/runtime/cla/parser.hpp118
-rw-r--r--boost/test/utils/runtime/errors.hpp4
-rw-r--r--boost/test/utils/runtime/parameter.hpp94
-rw-r--r--boost/test/utils/setcolor.hpp201
23 files changed, 698 insertions, 187 deletions
diff --git a/boost/test/data/test_case.hpp b/boost/test/data/test_case.hpp
index 2275f90fff..01dc91b06a 100644
--- a/boost/test/data/test_case.hpp
+++ b/boost/test/data/test_case.hpp
@@ -33,13 +33,16 @@
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/bind.hpp>
-
#include <boost/type_traits/is_copy_constructible.hpp>
-#include <boost/test/detail/suppress_warnings.hpp>
#include <boost/test/tools/detail/print_helper.hpp>
#include <boost/test/utils/string_cast.hpp>
+#include <list>
+#include <string>
+
+#include <boost/test/detail/suppress_warnings.hpp>
+
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
&& !defined(BOOST_TEST_DATASET_MAX_ARITY)
# define BOOST_TEST_DATASET_MAX_ARITY 10
@@ -161,6 +164,7 @@ public:
#if !defined(BOOST_TEST_DATASET_VARIADIC)
// see BOOST_TEST_DATASET_MAX_ARITY to increase the default supported arity
+ // there is also a limit on boost::bind
#define TC_MAKE(z,arity,_) \
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
void operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \
@@ -179,8 +183,8 @@ public:
new test_case( genTestCaseName(),
m_tc_file,
m_tc_line,
- boost::bind( &TestCase::template test_method<Arg...>,
- boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
+ std::bind( &TestCase::template test_method<Arg...>,
+ boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
}
#endif
diff --git a/boost/test/impl/compiler_log_formatter.ipp b/boost/test/impl/compiler_log_formatter.ipp
index 0e83448b14..aa0a0e229f 100644
--- a/boost/test/impl/compiler_log_formatter.ipp
+++ b/boost/test/impl/compiler_log_formatter.ipp
@@ -282,7 +282,7 @@ compiler_log_formatter::entry_context_finish( std::ostream& output, log_level l
//____________________________________________________________________________//
void
-compiler_log_formatter::log_entry_context( std::ostream& output, log_level l, const_string context_descr )
+compiler_log_formatter::log_entry_context( std::ostream& output, log_level /*l*/, const_string context_descr )
{
output << "\n " << context_descr;
}
diff --git a/boost/test/impl/debug.ipp b/boost/test/impl/debug.ipp
index f547052ded..a5e5f6da06 100644
--- a/boost/test/impl/debug.ipp
+++ b/boost/test/impl/debug.ipp
@@ -938,7 +938,7 @@ attach_debugger( bool break_or_continue )
return true;
#else // ****************************************************** default
-
+ (void) break_or_continue; // silence 'unused variable' warning
return false;
#endif
diff --git a/boost/test/impl/execution_monitor.ipp b/boost/test/impl/execution_monitor.ipp
index 94b6f9fbe7..035bb958c1 100644
--- a/boost/test/impl/execution_monitor.ipp
+++ b/boost/test/impl/execution_monitor.ipp
@@ -63,11 +63,15 @@ using std::va_list;
#endif
// to use vsnprintf
-#if defined(__QNXNTO__)
+#if defined(__QNXNTO__) || defined(__VXWORKS__)
# include <stdio.h>
using std::va_list;
#endif
+#if defined(__VXWORKS__)
+# define BOOST_TEST_LIMITED_SIGNAL_DETAILS
+#endif
+
#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
# include <windows.h>
@@ -363,11 +367,17 @@ system_signal_exception::report() const
return; // no error actually occur?
switch( m_sig_info->si_code ) {
+#ifdef __VXWORKS__
+// a bit of a hack to adapt code to small m_sig_info VxWorks uses
+#define si_addr si_value.sival_int
+#define si_band si_value.sival_int
+#else
case SI_USER:
report_error( execution_exception::system_error,
"signal: generated by kill() (or family); uid=%d; pid=%d",
(int)m_sig_info->si_uid, (int)m_sig_info->si_pid );
break;
+#endif
case SI_QUEUE:
report_error( execution_exception::system_error,
"signal: sent by sigqueue()" );
diff --git a/boost/test/impl/framework.ipp b/boost/test/impl/framework.ipp
index ca35ce1c2a..496e7de859 100644
--- a/boost/test/impl/framework.ipp
+++ b/boost/test/impl/framework.ipp
@@ -347,12 +347,10 @@ public:
, m_dep_collector( dep_collector )
{}
-private:
// test_tree_visitor interface
virtual bool visit( test_unit const& tu )
{
const_cast<test_unit&>(tu).p_run_status.value = m_new_status == test_unit::RS_INVALID ? tu.p_default_status : m_new_status;
-
if( m_dep_collector ) {
BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
test_unit const& dep = framework::get( dep_id, TUT_ANY );
@@ -369,6 +367,7 @@ private:
return true;
}
+private:
// Data members
test_unit::run_status m_new_status;
test_unit_id_list* m_dep_collector;
@@ -491,7 +490,8 @@ unsigned const TIMEOUT_EXCEEDED = static_cast<unsigned>( -1 );
class state {
public:
state()
- : m_curr_test_unit( INV_TEST_UNIT_ID )
+ : m_master_test_suite( 0 )
+ , m_curr_test_unit( INV_TEST_UNIT_ID )
, m_next_test_case_id( MIN_TEST_CASE_ID )
, m_next_test_suite_id( MIN_TEST_SUITE_ID )
, m_test_in_progress( false )
@@ -610,13 +610,27 @@ public:
tu_to_enable.pop_back();
- // 35. Ignore test units which already enabled
+ // 35. Ignore test units which are already enabled
if( tu.is_enabled() )
continue;
// set new status and add all dependencies into tu_to_enable
set_run_status enabler( test_unit::RS_ENABLED, &tu_to_enable );
traverse_test_tree( tu.p_id, enabler, true );
+
+ // Add the dependencies of the parent suites, see trac #13149
+ test_unit_id parent_id = tu.p_parent_id;
+ while( parent_id != INV_TEST_UNIT_ID
+ && parent_id != master_tu_id )
+ {
+ // we do not use the traverse_test_tree as otherwise it would enable the sibblings and subtree
+ // of the test case we want to enable (we need to enable the parent suites and their dependencies only)
+ // the parent_id needs to be enabled in order to be properly parsed by finalize_run_status, the visit
+ // does the job
+ test_unit& tu_parent = framework::get( parent_id, TUT_ANY );
+ enabler.visit( tu_parent );
+ parent_id = tu_parent.p_parent_id;
+ }
}
// 40. Apply all disablers
@@ -705,6 +719,9 @@ public:
// 40. We are going to time the execution
boost::timer tu_timer;
+ // we pass the random generator
+ const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper();
+
if( tu.p_type == TUT_SUITE ) {
test_suite const& ts = static_cast<test_suite const&>( tu );
@@ -714,14 +731,14 @@ public:
BOOST_TEST_FOREACH( value_type, chld, ts.m_ranked_children ) {
unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
- result = (std::min)( result, execute_test_tree( chld.second, chld_timeout ) );
+ result = (std::min)( result, execute_test_tree( chld.second, chld_timeout, &rand_gen ) );
if( unit_test_monitor.is_critical_error( result ) )
break;
}
}
else {
- // Go through ranges of chldren with the same dependency rank and shuffle them
+ // Go through ranges of children with the same dependency rank and shuffle them
// independently. Execute each subtree in this order
test_unit_id_list children_with_the_same_rank;
@@ -737,8 +754,6 @@ public:
it++;
}
- const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper();
-
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
impl::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end(), rand_gen );
#else
@@ -895,6 +910,13 @@ struct sum_to_first_only {
};
void
+shutdown_loggers_and_reports()
+{
+ s_frk_state().m_log_sinks.clear();
+ s_frk_state().m_report_sink.setup( "stderr" );
+}
+
+void
setup_loggers()
{
@@ -913,8 +935,15 @@ setup_loggers()
unit_test_log.set_format( format );
runtime_config::stream_holder& stream_logger = s_frk_state().m_log_sinks[format];
- if( runtime_config::has( runtime_config::btrt_log_sink ) )
- stream_logger.setup( runtime_config::get<std::string>( runtime_config::btrt_log_sink ) );
+ if( runtime_config::has( runtime_config::btrt_log_sink ) ) {
+ // we remove all streams in this case, so we do not specify the format
+ boost::function< void () > log_cleaner = boost::bind( &unit_test_log_t::set_stream,
+ &unit_test_log,
+ boost::ref(std::cout)
+ );
+ stream_logger.setup( runtime_config::get<std::string>( runtime_config::btrt_log_sink ),
+ log_cleaner );
+ }
unit_test_log.set_stream( stream_logger.ref() );
}
else
@@ -1026,7 +1055,6 @@ setup_loggers()
}
}
-
BOOST_TEST_I_ASSRT( formatter_log_level != invalid_log_level,
boost::runtime::access_to_missing_argument()
<< "Unable to determine the log level from '"
@@ -1041,12 +1069,18 @@ setup_loggers()
unit_test_log.set_threshold_level( format, formatter_log_level );
runtime_config::stream_holder& stream_logger = s_frk_state().m_log_sinks[format];
+ boost::function< void () > log_cleaner = boost::bind( &unit_test_log_t::set_stream,
+ &unit_test_log,
+ format,
+ boost::ref(std::cout) );
if( ++current_format_specs != utils::string_token_iterator() &&
current_format_specs->size() ) {
- stream_logger.setup( *current_format_specs );
+ stream_logger.setup( *current_format_specs,
+ log_cleaner );
}
else {
- stream_logger.setup( formatter->get_default_stream_description() );
+ stream_logger.setup( formatter->get_default_stream_description(),
+ log_cleaner );
}
unit_test_log.set_stream( format, stream_logger.ref() );
}
@@ -1092,8 +1126,14 @@ init( init_unit_test_func init_func, int argc, char* argv[] )
results_reporter::set_level( runtime_config::get<report_level>( runtime_config::btrt_report_level ) );
results_reporter::set_format( runtime_config::get<output_format>( runtime_config::btrt_report_format ) );
- if( runtime_config::has( runtime_config::btrt_report_sink ) )
- s_frk_state().m_report_sink.setup( runtime_config::get<std::string>( runtime_config::btrt_report_sink ) );
+ if( runtime_config::has( runtime_config::btrt_report_sink ) ) {
+ boost::function< void () > report_cleaner = boost::bind( &results_reporter::set_stream,
+ boost::ref(std::cerr)
+ );
+ s_frk_state().m_report_sink.setup( runtime_config::get<std::string>( runtime_config::btrt_report_sink ),
+ report_cleaner );
+ }
+
results_reporter::set_stream( s_frk_state().m_report_sink.ref() );
// 40. Register default test observers
@@ -1173,6 +1213,7 @@ test_in_progress()
void
shutdown()
{
+ impl::shutdown_loggers_and_reports();
// eliminating some fake memory leak reports. See for more details:
// http://connect.microsoft.com/VisualStudio/feedback/details/106937/memory-leaks-reported-by-debug-crt-inside-typeinfo-name
@@ -1568,6 +1609,7 @@ run( test_unit_id id, bool continue_test )
break;
case 1:
seed = static_cast<unsigned>( std::rand() ^ std::time( 0 ) ); // better init using std::rand() ^ ...
+ BOOST_FALLTHROUGH;
default:
BOOST_TEST_FRAMEWORK_MESSAGE( "Test cases order is shuffled using seed: " << seed );
std::srand( seed );
@@ -1581,6 +1623,8 @@ run( test_unit_id id, bool continue_test )
impl::s_frk_state().m_test_in_progress = false;
+ results_reporter::make_report( INV_REPORT_LEVEL, id );
+
unit_test::framework_init_observer.clear();
if( call_start_finish ) {
// indicates the framework that no test is in progress anymore if observers need to be notified
diff --git a/boost/test/impl/junit_log_formatter.ipp b/boost/test/impl/junit_log_formatter.ipp
index 0ec8d43832..e82e2bd1b0 100644
--- a/boost/test/impl/junit_log_formatter.ipp
+++ b/boost/test/impl/junit_log_formatter.ipp
@@ -431,13 +431,13 @@ public:
if(m_display_build_info)
{
m_stream << "<properties>" << std::endl;
- m_stream << "<property name=\"platform\" value" << utils::attr_value() << BOOST_PLATFORM << std::endl;
- m_stream << "<property name=\"compiler\" value" << utils::attr_value() << BOOST_COMPILER << std::endl;
- m_stream << "<property name=\"stl\" value" << utils::attr_value() << BOOST_STDLIB << std::endl;
+ m_stream << "<property name=\"platform\" value" << utils::attr_value() << BOOST_PLATFORM << " />" << std::endl;
+ m_stream << "<property name=\"compiler\" value" << utils::attr_value() << BOOST_COMPILER << " />" << std::endl;
+ m_stream << "<property name=\"stl\" value" << utils::attr_value() << BOOST_STDLIB << " />" << std::endl;
std::ostringstream o;
o << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
- m_stream << "<property name=\"boost\" value" << utils::attr_value() << o.str() << std::endl;
+ m_stream << "<property name=\"boost\" value" << utils::attr_value() << o.str() << " />" << std::endl;
m_stream << "</properties>" << std::endl;
}
}
@@ -646,7 +646,7 @@ junit_log_formatter::log_entry_start( std::ostream& /*ostr*/, log_entry_data con
last_entry.skipping = true;
break;
}
- // no break on purpose
+ BOOST_FALLTHROUGH;
}
case unit_test_log_formatter::BOOST_UTL_ET_MESSAGE:
{
@@ -654,7 +654,7 @@ junit_log_formatter::log_entry_start( std::ostream& /*ostr*/, log_entry_data con
last_entry.skipping = true;
break;
}
- // no break on purpose
+ BOOST_FALLTHROUGH;
}
case unit_test_log_formatter::BOOST_UTL_ET_WARNING:
{
diff --git a/boost/test/impl/test_tools.ipp b/boost/test/impl/test_tools.ipp
index 7e01453313..2956879326 100644
--- a/boost/test/impl/test_tools.ipp
+++ b/boost/test/impl/test_tools.ipp
@@ -119,14 +119,6 @@ print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const*
ostr << ( t ? t : L"null string" );
}
-#if !defined(BOOST_NO_CXX11_NULLPTR)
-void
-print_log_value<std::nullptr_t>::operator()( std::ostream& ostr, std::nullptr_t )
-{
- ostr << "nullptr";
-}
-#endif
-
//____________________________________________________________________________//
// ************************************************************************** //
diff --git a/boost/test/impl/test_tree.ipp b/boost/test/impl/test_tree.ipp
index 81995bb29f..e0839e3dd1 100644
--- a/boost/test/impl/test_tree.ipp
+++ b/boost/test/impl/test_tree.ipp
@@ -223,7 +223,7 @@ test_case::test_case( const_string name, const_string file_name, std::size_t lin
//____________________________________________________________________________//
test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
-: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
+: test_unit( ut_detail::normalize_test_case_name( name ), file_name, line_num, static_cast<test_unit_type>(type) )
{
framework::register_test_unit( this );
}
@@ -241,6 +241,14 @@ test_suite::test_suite( const_string module_name )
void
test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
{
+ // check for clashing names #12597
+ for( test_unit_id_list::const_iterator it(m_children.begin()), ite(m_children.end());
+ it < ite;
+ ++it) {
+ BOOST_TEST_SETUP_ASSERT( tu->p_name != framework::get(*it, TUT_ANY).p_name,
+ "test unit with name '" + tu->p_name.value + std::string("' registered multiple times") );
+ }
+
tu->p_timeout.value = timeout;
m_children.push_back( tu->p_id );
@@ -380,9 +388,25 @@ normalize_test_case_name( const_string name )
if( name[0] == '&' )
norm_name = norm_name.substr( 1 );
-
- std::replace(norm_name.begin(), norm_name.end(), ' ', '_');
- std::replace(norm_name.begin(), norm_name.end(), ':', '_');
+
+ // trim spaces
+ std::size_t first_not_space = norm_name.find_first_not_of(' ');
+ if( first_not_space ) {
+ norm_name.erase(0, first_not_space);
+ }
+
+ std::size_t last_not_space = norm_name.find_last_not_of(' ');
+ if( last_not_space !=std::string::npos ) {
+ norm_name.erase(last_not_space + 1);
+ }
+
+ // sanitize all chars that might be used in runtime filters
+ static const char to_replace[] = { ':', '*', '@', '+', '!', '/' };
+ for(std::size_t index = 0;
+ index < sizeof(to_replace)/sizeof(to_replace[0]);
+ index++) {
+ std::replace(norm_name.begin(), norm_name.end(), to_replace[index], '_');
+ }
return norm_name;
}
diff --git a/boost/test/impl/unit_test_log.ipp b/boost/test/impl/unit_test_log.ipp
index 6ef7d930a2..2a6c0f4bc6 100644
--- a/boost/test/impl/unit_test_log.ipp
+++ b/boost/test/impl/unit_test_log.ipp
@@ -525,6 +525,17 @@ unit_test_log_t::set_stream( output_format log_format, std::ostream& str )
}
}
+std::ostream*
+unit_test_log_t::get_stream( output_format log_format ) const
+{
+ BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
+ if( current_logger_data.m_format == log_format) {
+ return current_logger_data.m_stream;
+ }
+ }
+ return 0;
+}
+
//____________________________________________________________________________//
void
diff --git a/boost/test/impl/unit_test_main.ipp b/boost/test/impl/unit_test_main.ipp
index dabe328c8c..1780c6b93b 100644
--- a/boost/test/impl/unit_test_main.ipp
+++ b/boost/test/impl/unit_test_main.ipp
@@ -230,8 +230,6 @@ unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
framework::run();
- results_reporter::make_report();
-
result_code = !runtime_config::get<bool>( runtime_config::btrt_result_code )
? boost::exit_success
: results_collector.results( framework::master_test_suite().p_id ).result_code();
diff --git a/boost/test/impl/unit_test_parameters.ipp b/boost/test/impl/unit_test_parameters.ipp
index b825c46d6a..428c10116f 100644
--- a/boost/test/impl/unit_test_parameters.ipp
+++ b/boost/test/impl/unit_test_parameters.ipp
@@ -43,7 +43,6 @@
#include <boost/config.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#include <boost/test/detail/enable_warnings.hpp>
-#include <boost/optional.hpp>
#include <boost/cstdlib.hpp>
// STL
@@ -112,7 +111,7 @@ register_parameters( rt::parameters_store& store )
rt::description = "Automatically attaches debugger in case of system level failure (signal).",
rt::env_var = "BOOST_TEST_AUTO_START_DBG",
- rt::help = "Option " + btrt_auto_start_dbg + " specifies whether Boost.Test should attempt "
+ rt::help = "Specifies whether Boost.Test should attempt "
"to attach a debugger when fatal system error occurs. At the moment this feature "
"is only available on a few selected platforms: Win32 and *nix. There is a "
"default debugger configured for these platforms. You can manually configure "
@@ -145,7 +144,7 @@ register_parameters( rt::parameters_store& store )
rt::option build_info( btrt_build_info, (
rt::description = "Displays library build information.",
rt::env_var = "BOOST_TEST_BUILD_INFO",
- rt::help = "Option " + btrt_build_info + " displays library build information, including: platform, "
+ rt::help = "Displays library build information, including: platform, "
"compiler, STL version and Boost version."
));
@@ -164,7 +163,7 @@ register_parameters( rt::parameters_store& store )
#else
true,
#endif
- rt::help = "If option " + btrt_catch_sys_errors + " has value no the frameworks does not attempt to catch "
+ rt::help = "If option " + btrt_catch_sys_errors + " has value 'no' the frameworks does not attempt to catch "
"asynchronous system failure events (signals on *NIX platforms or structured exceptions on Windows). "
" Default value is "
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
@@ -183,9 +182,9 @@ register_parameters( rt::parameters_store& store )
rt::option color_output( btrt_color_output, (
rt::description = "Enables color output of the framework log and report messages.",
rt::env_var = "BOOST_TEST_COLOR_OUTPUT",
- rt::help = "The framework is able to produce color output on systems which supports it. "
- "To enable this behavior set this option to yes. By default the framework "
- "does not produces color output."
+ rt::default_value = true,
+ rt::help = "Produces color output for logs, reports and help. "
+ "Defaults to true. "
));
color_output.add_cla_id( "--", btrt_color_output, "=", true );
@@ -197,7 +196,7 @@ register_parameters( rt::parameters_store& store )
rt::option detect_fp_except( btrt_detect_fp_except, (
rt::description = "Enables/disables floating point exceptions traps.",
rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS",
- rt::help = "Option " + btrt_detect_fp_except + " enables/disables hardware traps for the floating "
+ rt::help = "Enables/disables hardware traps for the floating "
"point exceptions (if supported on your platfrom)."
));
@@ -212,7 +211,7 @@ register_parameters( rt::parameters_store& store )
rt::default_value = 1L,
rt::optional_value = 1L,
rt::value_hint = "<alloc order number>",
- rt::help = "Parameter " + btrt_detect_mem_leaks + " enables/disables memory leaks detection. "
+ rt::help = "Enables/disables memory leaks detection. "
"This parameter has optional long integer value. The default value is 1, which "
"enables the memory leak detection. The value 0 disables memory leak detection. "
"Any value N greater than 1 is treated as leak allocation number and tells the "
@@ -242,9 +241,9 @@ register_parameters( rt::parameters_store& store )
( "DOT", OF_DOT )
,
#endif
- rt::help = "Parameter " + btrt_list_content + " instructs the framework to list the content "
- "of the test module instead of executing the test cases. Parameter accepts "
- "optional string value indicating the format of the output. Currently the "
+ rt::help = "Lists the test suites and cases "
+ "of the test module instead of executing the test cases. The format of the "
+ "desired output can be passed to the command. Currently the "
"framework supports two formats: human readable format (HRF) and dot graph "
"format (DOT). If value is omitted HRF value is assumed."
));
@@ -285,7 +284,7 @@ register_parameters( rt::parameters_store& store )
( "JUNIT", OF_JUNIT )
,
#endif
- rt::help = "Parameter " + btrt_log_format + " allows to set the frameowrk's log format to one "
+ rt::help = "Set the frameowrk's log format to one "
"of the formats supplied by the framework. The only acceptable values for this "
"parameter are the names of the output formats supplied by the framework. By "
"default the framework uses human readable format (HRF) for testing log. This "
@@ -300,7 +299,7 @@ register_parameters( rt::parameters_store& store )
///////////////////////////////////////////////
rt::enum_parameter<unit_test::log_level> log_level( btrt_log_level, (
- rt::description = "Specifies log level.",
+ rt::description = "Specifies the logging level of the test execution.",
rt::env_var = "BOOST_TEST_LOG_LEVEL",
rt::default_value = log_all_errors,
rt::enum_values<unit_test::log_level>::value =
@@ -333,8 +332,8 @@ register_parameters( rt::parameters_store& store )
( "nothing" , log_nothing )
,
#endif
- rt::help = "Parameter " + btrt_log_level + " allows to set the framework's log level. "
- "Log level defines the verbosity of testing log produced by a testing "
+ rt::help = "Set the framework's log level. "
+ "The log level defines the verbosity of the testing logs produced by a test "
"module. The verbosity ranges from a complete log, when all assertions "
"(both successful and failing) are reported, all notifications about "
"test units start and finish are included, to an empty log when nothing "
@@ -348,11 +347,11 @@ register_parameters( rt::parameters_store& store )
///////////////////////////////////////////////
rt::parameter<std::string> log_sink( btrt_log_sink, (
- rt::description = "Specifies log sink: stdout(default), stderr or file name.",
+ rt::description = "Specifies log sink: stdout (default), stderr or file name.",
rt::env_var = "BOOST_TEST_LOG_SINK",
rt::value_hint = "<stderr|stdout|file name>",
- rt::help = "Parameter " + btrt_log_sink + " allows to set the log sink - location "
- "where we report the log to, thus it allows to easily redirect the "
+ rt::help = "Sets the log sink - the location "
+ "where Boost.Test writes the logs of the test execution. it allows to easily redirect the "
"test logs to file or standard streams. By default testing log is "
"directed to standard output."
));
@@ -380,7 +379,7 @@ register_parameters( rt::parameters_store& store )
( "XML", OF_XML )
,
#endif
- rt::help = "Parameter " + btrt_output_format + " combines an effect of " + btrt_report_format +
+ rt::help = "Combines an effect of " + btrt_report_format +
" and " + btrt_log_format + " parameters. This parameter has higher priority "
"than either one of them. In other words if this parameter is specified "
"it overrides the value of other two parameters. This parameter does not "
@@ -398,9 +397,12 @@ register_parameters( rt::parameters_store& store )
rt::parameter<std::string,rt::REPEATABLE_PARAM> combined_logger( btrt_combined_logger, (
rt::description = "Specifies log level and sink for one or several log format",
rt::env_var = "BOOST_TEST_LOGGER",
- rt::value_hint = "log_format:log_level:log_sink",
- rt::help = "Parameter " + btrt_combined_logger + " allows to specify the logger type, level and sink\n"
- "in one command."
+ rt::value_hint = "log_format,log_level,log_sink[:log_format,log_level,log_sink]",
+ rt::help = "Specify one or more logging definition, which include the logger type, level and sink. "
+ "The log format, level and sink follow the same format as for the argument '--" + btrt_log_format +
+ "', '--" + btrt_log_level + "' and '--" + btrt_log_sink + "' respetively. "
+ "This command can take several logging definition separated by a ':', or be repeated "
+ "on the command line."
));
combined_logger.add_cla_id( "--", btrt_combined_logger, "=" );
@@ -415,14 +417,14 @@ register_parameters( rt::parameters_store& store )
rt::default_value = 0U,
rt::optional_value = 1U,
rt::value_hint = "<seed>",
- rt::help = "Parameter " + btrt_random_seed + " instructs the framework to execute the "
- "test cases in random order. This parameter accepts optional unsigned "
- "integer argument. By default test cases are executed in some specific "
- "order defined by order of test units in test files and dependency between "
- "test units. If parameter is specified without the argument value testing "
+ rt::help = "Instructs the framework to execute the "
+ "test cases in random order. This parameter accepts an optional unsigned "
+ "integer argument. If parameter is specified without the argument value testing "
"order is randomized based on current time. Alternatively you can specify "
"any positive value greater than 1 and it will be used as random seed for "
- "the run."
+ "the run. "
+ "By default, the test cases are executed in an "
+ "order defined by their declaration and the optional dependencies among the test units."
));
random_seed.add_cla_id( "--", btrt_random_seed, "=" );
@@ -431,7 +433,7 @@ register_parameters( rt::parameters_store& store )
///////////////////////////////////////////////
rt::enum_parameter<unit_test::output_format> report_format( btrt_report_format, (
- rt::description = "Specifies report format.",
+ rt::description = "Specifies the test report format.",
rt::env_var = "BOOST_TEST_REPORT_FORMAT",
rt::default_value = OF_CLF,
rt::enum_values<unit_test::output_format>::value =
@@ -448,7 +450,7 @@ register_parameters( rt::parameters_store& store )
( "XML", OF_XML )
,
#endif
- rt::help = "Parameter " + btrt_report_format + " allows to set the framework's report format "
+ rt::help = "Set the framework's report format "
"to one of the formats supplied by the framework. The only acceptable values "
"for this parameter are the names of the output formats. By default the framework "
"uses human readable format (HRF) for results reporting. Alternatively you can "
@@ -463,7 +465,7 @@ register_parameters( rt::parameters_store& store )
///////////////////////////////////////////////
rt::enum_parameter<unit_test::report_level> report_level( btrt_report_level, (
- rt::description = "Specifies report level.",
+ rt::description = "Specifies test report level.",
rt::env_var = "BOOST_TEST_REPORT_LEVEL",
rt::default_value = CONFIRMATION_REPORT,
rt::enum_values<unit_test::report_level>::value =
@@ -482,9 +484,9 @@ register_parameters( rt::parameters_store& store )
( "no", NO_REPORT )
,
#endif
- rt::help = "Parameter " + btrt_report_level + " allows to set the verbosity level of the "
- "testing result report generated by the framework. Use value 'no' to "
- "eliminate the results report completely."
+ rt::help = "Set the verbosity level of the "
+ "result report generated by the testing framework. Use value 'no' to "
+ "disable the results report completely."
));
report_level.add_cla_id( "--", btrt_report_level, "=" );
@@ -512,10 +514,10 @@ register_parameters( rt::parameters_store& store )
rt::description = "Specifies report sink: stderr(default), stdout or file name.",
rt::env_var = "BOOST_TEST_REPORT_SINK",
rt::value_hint = "<stderr|stdout|file name>",
- rt::help = "Parameter " + btrt_report_sink + " allows to set the result report sink - "
- "the location where the framework writes the result report to, thus it "
- "allows to easily redirect the result report to a file or a standard "
- "stream. By default the testing result report is directed to the "
+ rt::help = "Sets the result report sink - "
+ "the location where the framework writes the result report to. "
+ "The sink may be a a file or a standard "
+ "stream. The default is 'stderr': the "
"standard error stream."
));
@@ -541,13 +543,13 @@ register_parameters( rt::parameters_store& store )
///////////////////////////////////////////////
rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( btrt_run_filters, (
- rt::description = "Filters, which test units to include or exclude from test module execution.",
+ rt::description = "Filters which tests to execute.",
rt::env_var = "BOOST_TEST_RUN_FILTERS",
rt::value_hint = "<test unit filter>",
- rt::help = "Parameter " + btrt_run_filters + " allows to filter which test units to execute during "
- "testing. The framework supports both 'selection filters', which allow to select "
+ rt::help = "Filters which test units to execute. "
+ "The framework supports both 'selection filters', which allow to select "
"which test units to enable from the set of available test units, and 'disabler "
- "filters', which allow to disable some test units. The __UTF__ also supports "
+ "filters', which allow to disable some test units. Boost.test also supports "
"enabling/disabling test units at compile time. These settings identify the default "
"set of test units to run. Parameter " + btrt_run_filters + " is used to change this default. "
"This parameter is repeatable, so you can specify more than one filter if necessary."
@@ -576,8 +578,8 @@ register_parameters( rt::parameters_store& store )
rt::option show_progress( btrt_show_progress, (
rt::description = "Turns on progress display.",
rt::env_var = "BOOST_TEST_SHOW_PROGRESS",
- rt::help = "Parameter " + btrt_show_progress + " instructs the framework to display test progress "
- "information. By default the test progress is not shown."
+ rt::help = "Instructs the framework to display the progress of the tests. "
+ "This feature is turned off by default."
));
show_progress.add_cla_id( "--", btrt_show_progress, "=" );
@@ -590,9 +592,9 @@ register_parameters( rt::parameters_store& store )
rt::description = "Turns on/off usage of an alternative stack for signal handling.",
rt::env_var = "BOOST_TEST_USE_ALT_STACK",
rt::default_value = true,
- rt::help = "Parameter " + btrt_use_alt_stack + " instructs the framework to use alternative "
- "stack for signals processing, on platforms where they are supported. The feature "
- "is enabled by default, but can be disabled using this parameter."
+ rt::help = "Instructs the framework to use an alternative "
+ "stack for operating system's signals handling (on platforms where this is supported). "
+ "The feature is enabled by default, but can be disabled using this command line switch."
));
use_alt_stack.add_cla_id( "--", btrt_use_alt_stack, "=", true );
@@ -603,9 +605,9 @@ register_parameters( rt::parameters_store& store )
rt::option wait_for_debugger( btrt_wait_for_debugger, (
rt::description = "Forces test module to wait for button to be pressed before starting test run.",
rt::env_var = "BOOST_TEST_WAIT_FOR_DEBUGGER",
- rt::help = "Parameter " + btrt_wait_for_debugger + " instructs the framework to pause before starting "
- "test units execution, so that you can attach a debugger to running test module. By "
- "default this parameters turned off."
+ rt::help = "Instructs the framework to pause before starting "
+ "test units execution, so that you can attach a debugger to the test module process. "
+ "This feature is turned off by default."
));
wait_for_debugger.add_cla_id( "--", btrt_wait_for_debugger, "=" );
@@ -618,10 +620,10 @@ register_parameters( rt::parameters_store& store )
rt::description = "Help for framework parameters.",
rt::optional_value = std::string(),
rt::value_hint = "<parameter name>",
- rt::help = "Parameter " + btrt_help + " displays help on the framework's parameters. "
+ rt::help = "Displays help on the framework's parameters. "
"The parameter accepts an optional argument value. If present, an argument value is "
"interpreted as a parameter name (name guessing works as well, so for example "
- "--help=rand displays help on the parameter random). If the parameter name is unknown "
+ "'--help=rand' displays help on the parameter 'random'). If the parameter name is unknown "
"or ambiguous error is reported. If argument value is absent, a summary of all "
"framework's parameter is displayed."
));
@@ -675,17 +677,26 @@ init( int& argc, char** argv )
// Set arguments to default values if defined and perform all the validations
rt::finalize_arguments( s_parameters_store, s_arguments_store );
+ // check if colorized output is enabled
+ bool use_color = true;
+ if( s_arguments_store.has(btrt_color_output ) ) {
+ use_color = runtime_config::get<bool>(runtime_config::btrt_color_output);
+ }
+
// Report help if requested
if( runtime_config::get<bool>( btrt_version ) ) {
parser->version( std::cerr );
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
}
else if( runtime_config::get<bool>( btrt_usage ) ) {
- parser->usage( std::cerr );
+ parser->usage( std::cerr, runtime::cstring(), use_color );
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
}
else if( s_arguments_store.has( btrt_help ) ) {
- parser->help( std::cerr, s_parameters_store, runtime_config::get<std::string>( btrt_help ) );
+ parser->help(std::cerr,
+ s_parameters_store,
+ runtime_config::get<std::string>( btrt_help ),
+ use_color );
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
}
diff --git a/boost/test/parameterized_test.hpp b/boost/test/parameterized_test.hpp
index b94e7ec8b3..cc9487abc2 100644
--- a/boost/test/parameterized_test.hpp
+++ b/boost/test/parameterized_test.hpp
@@ -14,6 +14,7 @@
// Boost.Test
#include <boost/test/unit_test_suite.hpp>
+#include <boost/test/utils/string_cast.hpp>
// Boost
#include <boost/type_traits/remove_reference.hpp>
@@ -65,6 +66,7 @@ public:
, m_tc_line( tc_line )
, m_par_begin( par_begin )
, m_par_end( par_end )
+ , m_index( 0 )
{}
virtual test_unit* next() const
@@ -72,9 +74,10 @@ public:
if( m_par_begin == m_par_end )
return (test_unit*)0;
- test_unit* res = new test_case( m_tc_name, m_tc_file, m_tc_line, boost::bind( m_test_func, *m_par_begin ) );
+ test_unit* res = new test_case( m_tc_name + "_" + utils::string_cast(m_index), m_tc_file, m_tc_line, boost::bind( m_test_func, *m_par_begin ) );
++m_par_begin;
+ ++m_index;
return res;
}
@@ -87,6 +90,7 @@ private:
std::size_t m_tc_line;
mutable ParamIter m_par_begin;
ParamIter m_par_end;
+ mutable std::size_t m_index;
};
//____________________________________________________________________________//
diff --git a/boost/test/tools/detail/print_helper.hpp b/boost/test/tools/detail/print_helper.hpp
index 1e4dd6e3c0..2c6a3b5e80 100644
--- a/boost/test/tools/detail/print_helper.hpp
+++ b/boost/test/tools/detail/print_helper.hpp
@@ -166,8 +166,11 @@ struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
#if !defined(BOOST_NO_CXX11_NULLPTR)
template<>
-struct BOOST_TEST_DECL print_log_value<std::nullptr_t> {
- void operator()( std::ostream& ostr, std::nullptr_t t );
+struct print_log_value<std::nullptr_t> {
+ // declaration and definition is here because of #12969 https://svn.boost.org/trac10/ticket/12969
+ void operator()( std::ostream& ostr, std::nullptr_t /*t*/ ) {
+ ostr << "nullptr";
+ }
};
#endif
diff --git a/boost/test/tree/test_case_template.hpp b/boost/test/tree/test_case_template.hpp
index 6a1fc3e57b..83a13f00f5 100644
--- a/boost/test/tree/test_case_template.hpp
+++ b/boost/test/tree/test_case_template.hpp
@@ -41,6 +41,12 @@
#include <string> // for std::string
#include <list> // for std::list
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
+ !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ #include <tuple>
+#endif
+
#include <boost/test/detail/suppress_warnings.hpp>
@@ -64,7 +70,7 @@ public:
// ************** generate_test_case_4_type ************** //
// ************************************************************************** //
-template<typename Generator,typename TestCaseTemplate>
+template<typename Generator, typename TestCaseTemplate>
struct generate_test_case_4_type {
explicit generate_test_case_4_type( const_string tc_name, const_string tc_file, std::size_t tc_line, Generator& G )
: m_test_case_name( tc_name )
@@ -106,17 +112,8 @@ private:
// ************** test_case_template ************** //
// ************************************************************************** //
-template<typename TestCaseTemplate,typename TestTypesList>
-class template_test_case_gen : public test_unit_generator {
+class template_test_case_gen_base : public test_unit_generator {
public:
- // Constructor
- template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
- {
- typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
-
- mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
- }
-
virtual test_unit* next() const
{
if( m_test_cases.empty() )
@@ -132,6 +129,58 @@ public:
mutable std::list<test_unit*> m_test_cases;
};
+template<typename TestCaseTemplate,typename TestTypesList>
+class template_test_case_gen : public template_test_case_gen_base {
+public:
+ // Constructor
+ template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
+ {
+ typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
+
+ mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
+ }
+};
+
+// adding support for tuple
+#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
+ !defined(BOOST_NO_CXX11_HDR_TUPLE) && \
+ !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+
+template<typename TestCaseTemplate, typename... tuple_parameter_pack>
+class template_test_case_gen<TestCaseTemplate, std::tuple<tuple_parameter_pack...> > : public template_test_case_gen_base {
+
+ template<int... Is>
+ struct seq { };
+
+ template<int N, int... Is>
+ struct gen_seq : gen_seq<N - 1, N - 1, Is...> { };
+
+ template<int... Is>
+ struct gen_seq<0, Is...> : seq<Is...> { };
+
+ template<typename tuple_t, typename F, int... Is>
+ void for_each(F &f, seq<Is...>)
+ {
+ auto l = { (f(mpl::identity<typename std::tuple_element<Is, tuple_t>::type>()), 0)... };
+ (void)l; // silence warning
+ }
+
+public:
+ // Constructor
+ template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
+ {
+ using tuple_t = std::tuple<tuple_parameter_pack...>;
+ using this_type = template_test_case_gen<TestCaseTemplate, tuple_t >;
+ using single_test_gen = generate_test_case_4_type<this_type, TestCaseTemplate>;
+
+ single_test_gen op( tc_name, tc_file, tc_line, *this );
+
+ this->for_each<tuple_t>(op, gen_seq<sizeof...(tuple_parameter_pack)>());
+ }
+};
+
+#endif /* C++11 variadic and tuples */
+
} // namespace ut_detail
} // unit_test
} // namespace boost
diff --git a/boost/test/unit_test_log.hpp b/boost/test/unit_test_log.hpp
index 4e6a97b3c2..6944ffa79a 100644
--- a/boost/test/unit_test_log.hpp
+++ b/boost/test/unit_test_log.hpp
@@ -137,6 +137,13 @@ public:
//! @par Since Boost 1.62
void set_stream( output_format, std::ostream& );
+ //! Returns a pointer to the stream associated to specific logger
+ //!
+ //! @note Returns a null pointer if the format is not found
+ //! @par Since Boost 1.67
+ std::ostream* get_stream( output_format ) const;
+
+
//! Sets the threshold level for all loggers/formatters.
//!
//! This will override the log level of all loggers, whether enabled or not.
diff --git a/boost/test/unit_test_parameters.hpp b/boost/test/unit_test_parameters.hpp
index 0b77f37197..e01bbd7aed 100644
--- a/boost/test/unit_test_parameters.hpp
+++ b/boost/test/unit_test_parameters.hpp
@@ -19,6 +19,9 @@
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/make_shared.hpp>
+// Boost
+#include <boost/function/function0.hpp>
+
// STL
#include <iostream>
#include <fstream>
@@ -96,24 +99,29 @@ BOOST_TEST_DECL bool save_pattern();
class stream_holder {
public:
// Constructor
- explicit stream_holder( std::ostream& default_stream = std::cout)
+ explicit stream_holder( std::ostream& default_stream = std::cout )
: m_stream( &default_stream )
{
}
- void setup( const const_string& stream_name )
+ void setup( const const_string& stream_name,
+ boost::function<void ()> const &cleaner_callback = boost::function<void ()>() )
{
if(stream_name.empty())
return;
- if( stream_name == "stderr" )
+ if( stream_name == "stderr" ) {
m_stream = &std::cerr;
- else if( stream_name == "stdout" )
+ m_cleaner.reset();
+ }
+ else if( stream_name == "stdout" ) {
m_stream = &std::cout;
+ m_cleaner.reset();
+ }
else {
- m_file = boost::make_shared<std::ofstream>();
- m_file->open( std::string(stream_name.begin(), stream_name.end()).c_str() );
- m_stream = m_file.get();
+ m_cleaner = boost::make_shared<callback_cleaner>(cleaner_callback);
+ m_cleaner->m_file.open( std::string(stream_name.begin(), stream_name.end()).c_str() );
+ m_stream = &m_cleaner->m_file;
}
}
@@ -121,9 +129,22 @@ public:
std::ostream& ref() const { return *m_stream; }
private:
+ struct callback_cleaner {
+ callback_cleaner(boost::function<void ()> cleaner_callback)
+ : m_cleaner_callback(cleaner_callback)
+ , m_file() {
+ }
+ ~callback_cleaner() {
+ if( m_cleaner_callback )
+ m_cleaner_callback();
+ }
+ boost::function<void ()> m_cleaner_callback;
+ std::ofstream m_file;
+ };
+
// Data members
- boost::shared_ptr<std::ofstream> m_file;
- std::ostream* m_stream;
+ boost::shared_ptr<callback_cleaner> m_cleaner;
+ std::ostream* m_stream;
};
} // namespace runtime_config
diff --git a/boost/test/utils/basic_cstring/basic_cstring.hpp b/boost/test/utils/basic_cstring/basic_cstring.hpp
index fdd87d5211..cec0214b73 100644
--- a/boost/test/utils/basic_cstring/basic_cstring.hpp
+++ b/boost/test/utils/basic_cstring/basic_cstring.hpp
@@ -60,8 +60,8 @@ public:
// !! should also present reverse_iterator, const_reverse_iterator
-#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
- enum npos_type { npos = static_cast<size_type>(-1) };
+#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) && !defined(__DCC__)
+ BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
#else
// IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
// But size_type is 8 bytes in 64bit mode.
diff --git a/boost/test/utils/is_forward_iterable.hpp b/boost/test/utils/is_forward_iterable.hpp
index e8f5d39467..1c9108054b 100644
--- a/boost/test/utils/is_forward_iterable.hpp
+++ b/boost/test/utils/is_forward_iterable.hpp
@@ -16,7 +16,7 @@
defined(BOOST_NO_CXX11_NULLPTR) || \
defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
- // some issues with boost.config
+ // this feature works with VC2012 upd 5 while BOOST_NO_CXX11_TRAILING_RESULT_TYPES is defined
#if !defined(BOOST_MSVC) || BOOST_MSVC_FULL_VER < 170061030 /* VC2012 upd 5 */
#define BOOST_TEST_FWD_ITERABLE_CXX03
#endif
@@ -35,8 +35,8 @@
#else
// Boost
+#include <boost/static_assert.hpp>
#include <boost/utility/declval.hpp>
-#include <boost/range.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
@@ -122,8 +122,6 @@ private:
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
-
-
};
//____________________________________________________________________________//
@@ -196,14 +194,27 @@ struct is_container_forward_iterable {
#endif /* defined(BOOST_TEST_FWD_ITERABLE_CXX03) */
+
+//! Helper structure for accessing the content of a container or an array
template <typename T, bool is_forward_iterable = is_forward_iterable<T>::value >
struct bt_iterator_traits;
template <typename T>
struct bt_iterator_traits< T, true >{
- BOOST_STATIC_ASSERT((is_forward_iterable<T>::value)); //, "only for forward iterable types");
+ BOOST_STATIC_ASSERT((is_forward_iterable<T>::value));
+
+#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
+ (defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061030))
typedef typename T::const_iterator const_iterator;
- typedef typename T::value_type value_type;
+ typedef typename std::iterator_traits<const_iterator>::value_type value_type;
+#else
+ typedef decltype(boost::declval<
+ typename boost::add_const<
+ typename boost::remove_reference<T>::type
+ >::type>().begin()) const_iterator;
+
+ typedef typename std::iterator_traits<const_iterator>::value_type value_type;
+#endif /* BOOST_TEST_FWD_ITERABLE_CXX03 */
static const_iterator begin(T const& container) {
return container.begin();
@@ -211,9 +222,26 @@ struct bt_iterator_traits< T, true >{
static const_iterator end(T const& container) {
return container.end();
}
- static std::size_t size(T const& container) {
+
+#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
+ (defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061030))
+ static std::size_t
+ size(T const& container) {
return container.size();
}
+#else
+ static std::size_t
+ size(T const& container) {
+ return size(container,
+ std::integral_constant<bool, ut_detail::has_member_size<T>::value>());
+ }
+private:
+ static std::size_t
+ size(T const& container, std::true_type) { return container.size(); }
+
+ static std::size_t
+ size(T const& container, std::false_type) { return std::distance(begin(container), end(container)); }
+#endif /* BOOST_TEST_FWD_ITERABLE_CXX03 */
};
template <typename T, std::size_t N>
diff --git a/boost/test/utils/named_params.hpp b/boost/test/utils/named_params.hpp
index 88b8a883fe..50de5bfba0 100644
--- a/boost/test/utils/named_params.hpp
+++ b/boost/test/utils/named_params.hpp
@@ -72,7 +72,7 @@ struct is_named_param_pack<named_parameter_combine<NP,Rest> > : public mpl::true
// ************** param_type ************** //
// ************************************************************************** //
-/// param_type<Params,Keyword,Default>::type is is the type of the parameter
+/// param_type<Params,Keyword,Default>::type is the type of the parameter
/// corresponding to the Keyword (if parameter is present) or Default
template<typename NP, typename Keyword, typename DefaultType=void>
@@ -91,7 +91,7 @@ struct param_type<named_parameter_combine<NP,Rest>,Keyword,DefaultType>
// ************** has_param ************** //
// ************************************************************************** //
-/// has_param<Params,Keyword>::value is true id Params has parameter corresponding
+/// has_param<Params,Keyword>::value is true if Params has parameter corresponding
/// to the Keyword
template<typename NP, typename Keyword>
diff --git a/boost/test/utils/runtime/cla/parser.hpp b/boost/test/utils/runtime/cla/parser.hpp
index 9fe8e1bbd9..a57091b474 100644
--- a/boost/test/utils/runtime/cla/parser.hpp
+++ b/boost/test/utils/runtime/cla/parser.hpp
@@ -287,57 +287,119 @@ public:
}
void
- usage( std::ostream& ostr, cstring param_name = cstring() )
+ usage(std::ostream& ostr,
+ cstring param_name = cstring(),
+ bool use_color = true)
{
+ namespace utils = unit_test::utils;
+ namespace ut_detail = unit_test::ut_detail;
+
if( !param_name.is_empty() ) {
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
param->usage( ostr, m_negation_prefix );
}
else {
- ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
- if( !m_end_of_param_indicator.empty() )
- ostr << m_end_of_param_indicator << " [custom test module argument]...";
- ostr << "\n";
+ ostr << "\n The program '" << m_program_name << "' is a Boost.test module containing unit tests.";
+
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
+ ostr << "\n\n Usage\n ";
+ }
+
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
+ ostr << m_program_name << " [Boost.Test argument]... ";
+ }
+ if( !m_end_of_param_indicator.empty() ) {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
+ ostr << '[' << m_end_of_param_indicator << " [custom test module argument]...]";
+ }
}
- ostr << "\nFor detailed help on Boost.Test parameters use:\n"
- << " " << m_program_name << " --help\n"
- << "or\n"
- << " " << m_program_name << " --help=<parameter name>\n";
+ ostr << "\n\n Use\n ";
+ {
+
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
+ ostr << m_program_name << " --help";
+ }
+ ostr << "\n or ";
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
+ ostr << m_program_name << " --help=<parameter name>";
+ }
+ ostr << "\n for detailed help on Boost.Test parameters.\n";
}
void
- help( std::ostream& ostr, parameters_store const& parameters, cstring param_name )
+ help(std::ostream& ostr,
+ parameters_store const& parameters,
+ cstring param_name,
+ bool use_color = true)
{
+ namespace utils = unit_test::utils;
+ namespace ut_detail = unit_test::ut_detail;
+
if( !param_name.is_empty() ) {
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
- param->help( ostr, m_negation_prefix );
+ param->help( ostr, m_negation_prefix, use_color);
return;
}
- ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
- if( !m_end_of_param_indicator.empty() )
- ostr << m_end_of_param_indicator << " [custom test module argument]...";
+ usage(ostr, cstring(), use_color);
+
+ ostr << "\n\n";
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
+ ostr << " Command line flags:\n";
+ }
+ runtime::commandline_pretty_print(
+ ostr,
+ " ",
+ "The command line flags of Boost.Test are listed below. "
+ "All parameters are optional. You can specify parameter value either "
+ "as a command line argument or as a value of its corresponding environment "
+ "variable. If a flag is specified as a command line argument and an environment variable "
+ "at the same time, the command line takes precedence. "
+ "The command line argument "
+ "support name guessing, and works with shorter names as long as those are not ambiguous."
+ );
+
+ if( !m_end_of_param_indicator.empty() ) {
+ ostr << "\n\n All the arguments after the '";
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
+ ostr << m_end_of_param_indicator;
+ }
+ ostr << "' are ignored by Boost.Test.";
+ }
+
- ostr << "\n\nBoost.Test arguments correspond to parameters listed below. "
- "All parameters are optional. You can use specify parameter value either "
- "as a command line argument or as a value of corresponding environment "
- "variable. In case if argument for the same parameter is specified in both "
- "places, command line is taking precedence. Command line argument format "
- "supports parameter name guessing, so you can use any unambiguous "
- "prefix to identify a parameter.";
- if( !m_end_of_param_indicator.empty() )
- ostr << " All the arguments after the " << m_end_of_param_indicator << " are ignored by the Boost.Test.";
+ {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
+ ostr << "\n\n Environment variables:\n";
+ }
+ runtime::commandline_pretty_print(
+ ostr,
+ " ",
+ "Every argument listed below may also be set by a corresponding environment"
+ "variable. For an argument '--argument_x=<value>', the corresponding "
+ "environment variable is 'BOOST_TEST_ARGUMENT_X=value"
+ );
- ostr << "\n\nBoost.Test supports following parameters:\n";
- BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
- basic_param_ptr param = v.second;
- param->usage( ostr, m_negation_prefix );
+ ostr << "\n\n The following parameters are supported:\n";
+
+ BOOST_TEST_FOREACH(
+ parameters_store::storage_type::value_type const&,
+ v,
+ parameters.all() )
+ {
+ basic_param_ptr param = v.second;
+ ostr << "\n";
+ param->usage( ostr, m_negation_prefix, use_color);
}
- ostr << "\nUse --help=<parameter name> to display detailed help for specific parameter.\n";
}
private:
diff --git a/boost/test/utils/runtime/errors.hpp b/boost/test/utils/runtime/errors.hpp
index 37f8d9371b..5b263d21c5 100644
--- a/boost/test/utils/runtime/errors.hpp
+++ b/boost/test/utils/runtime/errors.hpp
@@ -86,7 +86,7 @@ public:
{
this->msg.append( val );
- return reinterpret_cast<Derived&&>(*this);
+ return static_cast<Derived&&>(*this);
}
//____________________________________________________________________________//
@@ -96,7 +96,7 @@ public:
{
this->msg.append( unit_test::utils::string_cast( val ) );
- return reinterpret_cast<Derived&&>(*this);
+ return static_cast<Derived&&>(*this);
}
//____________________________________________________________________________//
diff --git a/boost/test/utils/runtime/parameter.hpp b/boost/test/utils/runtime/parameter.hpp
index f11ce9813c..420b60264d 100644
--- a/boost/test/utils/runtime/parameter.hpp
+++ b/boost/test/utils/runtime/parameter.hpp
@@ -24,6 +24,7 @@
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/foreach.hpp>
+#include <boost/test/utils/setcolor.hpp>
// Boost
#include <boost/function/function2.hpp>
@@ -37,6 +38,40 @@
namespace boost {
namespace runtime {
+inline
+std::ostream& commandline_pretty_print(
+ std::ostream& ostr,
+ std::string const& prefix,
+ std::string const& to_print) {
+
+ const int split_at = 80;
+
+ std::string::size_type current = 0;
+
+ while(current < to_print.size()) {
+
+ // discards spaces at the beginning
+ std::string::size_type startpos = to_print.find_first_not_of(" \t\n", current);
+ current += startpos - current;
+
+ bool has_more_lines = (current + split_at) < to_print.size();
+
+ if(has_more_lines) {
+ std::string::size_type endpos = to_print.find_last_of(" \t\n", current + split_at);
+ std::string sub(to_print.substr(current, endpos - current));
+ ostr << prefix << sub;
+ ostr << "\n";
+ current += endpos - current;
+ }
+ else
+ {
+ ostr << prefix << to_print.substr(current, split_at);
+ current += split_at;
+ }
+ }
+ return ostr;
+}
+
// ************************************************************************** //
// ************** runtime::parameter_cla_id ************** //
// ************************************************************************** //
@@ -142,23 +177,37 @@ public:
virtual void produce_default( arguments_store& store ) const = 0;
/// interfaces for help message reporting
- virtual void usage( std::ostream& ostr, cstring negation_prefix_ )
+ virtual void usage( std::ostream& ostr, cstring negation_prefix_, bool use_color = true )
{
- ostr << "Parameter: " << p_name << '\n';
- if( !p_description.empty() )
- ostr << ' ' << p_description << '\n';
+ namespace utils = unit_test::utils;
+ namespace ut_detail = unit_test::ut_detail;
+
+ //
+ ostr << " ";
+ {
+
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
+ ostr << p_name;
+ }
+
+ ostr << '\n';
+
+ if( !p_description.empty() ) {
+ commandline_pretty_print(ostr, " ", p_description) << '\n';
+ }
- ostr << " Command line formats:\n";
BOOST_TEST_FOREACH( parameter_cla_id const&, id, cla_ids() ) {
if( id.m_prefix == help_prefix )
continue;
- ostr << " " << id.m_prefix;
+ ostr << " " << id.m_prefix;
+
if( id.m_negatable )
- cla_name_help( ostr, id.m_tag, negation_prefix_ );
+ cla_name_help( ostr, id.m_tag, negation_prefix_, use_color );
else
- cla_name_help( ostr, id.m_tag, "" );
+ cla_name_help( ostr, id.m_tag, "", use_color );
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
bool optional_value_ = false;
if( p_has_optional_value ) {
@@ -166,6 +215,7 @@ public:
ostr << '[';
}
+
if( id.m_value_separator.empty() )
ostr << ' ';
else {
@@ -179,16 +229,16 @@ public:
ostr << '\n';
}
- if( !p_env_var.empty() )
- ostr << " Environment variable: " << p_env_var << '\n';
}
- virtual void help( std::ostream& ostr, cstring negation_prefix_ )
+ virtual void help( std::ostream& ostr, cstring negation_prefix_, bool use_color = true )
{
- usage( ostr, negation_prefix_ );
+ usage( ostr, negation_prefix_, use_color );
- if( !p_help.empty() )
- ostr << '\n' << p_help << '\n';
+ if( !p_help.empty() ) {
+ ostr << '\n';
+ commandline_pretty_print(ostr, " ", p_help);
+ }
}
protected:
@@ -220,7 +270,7 @@ protected:
private:
/// interface for usage/help customization
- virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /* negation_prefix_ */) const
+ virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /*negation_prefix_*/, bool /*use_color*/ = true) const
{
ostr << cla_tag;
}
@@ -337,12 +387,16 @@ private:
{
m_arg_factory.produce_default( p_name, store );
}
- virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring negation_prefix_ ) const
+ virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring negation_prefix_, bool use_color = true ) const
{
- if( negation_prefix_.is_empty() )
- ostr << cla_tag;
- else
- ostr << '[' << negation_prefix_ << ']' << cla_tag;
+ namespace utils = unit_test::utils;
+ namespace ut_detail = unit_test::ut_detail;
+
+ if( !negation_prefix_.is_empty() ) {
+ BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
+ ostr << '[' << negation_prefix_ << ']';
+ }
+ ostr << cla_tag;
}
virtual void value_help( std::ostream& ostr ) const
{
diff --git a/boost/test/utils/setcolor.hpp b/boost/test/utils/setcolor.hpp
index c70209038a..91b068ae6f 100644
--- a/boost/test/utils/setcolor.hpp
+++ b/boost/test/utils/setcolor.hpp
@@ -24,6 +24,15 @@
#include <boost/test/detail/suppress_warnings.hpp>
+#ifdef _WIN32
+ #include <windows.h>
+
+ #if defined(__MINGW32__) && !defined(COMMON_LVB_UNDERSCORE)
+ // mingw badly mimicking windows.h
+ #define COMMON_LVB_UNDERSCORE 0x8000
+ #endif
+#endif
+
//____________________________________________________________________________//
namespace boost {
@@ -64,6 +73,7 @@ struct term_color { enum _ {
// ************** setcolor ************** //
// ************************************************************************** //
+#ifndef _WIN32
class setcolor {
public:
// Constructor
@@ -77,7 +87,10 @@ public:
friend std::ostream&
operator<<( std::ostream& os, setcolor const& sc )
{
- return os.write( sc.m_control_command, sc.m_command_size );
+ if (&os == &std::cout || &os == &std::cerr) {
+ return os.write( sc.m_control_command, sc.m_command_size );
+ }
+ return os;
}
private:
@@ -86,10 +99,151 @@ private:
int m_command_size;
};
+#else
+
+class setcolor {
+
+protected:
+ void set_console_color(std::ostream& os, WORD *attributes = NULL) const {
+ DWORD console_type;
+ if (&os == &std::cout) {
+ console_type = STD_OUTPUT_HANDLE;
+ }
+ else if (&os == &std::cerr) {
+ console_type = STD_ERROR_HANDLE;
+ }
+ else {
+ return;
+ }
+ HANDLE hConsole = GetStdHandle(console_type);
+
+ if(hConsole == INVALID_HANDLE_VALUE || hConsole == NULL )
+ return;
+
+ if(attributes != NULL) {
+ SetConsoleTextAttribute(hConsole, *attributes);
+ return;
+ }
+
+ CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
+ GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
+ //if(!has_written_console_ext) {
+ saved_attributes = consoleInfo.wAttributes;
+ //}
+
+ WORD fg_attr = 0;
+ switch(m_fg)
+ {
+ case term_color::WHITE:
+ fg_attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
+ break;
+ case term_color::BLACK:
+ fg_attr = 0;
+ break;
+ case term_color::RED:
+ fg_attr = FOREGROUND_RED;
+ break;
+ case term_color::GREEN:
+ fg_attr = FOREGROUND_GREEN;
+ break;
+ case term_color::CYAN:
+ fg_attr = FOREGROUND_GREEN | FOREGROUND_BLUE;
+ break;
+ case term_color::MAGENTA:
+ fg_attr = FOREGROUND_RED | FOREGROUND_BLUE;
+ break;
+ case term_color::BLUE:
+ fg_attr = FOREGROUND_BLUE;
+ break;
+ case term_color::YELLOW:
+ fg_attr = FOREGROUND_RED | FOREGROUND_GREEN;
+ break;
+ case term_color::ORIGINAL:
+ default:
+ fg_attr = saved_attributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
+ break;
+ }
+
+ WORD bg_attr = 0;
+ switch(m_bg)
+ {
+ case term_color::BLACK:
+ bg_attr = 0;
+ break;
+ case term_color::WHITE:
+ bg_attr = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
+ break;
+ case term_color::RED:
+ bg_attr = BACKGROUND_RED;
+ break;
+ case term_color::GREEN:
+ bg_attr = BACKGROUND_GREEN;
+ break;
+ case term_color::BLUE:
+ bg_attr = BACKGROUND_BLUE;
+ break;
+ case term_color::ORIGINAL:
+ default:
+ bg_attr = saved_attributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
+ break;
+ }
+
+ WORD text_attr = 0;
+ switch(m_attr)
+ {
+ case term_attr::BRIGHT:
+ text_attr = FOREGROUND_INTENSITY;
+ break;
+ case term_attr::UNDERLINE:
+ text_attr = COMMON_LVB_UNDERSCORE;
+ break;
+ default:
+ break;
+ }
+
+ SetConsoleTextAttribute(hConsole, fg_attr | bg_attr | text_attr);
+
+ //has_written_console_ext = true;
+ return;
+ }
+
+public:
+ // Constructor
+ explicit setcolor(
+ term_attr::_ attr = term_attr::NORMAL,
+ term_color::_ fg = term_color::ORIGINAL,
+ term_color::_ bg = term_color::ORIGINAL )
+ : /*has_written_console_ext(false)
+ , */m_attr(attr)
+ , m_fg(fg)
+ , m_bg(bg)
+ {}
+
+ friend std::ostream&
+ operator<<( std::ostream& os, setcolor const& sc )
+ {
+ sc.set_console_color(os);
+ return os;
+ }
+
+private:
+ term_attr::_ m_attr;
+ term_color::_ m_fg;
+ term_color::_ m_bg;
+
+protected:
+ // Data members
+ mutable WORD saved_attributes;
+ //mutable bool has_written_console_ext;
+};
+
+#endif
// ************************************************************************** //
// ************** scope_setcolor ************** //
// ************************************************************************** //
+#ifndef _WIN32
+
struct scope_setcolor {
scope_setcolor() : m_os( 0 ) {}
explicit scope_setcolor( std::ostream& os,
@@ -106,15 +260,50 @@ struct scope_setcolor {
*m_os << setcolor();
}
private:
+ scope_setcolor(const scope_setcolor& r);
+ scope_setcolor& operator=(const scope_setcolor& r);
// Data members
std::ostream* m_os;
};
-#define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \
- utils::scope_setcolor const& sc = is_color_output \
- ? utils::scope_setcolor( os, utils::attr, utils::color ) \
- : utils::scope_setcolor(); \
- ut_detail::ignore_unused_variable_warning( sc ) \
+#else
+
+struct scope_setcolor : setcolor {
+ scope_setcolor() : m_os( 0 ) {}
+ explicit scope_setcolor(
+ std::ostream& os,
+ term_attr::_ attr = term_attr::NORMAL,
+ term_color::_ fg = term_color::ORIGINAL,
+ term_color::_ bg = term_color::ORIGINAL )
+ :
+ setcolor(attr, fg, bg),
+ m_os( &os )
+ {
+ os << *this;
+ }
+
+ ~scope_setcolor()
+ {
+ if (m_os) {
+ set_console_color(*m_os, &this->saved_attributes);
+ }
+ }
+private:
+ scope_setcolor(const scope_setcolor& r);
+ scope_setcolor& operator=(const scope_setcolor& r);
+ // Data members
+ std::ostream* m_os;
+};
+
+
+#endif
+
+#define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \
+ utils::scope_setcolor const sc( \
+ os, \
+ is_color_output ? utils::attr : utils::term_attr::NORMAL, \
+ is_color_output ? utils::color : utils::term_color::ORIGINAL);\
+ ut_detail::ignore_unused_variable_warning( sc ) \
/**/
} // namespace utils