From d4d71a6659b659057864f224c42f54166899207e Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sun, 30 Jul 2017 03:47:06 +0200 Subject: [PATCH 01/41] Removing unused headers --- include/boost/test/impl/unit_test_parameters.ipp | 1 - include/boost/test/utils/is_forward_iterable.hpp | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/include/boost/test/impl/unit_test_parameters.ipp b/include/boost/test/impl/unit_test_parameters.ipp index b825c46d..ffc3e48d 100644 --- a/include/boost/test/impl/unit_test_parameters.ipp +++ b/include/boost/test/impl/unit_test_parameters.ipp @@ -43,7 +43,6 @@ #include #include #include -#include #include // STL diff --git a/include/boost/test/utils/is_forward_iterable.hpp b/include/boost/test/utils/is_forward_iterable.hpp index e8f5d394..821ead38 100644 --- a/include/boost/test/utils/is_forward_iterable.hpp +++ b/include/boost/test/utils/is_forward_iterable.hpp @@ -35,8 +35,8 @@ #else // Boost +#include #include -#include #include #include #include From c3e34389d681ed28b5de9645cd55d778e506e208 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 31 Aug 2017 11:19:57 +0200 Subject: [PATCH 02/41] Boost 1.66 change logs --- doc/closing_chapters/change_log.qbk | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 64d7bf96..1576986a 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -7,6 +7,15 @@ [section Change log] +[h4 Boost.Test v3.7 / boost 1.66] + +[h5 Breaking changes] + +[h5 New features] + +[h5 Bugfixes and feature requests] + + [h4 Boost.Test v3.6 / boost 1.65] [h5 Breaking changes] From c06ac34b376f068dd7f22fff1adb8ee4f400c73e Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Mon, 25 Dec 2017 16:26:45 +0100 Subject: [PATCH 03/41] Change log update for 1.67 --- .gitignore | 3 +++ doc/closing_chapters/change_log.qbk | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 8be684b4..6d68eb09 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,6 @@ doc/html/*.html doc/examples/build doc/doxygen build/tmp +Master_Test_Suite*.xml +smoke-ts-sink.* +smoke-ts-sink-new-style.* diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 1576986a..ae9de65d 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -7,7 +7,7 @@ [section Change log] -[h4 Boost.Test v3.7 / boost 1.66] +[h4 Boost.Test v3.7 / boost 1.67] [h5 Breaking changes] From 93cc089c49c9a35036ff9c038907ea7e8bf608dc Mon Sep 17 00:00:00 2001 From: Brian Kuhl Date: Tue, 5 Sep 2017 23:12:47 -0400 Subject: [PATCH 04/41] Adapt Boost.Test to VxWorks - execution_monitor.ipp: m_sig_info doesn't have all the POSIX designated members and VxWorks has no USER signal - basic_cstring.hpp: Diab compiler has limit on size of enum, similar to the IBM compiler - VxWorks also has limited signals --- include/boost/test/impl/execution_monitor.ipp | 12 +++++++++++- .../boost/test/utils/basic_cstring/basic_cstring.hpp | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/include/boost/test/impl/execution_monitor.ipp b/include/boost/test/impl/execution_monitor.ipp index 94b6f9fb..035bb958 100644 --- a/include/boost/test/impl/execution_monitor.ipp +++ b/include/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 using std::va_list; #endif +#if defined(__VXWORKS__) +# define BOOST_TEST_LIMITED_SIGNAL_DETAILS +#endif + #ifdef BOOST_SEH_BASED_SIGNAL_HANDLING # include @@ -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/include/boost/test/utils/basic_cstring/basic_cstring.hpp b/include/boost/test/utils/basic_cstring/basic_cstring.hpp index fdd87d52..a1acd14d 100644 --- a/include/boost/test/utils/basic_cstring/basic_cstring.hpp +++ b/include/boost/test/utils/basic_cstring/basic_cstring.hpp @@ -60,7 +60,7 @@ public: // !! should also present reverse_iterator, const_reverse_iterator -#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) +#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) && !defined(__DCC__) enum npos_type { npos = static_cast(-1) }; #else // IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes. From c0693942195e2f83ef47ab0c8e63635e86995e82 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Wed, 6 Sep 2017 09:56:29 +0200 Subject: [PATCH 05/41] Change log update --- doc/closing_chapters/change_log.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ae9de65d..10e9740c 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -14,7 +14,7 @@ [h5 New features] [h5 Bugfixes and feature requests] - +# [pull_request 118] Update VxWorks support [h4 Boost.Test v3.6 / boost 1.65] From 2b100e13ca20bce55a317a6e2b8cbfd3bbac9e33 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sun, 12 Nov 2017 16:51:20 +0100 Subject: [PATCH 06/41] Colorized and clearer help - Color output on Windows - Pretty printing of long docstrings - Avoid colorizing streams we do not know --- .../boost/test/impl/unit_test_parameters.ipp | 120 ++++++----- .../boost/test/utils/runtime/cla/parser.hpp | 122 ++++++++--- .../boost/test/utils/runtime/parameter.hpp | 98 +++++++-- include/boost/test/utils/setcolor.hpp | 196 +++++++++++++++++- 4 files changed, 424 insertions(+), 112 deletions(-) diff --git a/include/boost/test/impl/unit_test_parameters.ipp b/include/boost/test/impl/unit_test_parameters.ipp index ffc3e48d..428c1011 100644 --- a/include/boost/test/impl/unit_test_parameters.ipp +++ b/include/boost/test/impl/unit_test_parameters.ipp @@ -111,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 " @@ -144,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." )); @@ -163,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 @@ -182,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 ); @@ -196,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)." )); @@ -211,7 +211,7 @@ register_parameters( rt::parameters_store& store ) rt::default_value = 1L, rt::optional_value = 1L, rt::value_hint = "", - 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 " @@ -241,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." )); @@ -284,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 " @@ -299,7 +299,7 @@ register_parameters( rt::parameters_store& store ) /////////////////////////////////////////////// rt::enum_parameter 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::value = @@ -332,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 " @@ -347,11 +347,11 @@ register_parameters( rt::parameters_store& store ) /////////////////////////////////////////////// rt::parameter 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 = "", - 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." )); @@ -379,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 " @@ -397,9 +397,12 @@ register_parameters( rt::parameters_store& store ) rt::parameter 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, "=" ); @@ -414,14 +417,14 @@ register_parameters( rt::parameters_store& store ) rt::default_value = 0U, rt::optional_value = 1U, rt::value_hint = "", - 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, "=" ); @@ -430,7 +433,7 @@ register_parameters( rt::parameters_store& store ) /////////////////////////////////////////////// rt::enum_parameter 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::value = @@ -447,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 " @@ -462,7 +465,7 @@ register_parameters( rt::parameters_store& store ) /////////////////////////////////////////////// rt::enum_parameter 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::value = @@ -481,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, "=" ); @@ -511,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 = "", - 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." )); @@ -540,13 +543,13 @@ register_parameters( rt::parameters_store& store ) /////////////////////////////////////////////// rt::parameter 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 = "", - 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." @@ -575,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, "=" ); @@ -589,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 ); @@ -602,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, "=" ); @@ -617,10 +620,10 @@ register_parameters( rt::parameters_store& store ) rt::description = "Help for framework parameters.", rt::optional_value = std::string(), rt::value_hint = "", - 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." )); @@ -674,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(runtime_config::btrt_color_output); + } + // Report help if requested if( runtime_config::get( btrt_version ) ) { parser->version( std::cerr ); BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) ); } else if( runtime_config::get( 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( btrt_help ) ); + parser->help(std::cerr, + s_parameters_store, + runtime_config::get( btrt_help ), + use_color ); BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) ); } diff --git a/include/boost/test/utils/runtime/cla/parser.hpp b/include/boost/test/utils/runtime/cla/parser.hpp index 9fe8e1bb..a57091b4 100644 --- a/include/boost/test/utils/runtime/cla/parser.hpp +++ b/include/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=\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="; + } + 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\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."; + 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." + ); - 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 ); + 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."; + } + + + { + 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=', the corresponding " + "environment variable is 'BOOST_TEST_ARGUMENT_X=value" + ); + + + + 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= to display detailed help for specific parameter.\n"; } private: diff --git a/include/boost/test/utils/runtime/parameter.hpp b/include/boost/test/utils/runtime/parameter.hpp index f11ce981..1389cf34 100644 --- a/include/boost/test/utils/runtime/parameter.hpp +++ b/include/boost/test/utils/runtime/parameter.hpp @@ -24,6 +24,7 @@ // Boost.Test #include #include +#include // Boost #include @@ -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; - if( id.m_negatable ) - cla_name_help( ostr, id.m_tag, negation_prefix_ ); - else - cla_name_help( ostr, id.m_tag, "" ); + ostr << " " << id.m_prefix; + if( id.m_negatable ) + cla_name_help( ostr, id.m_tag, negation_prefix_, use_color ); + else + 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/include/boost/test/utils/setcolor.hpp b/include/boost/test/utils/setcolor.hpp index c7020903..29758531 100644 --- a/include/boost/test/utils/setcolor.hpp +++ b/include/boost/test/utils/setcolor.hpp @@ -24,6 +24,10 @@ #include +#ifdef _WIN32 +#include +#endif + //____________________________________________________________________________// namespace boost { @@ -64,6 +68,7 @@ struct term_color { enum _ { // ************** setcolor ************** // // ************************************************************************** // +#ifndef _WIN32 class setcolor { public: // Constructor @@ -77,7 +82,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 +94,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 +255,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 From 70403145252bd08c246405a110748fe50af70f52 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 23 Nov 2017 16:16:37 +0100 Subject: [PATCH 07/41] Change log update --- doc/closing_chapters/change_log.qbk | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ae9de65d..92dda918 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -11,7 +11,13 @@ [h5 Breaking changes] +* Now colour is on by default for the output streams that are either `std::cout` or `std::cerr`. This can be + disabled by passing [link boost_test.utf_reference.rt_param_reference.color_output `--no_color_ouput`] (or just `--no_color`) + to the command line. + [h5 New features] +* Colour output on Windows +* Improved and clearer command line help [h5 Bugfixes and feature requests] From 3f305cebf0ebdd2e58baa7d8b0da0fa3c177356f Mon Sep 17 00:00:00 2001 From: "James E. King III" Date: Thu, 9 Nov 2017 11:19:34 -0800 Subject: [PATCH 08/41] fix compiler warning --- include/boost/test/impl/compiler_log_formatter.ipp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/test/impl/compiler_log_formatter.ipp b/include/boost/test/impl/compiler_log_formatter.ipp index 0e83448b..aa0a0e22 100644 --- a/include/boost/test/impl/compiler_log_formatter.ipp +++ b/include/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; } From deb9efa2c1d02d1c2bc9c063ab84863724619c2f Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Mon, 25 Dec 2017 16:45:39 +0100 Subject: [PATCH 09/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ae9de65d..a12b063d 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -14,6 +14,7 @@ [h5 New features] [h5 Bugfixes and feature requests] +# [pull_request 121] fix compiler warning [h4 Boost.Test v3.6 / boost 1.65] From 0f4c3f001973bbb46514e453622941caf48e9e61 Mon Sep 17 00:00:00 2001 From: Aaron Gorenstein Date: Tue, 14 Feb 2017 12:04:24 -0800 Subject: [PATCH 10/41] Deliberate-failure tests shouldn't be optimized A few tests designed to deliberately fail appeal to UB (undefined behavior), but as the MSVC optimizer improves we will take advantage of that to remove UB statements. In order for deliberate failures to occur, the tests must have the optimizer turned off. --- doc/examples/example22.run-fail.cpp | 9 +++++++++ doc/examples/example23.run-fail.cpp | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/doc/examples/example22.run-fail.cpp b/doc/examples/example22.run-fail.cpp index 42f0ae2d..b9c93c40 100644 --- a/doc/examples/example22.run-fail.cpp +++ b/doc/examples/example22.run-fail.cpp @@ -23,8 +23,17 @@ void goo( int ) { } +#if defined(BOOST_MSVC) +// compiler optimizations may cause this code NOT to crash. +#pragma optimize("", off) +#endif + void foo( int i ) { goo( 2/(i-1) ); } + +#if defined(BOOST_MSVC) +#pragma optimize("", on) +#endif //] diff --git a/doc/examples/example23.run-fail.cpp b/doc/examples/example23.run-fail.cpp index 34b40448..1b57feef 100644 --- a/doc/examples/example23.run-fail.cpp +++ b/doc/examples/example23.run-fail.cpp @@ -9,8 +9,18 @@ #define BOOST_TEST_MODULE example #include +#if defined(BOOST_MSVC) +// compiler optimizations may cause this code NOT to crash. +#pragma optimize("", off) +#endif + + void foo( int ) {} +#if defined(BOOST_MSVC) +#pragma optimize("", on) +#endif + BOOST_AUTO_TEST_CASE( test_case ) { int* p = 0; From 26d11fac07093d1feb4fd82557481c8836c40145 Mon Sep 17 00:00:00 2001 From: Aaron Gorenstein Date: Tue, 21 Mar 2017 11:36:44 -0700 Subject: [PATCH 11/41] Added BOOST_MSVC version check to test patches --- doc/examples/example22.run-fail.cpp | 6 +++--- doc/examples/example23.run-fail.cpp | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/examples/example22.run-fail.cpp b/doc/examples/example22.run-fail.cpp index b9c93c40..7bd2bade 100644 --- a/doc/examples/example22.run-fail.cpp +++ b/doc/examples/example22.run-fail.cpp @@ -23,8 +23,8 @@ void goo( int ) { } -#if defined(BOOST_MSVC) -// compiler optimizations may cause this code NOT to crash. +#if defined(BOOST_MSVC) && (BOOST_MSVC > 1900) +// VS2017+ compiler optimizations may cause this code NOT to crash. #pragma optimize("", off) #endif @@ -33,7 +33,7 @@ void foo( int i ) goo( 2/(i-1) ); } -#if defined(BOOST_MSVC) +#if defined(BOOST_MSVC) && (BOOST_MSVC > 1900) #pragma optimize("", on) #endif //] diff --git a/doc/examples/example23.run-fail.cpp b/doc/examples/example23.run-fail.cpp index 1b57feef..5b824b78 100644 --- a/doc/examples/example23.run-fail.cpp +++ b/doc/examples/example23.run-fail.cpp @@ -9,15 +9,15 @@ #define BOOST_TEST_MODULE example #include -#if defined(BOOST_MSVC) -// compiler optimizations may cause this code NOT to crash. +#if defined(BOOST_MSVC) && (BOOST_MSVC > 1900) +// VS2017+ compiler optimizations may cause this code NOT to crash. #pragma optimize("", off) #endif void foo( int ) {} -#if defined(BOOST_MSVC) +#if defined(BOOST_MSVC) && (BOOST_MSVC > 1900) #pragma optimize("", on) #endif From 5edea86f6d1dbbb6fb5fc65e12a6dd2ba4764e3a Mon Sep 17 00:00:00 2001 From: Romain Geissler Date: Tue, 19 Dec 2017 00:23:45 +0100 Subject: [PATCH 12/41] Fix some fallthrough warnings with gcc >= 7. --- include/boost/test/impl/framework.ipp | 1 + include/boost/test/impl/junit_log_formatter.ipp | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/include/boost/test/impl/framework.ipp b/include/boost/test/impl/framework.ipp index ca35ce1c..c86d0bd4 100644 --- a/include/boost/test/impl/framework.ipp +++ b/include/boost/test/impl/framework.ipp @@ -1568,6 +1568,7 @@ run( test_unit_id id, bool continue_test ) break; case 1: seed = static_cast( 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 ); diff --git a/include/boost/test/impl/junit_log_formatter.ipp b/include/boost/test/impl/junit_log_formatter.ipp index 0ec8d438..8bc5bef4 100644 --- a/include/boost/test/impl/junit_log_formatter.ipp +++ b/include/boost/test/impl/junit_log_formatter.ipp @@ -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: { From 05e8eff23129b96319f516b8d04ac38a7c849491 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 28 Dec 2017 17:09:58 +0100 Subject: [PATCH 13/41] Change log --- doc/closing_chapters/change_log.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ae9de65d..bea9fc6e 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -14,7 +14,7 @@ [h5 New features] [h5 Bugfixes and feature requests] - +# [pull_request 122] Fix some fallthrough warnings with `gcc >= 7` [h4 Boost.Test v3.6 / boost 1.65] From 52a09ddc7cd75c295058cf67127a5445c02481ae Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 28 Dec 2017 18:22:50 +0100 Subject: [PATCH 14/41] Contribution instructions, better README.md --- CONTRIBUTE.md | 25 +++++++++++++++++++++++++ README.md | 36 +++++++++++++++++++++++++++--------- test/README.md | 38 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 9 deletions(-) create mode 100644 CONTRIBUTE.md create mode 100644 test/README.md diff --git a/CONTRIBUTE.md b/CONTRIBUTE.md new file mode 100644 index 00000000..e9773acd --- /dev/null +++ b/CONTRIBUTE.md @@ -0,0 +1,25 @@ +# How to contribute to Boost.Test + +## Ticket +We like having a ticket stating the bug or the feature you want to implement. We use a dedicated ticket +management for this that can be found here: https://svn.boost.org/ . Please create a ticket there +by selecting the component `test`. + +## Pull requests +We welcome any contribution in the form of a pull request. Each PR is never integrated exactly as submitted, +we first run our internal unit tests on several platforms, and work the PR if needed. + +To ease the work of the maintainer and make the integration of your changes faster, please + +- base all your PR on the latest develop, rebase if develop changed since you forked the library +- ensure that your changes are not creating any regression in the current test bed (see below on how to run + the unit tests) +- provide a test case that reproduces the problem you encountered +- integrate your unit test into the `Jamfile.v2` of the test folder + +# Running the unit tests +Please make sure that the current set of tests pass for the changes that you submit. +To run the tests, see [this document](test/README.md). + +# Compile the documentation +The instructions for compiling the documentation are provided in [this document](doc/README.md). diff --git a/README.md b/README.md index 7e46241b..ebf4f73f 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,39 @@ ![boosttest logo](doc/html/images/boost.test.logo.png) -This is the main directory for the Boost Test Library. +# What is Boost.Test? +Boost.Test is a C++03 and C++11/14 unit testing library, available on a wide range of platforms and compilers. -(Not to be confused with a directory containing test programs for the parent directory.) +The library is part of [Boost](www.boost.org). The latest release +of the library is available from the boost web site. Full instructions for use of this library can be accessed from http://www.boost.org/doc/libs/release/libs/test/ -This library is part of boost (see www.boost.org), the latest version -of the library is available from the boost web site, or development -snapshots from the boost git repository at -https://github.com/boostorg/test +# Key features -************************************************************************ +* Easy to get started with: + 1. download and deflate the latest boost archive + 1. create a test module with this (header version): + ``` + #define BOOST_TEST_MODULE your_test_module + #include + ``` + 1. done +* powerful and unique test assertion macro [`BOOST_TEST`](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/testing_tools/boost_test_universal_macro.html), that understands floating points, collections, strings... and uses appropriate comparison paradigm +* self-registering test cases, organize cases in test suites, apply fixtures on test cases, suites or globally +* provide assertion [context](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/test_output/test_tools_support_for_logging/contexts.html) for advanced diagnostic on failure +* powerful and extensible [dataset](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/tests_organization/test_cases/test_case_generation.html) tests +* add [decoration](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/tests_organization/decorators.html) to test cases and suites for [advanced description](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/tests_organization/semantic.html), [group/label](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/tests_organization/tests_grouping.html), and [dependencies](http://www.boost.org/doc/libs/release/libs/test/doc/html/boost_test/tests_organization/tests_dependencies.html) +* powerful command line options and test case filters +* extensible logging, XML and JUNIT outputs for third-party tools (eg. cont. integration) +* various usage (shared/static library) for faster compilation/build cycles, smaller binaries +# Copyright and license Copyright 2001-2014, Gennadiy Rozental. -Copyright 2013-2015, Boost.Test team. +Copyright 2013-2018, Boost.Test team. Distributed under the Boost Software License, Version 1.0. -(See accompanying file LICENSE_1_0.txt or copy at www.boost.org/LICENSE_1_0.txt) +(Get a copy at www.boost.org/LICENSE_1_0.txt) + +# Contribute +Please read [this document](CONTRIBUTE.md) to get started. diff --git a/test/README.md b/test/README.md new file mode 100644 index 00000000..a00c6297 --- /dev/null +++ b/test/README.md @@ -0,0 +1,38 @@ +# How to run the unit tests + +This folder contains the unit tests for Boost.Test. + +In order to run the unit tests, you first need to create `b2`. Check the documentation of boost +on how to generate `b2`. + +## OSX + +Please run the tests in C++11 mode, with the following commands + + cd + ./bootstrap.sh + ./b2 headers + cd libs/test/test + ../../../b2 -j8 toolset=clang cxxflags="-stdlib=libc++ -std=c++11" linkflags="-stdlib=libc++" + +## Linux + +As for OSX, please run the tests in C++11 mode, using the following commands + + cd + ./bootstrap.sh + ./b2 headers + cd libs/test/test + ../../../b2 cxxflags=-std=c++11 + +## Windows + + +### Visual Studio 2017 C++17 mode +To run the tests for Visual Studio 2017 / C++17 mode, use the following commands: + + cd + call bootstrap.bat + b2 headers + cd libs\test\test + ..\..\..\b2 --abbreviate-paths toolset=msvc-14.1 cxxflags="/std:c++latest" \ No newline at end of file From a3183f2f9afc528db24e48a6ab6fca85383f1386 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 28 Dec 2017 22:49:43 +0100 Subject: [PATCH 15/41] Add link --- doc/tutorials/web_wisdom.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/tutorials/web_wisdom.qbk b/doc/tutorials/web_wisdom.qbk index 7302d6db..bd488d61 100644 --- a/doc/tutorials/web_wisdom.qbk +++ b/doc/tutorials/web_wisdom.qbk @@ -53,5 +53,6 @@ and posted about this online. This page gathers a few of the additional material * [@http://www.eld.leidenuniv.nl/~moene/Home/projects/testdox/boosttest/ Customizing the output log and report format] * [@https://github.com/etas/vs-boost-unit-test-adapter Boost Test Adapter] (Boost.Test extension for Microsoft Visual Studio, also available from [@https://visualstudiogallery.msdn.microsoft.com/5f4ae1bd-b769-410e-8238-fb30beda987f here]). +* [@https://marketplace.visualstudio.com/items?itemName=VisualCPPTeam.TestAdapterforBoostTest Microsoft Boost Test Adapter] [endsect] [/section:web_wisdom] From c18b090c16926ac6a253e06043146f62f681c0fe Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Fri, 29 Dec 2017 20:42:32 +0100 Subject: [PATCH 16/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ae9de65d..2bb1aca8 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -14,6 +14,7 @@ [h5 New features] [h5 Bugfixes and feature requests] +# [pull_request 112] Deliberate-failure tests shouldn't be optimized [h4 Boost.Test v3.6 / boost 1.65] From 6393f2daad911d0cb5f308ad05fc12fd733911ac Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 28 Dec 2017 21:48:33 +0100 Subject: [PATCH 17/41] Bugfix passing random generator --- include/boost/test/impl/framework.ipp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/include/boost/test/impl/framework.ipp b/include/boost/test/impl/framework.ipp index c86d0bd4..a5dfd80f 100644 --- a/include/boost/test/impl/framework.ipp +++ b/include/boost/test/impl/framework.ipp @@ -705,6 +705,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( tu ); @@ -714,14 +717,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 +740,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 From cbd780ea5b1b8da185afe710837f6db6e0013e38 Mon Sep 17 00:00:00 2001 From: Namezero Date: Sun, 6 Aug 2017 13:09:21 +0200 Subject: [PATCH 18/41] Dependency decorators on parent suites (trac #13149) Dependency decorators on parent suites are not honored when a nested test selected to run via command line --- include/boost/test/impl/framework.ipp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/include/boost/test/impl/framework.ipp b/include/boost/test/impl/framework.ipp index c86d0bd4..9786a42f 100644 --- a/include/boost/test/impl/framework.ipp +++ b/include/boost/test/impl/framework.ipp @@ -610,13 +610,22 @@ 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 ) + { + traverse_test_tree( parent_id, enabler, true ); + parent_id = framework::get( parent_id, TUT_ANY ).p_parent_id; + } } // 40. Apply all disablers From 0c36fae06f405aa331ce424ca612e4466a6bbc4f Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Tue, 26 Dec 2017 23:37:04 +0100 Subject: [PATCH 19/41] Fix patch and regression tests --- include/boost/test/impl/framework.ipp | 12 ++- test/Jamfile.v2 | 1 + .../test_unit-nested-suite-dependency.cpp | 84 +++++++++++++++++++ 3 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 test/test-organization-ts/test_unit-nested-suite-dependency.cpp diff --git a/include/boost/test/impl/framework.ipp b/include/boost/test/impl/framework.ipp index 9786a42f..15c30565 100644 --- a/include/boost/test/impl/framework.ipp +++ b/include/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(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; @@ -623,8 +622,13 @@ public: while( parent_id != INV_TEST_UNIT_ID && parent_id != master_tu_id ) { - traverse_test_tree( parent_id, enabler, true ); - parent_id = framework::get( parent_id, TUT_ANY ).p_parent_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; } } diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index f5bc1fd5..2f71457c 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -173,6 +173,7 @@ test-suite "test-organization-ts" [ boost.test-self-test run : test-organization-ts : dataset-variadic_and_move_semantic-test : : : : : : $(requirements_datasets) ] [ boost.test-self-test run : test-organization-ts : test_unit-order-test ] [ boost.test-self-test run : test-organization-ts : test_unit-order-shuffled-test : : : : : : $(requirements_boost_test_full_support) ] + [ boost.test-self-test run : test-organization-ts : test_unit-nested-suite-dependency ] [ boost.test-self-test run : test-organization-ts : test-tree-management-test ] [ boost.test-self-test run : test-organization-ts : test-tree-several-suite-decl ] ; diff --git a/test/test-organization-ts/test_unit-nested-suite-dependency.cpp b/test/test-organization-ts/test_unit-nested-suite-dependency.cpp new file mode 100644 index 00000000..1cf38cfe --- /dev/null +++ b/test/test-organization-ts/test_unit-nested-suite-dependency.cpp @@ -0,0 +1,84 @@ +// (C) Copyright Raffi Enficiaud 2017. +// 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 +//! checking the nested suites activation, ticket trac #13149 +// ***************************************************************************** + +#define BOOST_TEST_MODULE test_nested_dependency +#include +#include +#include +#include + +// initial reproducing snippet on the corresponding ticket +#if 0 +BOOST_AUTO_TEST_SUITE(suite1, *boost::unit_test::depends_on("suite2")) + BOOST_AUTO_TEST_SUITE(suite1_nested) + BOOST_AUTO_TEST_CASE(suite1_test1) + { + BOOST_CHECK(true); + } + BOOST_AUTO_TEST_SUITE_END() +BOOST_AUTO_TEST_SUITE_END() + +BOOST_AUTO_TEST_SUITE(suite2) + BOOST_AUTO_TEST_CASE(suite2_test2) + { + BOOST_CHECK(true); + } +BOOST_AUTO_TEST_SUITE_END() +#endif + +void suite1_test1() +{ + BOOST_CHECK(true); +} + +void suite2_test2() +{ + BOOST_CHECK(true); +} + +BOOST_AUTO_TEST_CASE( some_test ) +{ + using namespace boost::unit_test; + + // test tree + test_suite* master_ts = BOOST_TEST_SUITE("local master"); + test_suite* t_suite1 = BOOST_TEST_SUITE( "suite1" ); + test_suite* t_suite1_nested = BOOST_TEST_SUITE( "suite1_nested" ); + t_suite1_nested->add( BOOST_TEST_CASE( suite1_test1 ) ); + t_suite1->add(t_suite1_nested); + + test_suite* t_suite2 = BOOST_TEST_SUITE( "suite2" ); + t_suite2->add( BOOST_TEST_CASE( suite2_test2 ) ); + + master_ts->add(t_suite1); + master_ts->add(t_suite2); + + // dependencies + t_suite1->depends_on( t_suite2 ); + + // running + char const* argv[] = { "dummy-test-module.exe", "--log_level=all", "--run_test=suite1/suite1_nested"}; + int argc = sizeof(argv)/sizeof(argv[0]); + + master_ts->p_default_status.value = test_unit::RS_ENABLED; + framework::finalize_setup_phase( master_ts->p_id ); + + runtime_config::init( argc, (char**)argv ); + framework::impl::setup_for_execution( *master_ts ); + + // no need to run + //framework::run( master_ts ); + + // we should have 2 test cases enabled with this run parameters + test_case_counter tcc; + traverse_test_tree( master_ts->p_id, tcc ); + BOOST_TEST( tcc.p_count == 2 ); +} From 6ecfe4b7cf679ab29a03432d5c51787e7eca12d9 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Tue, 26 Dec 2017 23:37:54 +0100 Subject: [PATCH 20/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ea786e45..e314c180 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -24,6 +24,7 @@ # [pull_request 118] Update VxWorks support # [pull_request 121] fix compiler warning # [pull_request 122] Fix some fallthrough warnings with `gcc >= 7` +# [ticket 13149] Dependency decorators on parent suites [h4 Boost.Test v3.6 / boost 1.65] From c767b8790aa3f8d84c75cd1e57416b2cacf18056 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sat, 30 Dec 2017 10:44:18 +0100 Subject: [PATCH 21/41] Fix issue when library is compiled with non C++14 options (trac 12969) --- include/boost/test/impl/test_tools.ipp | 8 -------- include/boost/test/tools/detail/print_helper.hpp | 7 +++++-- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/include/boost/test/impl/test_tools.ipp b/include/boost/test/impl/test_tools.ipp index 7e014533..29568793 100644 --- a/include/boost/test/impl/test_tools.ipp +++ b/include/boost/test/impl/test_tools.ipp @@ -119,14 +119,6 @@ print_log_value::operator()( std::ostream& ostr, wchar_t const* ostr << ( t ? t : L"null string" ); } -#if !defined(BOOST_NO_CXX11_NULLPTR) -void -print_log_value::operator()( std::ostream& ostr, std::nullptr_t ) -{ - ostr << "nullptr"; -} -#endif - //____________________________________________________________________________// // ************************************************************************** // diff --git a/include/boost/test/tools/detail/print_helper.hpp b/include/boost/test/tools/detail/print_helper.hpp index 1e4dd6e3..e95e27ab 100644 --- a/include/boost/test/tools/detail/print_helper.hpp +++ b/include/boost/test/tools/detail/print_helper.hpp @@ -166,8 +166,11 @@ struct BOOST_TEST_DECL print_log_value { #if !defined(BOOST_NO_CXX11_NULLPTR) template<> -struct BOOST_TEST_DECL print_log_value { - void operator()( std::ostream& ostr, std::nullptr_t t ); +struct print_log_value { + // 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 From bc53f66ac32a914c55b9fcbb4bf2a2d00aa88fac Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sat, 30 Dec 2017 10:47:29 +0100 Subject: [PATCH 22/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index ea786e45..e6901c7b 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -24,6 +24,7 @@ # [pull_request 118] Update VxWorks support # [pull_request 121] fix compiler warning # [pull_request 122] Fix some fallthrough warnings with `gcc >= 7` +# [ticket 12969] Problem linking `print_helper_t` under Clang [h4 Boost.Test v3.6 / boost 1.65] From 306b55259d50b67cfdadd9679dcfbaa4b150a6fc Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Tue, 2 Jan 2018 11:22:40 +0100 Subject: [PATCH 23/41] Check for clashing names in adding test units - clashing on name only - adding tests --- include/boost/test/impl/test_tree.ipp | 8 +++ test/Jamfile.v2 | 1 + .../test_unit-report-clashing-names.cpp | 68 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 test/test-organization-ts/test_unit-report-clashing-names.cpp diff --git a/include/boost/test/impl/test_tree.ipp b/include/boost/test/impl/test_tree.ipp index 81995bb2..d6212ab1 100644 --- a/include/boost/test/impl/test_tree.ipp +++ b/include/boost/test/impl/test_tree.ipp @@ -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 ); diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 2f71457c..414314f9 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -176,6 +176,7 @@ test-suite "test-organization-ts" [ boost.test-self-test run : test-organization-ts : test_unit-nested-suite-dependency ] [ boost.test-self-test run : test-organization-ts : test-tree-management-test ] [ boost.test-self-test run : test-organization-ts : test-tree-several-suite-decl ] + [ boost.test-self-test run : test-organization-ts : test_unit-report-clashing-names ] ; #_________________________________________________________________________________________________# diff --git a/test/test-organization-ts/test_unit-report-clashing-names.cpp b/test/test-organization-ts/test_unit-report-clashing-names.cpp new file mode 100644 index 00000000..0edf0577 --- /dev/null +++ b/test/test-organization-ts/test_unit-report-clashing-names.cpp @@ -0,0 +1,68 @@ +// (C) Copyright Raffi Enficiaud 2018. +// 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 +//! checking the clashing names, ticket trac #12597 +// ***************************************************************************** + +#define BOOST_TEST_MODULE test_clashing_names +#include +#include + +void suite1_test1() +{ + BOOST_CHECK(true); +} + +BOOST_AUTO_TEST_CASE( test_clashing_suites ) +{ + using namespace boost::unit_test; + test_suite* master_ts = BOOST_TEST_SUITE("local master"); + test_suite* t_suite1 = BOOST_TEST_SUITE( "suite1" ); + test_suite* t_suite2 = BOOST_TEST_SUITE( "suite1" ); + master_ts->add(t_suite1); + BOOST_CHECK_THROW( master_ts->add(t_suite2), + boost::unit_test::framework::setup_error ); +} + +BOOST_AUTO_TEST_CASE( test_clashing_cases ) +{ + using namespace boost::unit_test; + test_suite* master_ts = BOOST_TEST_SUITE("local master"); + test_suite* t_suite1 = BOOST_TEST_SUITE( "suite1" ); + test_suite* t_suite2 = BOOST_TEST_SUITE( "suite2" ); + master_ts->add(t_suite1); + master_ts->add(t_suite2); + + t_suite1->add( BOOST_TEST_CASE( suite1_test1 ) ); + BOOST_CHECK_THROW( t_suite1->add( BOOST_TEST_CASE( suite1_test1 ) ), + boost::unit_test::framework::setup_error ); + + BOOST_CHECK_NO_THROW( t_suite2->add( BOOST_TEST_CASE( suite1_test1 ) ) ); +} + +BOOST_TEST_CASE_TEMPLATE_FUNCTION( template_test_case, T ) +{ + BOOST_TEST( sizeof(T) == 4U ); +} + +BOOST_AUTO_TEST_CASE( test_clashing_cases_template_test_case ) +{ + using namespace boost::unit_test; + test_suite* master_ts = BOOST_TEST_SUITE("local master"); + test_suite* t_suite1 = BOOST_TEST_SUITE( "suite1" ); + test_suite* t_suite2 = BOOST_TEST_SUITE( "suite2" ); + master_ts->add(t_suite1); + master_ts->add(t_suite2); + + typedef boost::mpl::list test_types1; + typedef boost::mpl::list test_types2; + + BOOST_CHECK_NO_THROW( t_suite2->add( BOOST_TEST_CASE_TEMPLATE( template_test_case, test_types1 ) ) ); + BOOST_CHECK_THROW( t_suite1->add( BOOST_TEST_CASE_TEMPLATE( template_test_case, test_types2 ) ), + boost::unit_test::framework::setup_error ); +} From 77bda1ffd272655077c3bb0fba9840d23f57e460 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Tue, 2 Jan 2018 20:39:25 +0100 Subject: [PATCH 24/41] Avoiding duplicate test cases in template and param test cases - fixing logging on non-existant stream - fixing doc test cases with duplicate test cases - updating log and report tests --- doc/examples/example49.run.cpp | 14 ++--- include/boost/test/parameterized_test.hpp | 6 +- .../log-formatter-test.pattern | 60 +++++++++---------- .../result-report-test.pattern | 4 +- test/framework-ts/log-formatter-test.cpp | 5 +- test/framework-ts/result-report-test.cpp | 4 +- .../parameterized_test-test.cpp | 60 ++++++++++++------- .../test-tree-management-test.cpp | 2 +- .../test_case_template-test.cpp | 27 +++++++-- 9 files changed, 105 insertions(+), 77 deletions(-) diff --git a/doc/examples/example49.run.cpp b/doc/examples/example49.run.cpp index 9c5da8e2..495c2a21 100644 --- a/doc/examples/example49.run.cpp +++ b/doc/examples/example49.run.cpp @@ -6,20 +6,14 @@ // See http://www.boost.org/libs/test for the library home page. //[example_code +#define BOOST_TEST_MODULE example49 #include +#include using namespace boost::unit_test; -void free_test_function() +BOOST_DATA_TEST_CASE( free_test_function, boost::unit_test::data::xrange(1000) ) { + // sleep(1); BOOST_TEST( true /* test assertion */ ); } - -test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) -{ - for( int i=0; i < 10000; i++ ) - framework::master_test_suite(). - add( BOOST_TEST_CASE( &free_test_function ) ); - - return 0; -} //] diff --git a/include/boost/test/parameterized_test.hpp b/include/boost/test/parameterized_test.hpp index b94e7ec8..cc9487ab 100644 --- a/include/boost/test/parameterized_test.hpp +++ b/include/boost/test/parameterized_test.hpp @@ -14,6 +14,7 @@ // Boost.Test #include +#include // Boost #include @@ -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/test/baseline-outputs/log-formatter-test.pattern b/test/baseline-outputs/log-formatter-test.pattern index 9681306b..b25ad96e 100644 --- a/test/baseline-outputs/log-formatter-test.pattern +++ b/test/baseline-outputs/log-formatter-test.pattern @@ -279,11 +279,11 @@ xxx/log-formatter-test.cpp:62: fatal error: in "Fake Test Suite Hierarchy/3 test Failure occurred in a following context: some context xxx/log-formatter-test.cpp:224: Leaving test case "very_bad_foo" -xxx/log-formatter-test.cpp:226: Test case "Fake Test Suite Hierarchy/3 test cases inside/bad_foo" is skipped because dependency test case "Fake Test Suite Hierarchy/3 test cases inside/very_bad_foo" has failed +xxx/log-formatter-test.cpp:226: Test case "Fake Test Suite Hierarchy/3 test cases inside/bad_foo2" is skipped because dependency test case "Fake Test Suite Hierarchy/3 test cases inside/very_bad_foo" has failed xxx/log-formatter-test.cpp:222: Leaving test suite "3 test cases inside" * 2-format ******************************************************************* -ZZZZZZ +ZZZZZZ * 3-format ******************************************************************* @@ -343,10 +343,10 @@ ASSERTION FAILURE: - line: 224 ]]> - + @@ -398,10 +398,10 @@ ASSERTION FAILURE: - line: 224 ]]> - + @@ -433,20 +433,20 @@ xxx/log-formatter-test.cpp:71: last checkpoint Failure occurred in a following context: exception context should be shown xxx/log-formatter-test.cpp:233: Leaving test case "very_bad_exception" -xxx/log-formatter-test.cpp:234: Entering test case "bad_foo" -xxx/log-formatter-test.cpp:48: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo": +xxx/log-formatter-test.cpp:234: Entering test case "bad_foo2" +xxx/log-formatter-test.cpp:48: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo2": this is a message xxx/log-formatter-test.cpp:51: info: check true has passed -xxx/log-formatter-test.cpp:55: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo": with some message +xxx/log-formatter-test.cpp:55: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo2": with some message Failure occurred in a following context: Context value=something Context value2=something different -xxx/log-formatter-test.cpp:57: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo": non sense -xxx/log-formatter-test.cpp:234: Leaving test case "bad_foo" +xxx/log-formatter-test.cpp:57: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo2": non sense +xxx/log-formatter-test.cpp:234: Leaving test case "bad_foo2" xxx/log-formatter-test.cpp:230: Leaving test suite "4 test cases inside" * 2-format ******************************************************************* -ZZZZZZZZZZZZ +ZZZZZZZZZZZZ * 3-format ******************************************************************* @@ -541,7 +541,7 @@ CONTEXT: - line: 233 ]]> - + @@ -665,7 +665,7 @@ CONTEXT: - line: 233 ]]> - + @@ -754,22 +754,22 @@ xxx/log-formatter-test.cpp:71: last checkpoint Failure occurred in a following context: exception context should be shown xxx/log-formatter-test.cpp:233: Leaving test case "very_bad_exception" -xxx/log-formatter-test.cpp:234: Entering test case "bad_foo" -xxx/log-formatter-test.cpp:48: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo": +xxx/log-formatter-test.cpp:234: Entering test case "bad_foo2" +xxx/log-formatter-test.cpp:48: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo2": this is a message xxx/log-formatter-test.cpp:51: info: check true has passed -xxx/log-formatter-test.cpp:55: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo": with some message +xxx/log-formatter-test.cpp:55: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo2": with some message Failure occurred in a following context: Context value=something Context value2=something different -xxx/log-formatter-test.cpp:57: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo": non sense -xxx/log-formatter-test.cpp:234: Leaving test case "bad_foo" +xxx/log-formatter-test.cpp:57: error: in "Fake Test Suite Hierarchy/4 test cases inside/bad_foo2": non sense +xxx/log-formatter-test.cpp:234: Leaving test case "bad_foo2" xxx/log-formatter-test.cpp:230: Leaving test suite "4 test cases inside" xxx/log-formatter-test.cpp:222: Test suite "Fake Test Suite Hierarchy/3 test cases inside" is skipped because dependency test suite "Fake Test Suite Hierarchy/1 test cases inside" has failed xxx/log-formatter-test.cpp:236: Leaving test suite "Fake Test Suite Hierarchy" * 2-format ******************************************************************* -ZZZZZZZZZZZZZZZZZZZZZZZZ +ZZZZZZZZZZZZZZZZZZZZZZZZ * 3-format ******************************************************************* @@ -883,10 +883,10 @@ INFO: - disabled test unit: 'Fake Test Suite Hierarchy/3 test cases inside' - reason: 'dependency test suite "Fake Test Suite Hierarchy/1 test cases inside" has failed']]> - + @@ -981,7 +981,7 @@ CONTEXT: - line: 233 ]]> - + @@ -1101,10 +1101,10 @@ ASSERTION FAILURE: - disabled test unit: 'Fake Test Suite Hierarchy/3 test cases inside' - reason: 'dependency test suite "Fake Test Suite Hierarchy/1 test cases inside" has failed']]> - + @@ -1188,7 +1188,7 @@ CONTEXT: - line: 233 ]]> - + diff --git a/test/baseline-outputs/result-report-test.pattern b/test/baseline-outputs/result-report-test.pattern index f1389df2..6cb8fb59 100644 --- a/test/baseline-outputs/result-report-test.pattern +++ b/test/baseline-outputs/result-report-test.pattern @@ -111,11 +111,11 @@ Test suite "Fake Test Suite Hierarchy/3 test cases inside" has failed with: Test case "Fake Test Suite Hierarchy/3 test cases inside/very_bad_foo" was aborted with: 1 assertion out of 1 failed - Test case "Fake Test Suite Hierarchy/3 test cases inside/bad_foo" was skipped + Test case "Fake Test Suite Hierarchy/3 test cases inside/bad_foo2" was skipped ************************************************************************* ************************************************************************* ************************************************************************* -************************************************************************* +************************************************************************* *** 2 failures are detected (1 failure is expected) in the test suite "Fake Test Suite Hierarchy" ************************************************************************* diff --git a/test/framework-ts/log-formatter-test.cpp b/test/framework-ts/log-formatter-test.cpp index 9566cec8..0756c74c 100644 --- a/test/framework-ts/log-formatter-test.cpp +++ b/test/framework-ts/log-formatter-test.cpp @@ -74,6 +74,7 @@ void very_bad_exception() { throw local_exception(); } +void bad_foo2() { bad_foo(); } // tests with clashing names //____________________________________________________________________________// @@ -160,7 +161,7 @@ BOOST_AUTO_TEST_CASE( test_result_reports ) ts_3->add( BOOST_TEST_CASE( bad_foo ) ); test_case* tc1 = BOOST_TEST_CASE( very_bad_foo ); ts_3->add( tc1 ); - test_case* tc2 = BOOST_TEST_CASE( bad_foo ); + test_case* tc2 = BOOST_TEST_CASE( bad_foo2 ); ts_3->add( tc2 ); tc2->depends_on( tc1 ); @@ -168,7 +169,7 @@ BOOST_AUTO_TEST_CASE( test_result_reports ) ts_4->add( BOOST_TEST_CASE( bad_foo ) ); ts_4->add( BOOST_TEST_CASE( very_bad_foo ) ); ts_4->add( BOOST_TEST_CASE( very_bad_exception ) ); - ts_4->add( BOOST_TEST_CASE( bad_foo ) ); + ts_4->add( BOOST_TEST_CASE( bad_foo2 ) ); test_suite* ts_main = BOOST_TEST_SUITE( "Fake Test Suite Hierarchy" ); ts_main->add( ts_0 ); diff --git a/test/framework-ts/result-report-test.cpp b/test/framework-ts/result-report-test.cpp index 643371f4..b8def826 100644 --- a/test/framework-ts/result-report-test.cpp +++ b/test/framework-ts/result-report-test.cpp @@ -46,7 +46,7 @@ void bad_foo() { BOOST_ERROR( "" ); unit_test_log.set_stream( std::cout ); } - +void bad_foo2() { bad_foo(); } // preventing clashing names struct log_guard { ~log_guard() { @@ -141,7 +141,7 @@ BOOST_AUTO_TEST_CASE( test_result_reports ) ts_3->add( BOOST_TEST_CASE( bad_foo ) ); test_case* tc1 = BOOST_TEST_CASE( very_bad_foo ); ts_3->add( tc1 ); - test_case* tc2 = BOOST_TEST_CASE( bad_foo ); + test_case* tc2 = BOOST_TEST_CASE( bad_foo2 ); ts_3->add( tc2 ); tc2->depends_on( tc1 ); diff --git a/test/test-organization-ts/parameterized_test-test.cpp b/test/test-organization-ts/parameterized_test-test.cpp index 70aefe3d..a897ba51 100644 --- a/test/test-organization-ts/parameterized_test-test.cpp +++ b/test/test-organization-ts/parameterized_test-test.cpp @@ -55,12 +55,26 @@ setup_tree( ut::test_suite* master_tu ) //____________________________________________________________________________// +struct logger_guard { + logger_guard(std::ostream& s_out) { + ut::unit_test_log.set_stream( s_out ); + } + ~logger_guard() { + ut::unit_test_log.set_stream( std::cout ); + } +}; + BOOST_AUTO_TEST_CASE( test_case1 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + // if an exception is thrown in the test, this object is destructed when we reach the logger + // for logging the exception. This happens for instance if the test->add throws: + // - test case aborted, null_output destructed but still refered from the logger + // - exception caught by the framework, and exception content logged + // - reference to a non-existing log stream + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 2, 2, 2 }; test->add( BOOST_PARAM_TEST_CASE( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -77,10 +91,10 @@ BOOST_AUTO_TEST_CASE( test_case1 ) BOOST_AUTO_TEST_CASE( test_case2 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 1, 2, 2 }; test->add( BOOST_PARAM_TEST_CASE( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -97,10 +111,10 @@ BOOST_AUTO_TEST_CASE( test_case2 ) BOOST_AUTO_TEST_CASE( test_case3 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 1, 1, 2 }; test->add( BOOST_PARAM_TEST_CASE( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -117,10 +131,10 @@ BOOST_AUTO_TEST_CASE( test_case3 ) BOOST_AUTO_TEST_CASE( test_case4 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 1, 1, 1 }; test->add( BOOST_PARAM_TEST_CASE( &test0, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -137,10 +151,10 @@ BOOST_AUTO_TEST_CASE( test_case4 ) BOOST_AUTO_TEST_CASE( test_case5 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 6, 6, 6 }; test->add( BOOST_PARAM_TEST_CASE( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -158,10 +172,10 @@ BOOST_AUTO_TEST_CASE( test_case5 ) BOOST_AUTO_TEST_CASE( test_case6 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 0, 3, 9 }; test->add( BOOST_PARAM_TEST_CASE( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -178,10 +192,10 @@ BOOST_AUTO_TEST_CASE( test_case6 ) BOOST_AUTO_TEST_CASE( test_case7 ) { - onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + onullstream_type null_output; + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 2, 3, 9 }; test->add( BOOST_PARAM_TEST_CASE( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); @@ -199,9 +213,9 @@ BOOST_AUTO_TEST_CASE( test_case7 ) BOOST_AUTO_TEST_CASE( test_case8 ) { onullstream_type null_output; - ut::test_suite* test = BOOST_TEST_SUITE( "" ); + logger_guard G( null_output ); - ut::unit_test_log.set_stream( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); int test_data[] = { 3, 2, 6 }; test->add( BOOST_PARAM_TEST_CASE( &test1, (int*)test_data, (int*)test_data + sizeof(test_data)/sizeof(int) ) ); diff --git a/test/test-organization-ts/test-tree-management-test.cpp b/test/test-organization-ts/test-tree-management-test.cpp index 1a45844c..86609307 100644 --- a/test/test-organization-ts/test-tree-management-test.cpp +++ b/test/test-organization-ts/test-tree-management-test.cpp @@ -91,7 +91,7 @@ struct F2 { BOOST_FIXTURE_TEST_SUITE( S5, F2 ) -typedef boost::mpl::vector test_types; +typedef boost::mpl::vector test_types; BOOST_AUTO_TEST_CASE_TEMPLATE( tctempl, T, test_types ) { } diff --git a/test/test-organization-ts/test_case_template-test.cpp b/test/test-organization-ts/test_case_template-test.cpp index acd875a3..3000d5b9 100644 --- a/test/test-organization-ts/test_case_template-test.cpp +++ b/test/test-organization-ts/test_case_template-test.cpp @@ -31,6 +31,15 @@ namespace mpl = boost::mpl; // STL #include +struct logger_guard { + logger_guard(std::ostream& s_out) { + ut::unit_test_log.set_stream( s_out ); + } + ~logger_guard() { + ut::unit_test_log.set_stream( std::cout ); + } +}; + //____________________________________________________________________________// BOOST_TEST_CASE_TEMPLATE_FUNCTION( test0, Number ) @@ -58,11 +67,15 @@ BOOST_TEST_CASE_TEMPLATE_FUNCTION( test2, Number ) BOOST_AUTO_TEST_CASE( test0_only_2 ) { + // if an exception is thrown in the test, this object is destructed when we reach the logger + // for logging the exception. This happens for instance if the test->add throws: + // - test case aborted, null_output destructed but still refered from the logger + // - exception caught by the framework, and exception content logged + // - reference to a non-existing log stream onullstream_type null_output; + logger_guard G( null_output ); - typedef boost::mpl::list_c only_2; - ut::unit_test_log.set_stream( null_output ); - + typedef boost::mpl::list_c only_2; ut::test_suite* test = BOOST_TEST_SUITE( "" ); test->add( BOOST_TEST_CASE_TEMPLATE( test0, only_2 ) ); @@ -82,10 +95,11 @@ BOOST_AUTO_TEST_CASE( test0_only_2 ) BOOST_AUTO_TEST_CASE( test0_one_to_ten ) { onullstream_type null_output; + logger_guard G( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); typedef boost::mpl::range_c one_to_ten; - ut::unit_test_log.set_stream( null_output ); test->add( BOOST_TEST_CASE_TEMPLATE( test0, one_to_ten ) ); @@ -105,10 +119,11 @@ BOOST_AUTO_TEST_CASE( test0_one_to_ten ) BOOST_AUTO_TEST_CASE( test1_one_to_five ) { onullstream_type null_output; + logger_guard G( null_output ); + ut::test_suite* test = BOOST_TEST_SUITE( "" ); typedef boost::mpl::range_c one_to_five; - ut::unit_test_log.set_stream( null_output ); test->add( BOOST_TEST_CASE_TEMPLATE( test1, one_to_five ) ); test->p_default_status.value = ut::test_unit::RS_ENABLED; @@ -126,10 +141,10 @@ BOOST_AUTO_TEST_CASE( test1_one_to_five ) BOOST_AUTO_TEST_CASE( test2_one_to_three ) { onullstream_type null_output; + logger_guard G( null_output ); ut::test_suite* test = BOOST_TEST_SUITE( "" ); typedef boost::mpl::range_c one_to_three; - ut::unit_test_log.set_stream( null_output ); test->add( BOOST_TEST_CASE_TEMPLATE( test2, one_to_three ) ); test->p_default_status.value = ut::test_unit::RS_ENABLED; From 18d62cf85696c066e5ee01aed0977d218ad9c5af Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Tue, 2 Jan 2018 11:37:50 +0100 Subject: [PATCH 25/41] Change log and doc update --- doc/closing_chapters/change_log.qbk | 7 ++++++- doc/test_organization/typed_parametrized_tests.qbk | 11 ++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index e314c180..26c3c1b3 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -7,13 +7,17 @@ [section Change log] -[h4 Boost.Test v3.7 / boost 1.67] +[#ref_CHANGE_LOG_3_7][h4 Boost.Test v3.7 / boost 1.67] [h5 Breaking changes] * Now colour is on by default for the output streams that are either `std::cout` or `std::cerr`. This can be disabled by passing [link boost_test.utf_reference.rt_param_reference.color_output `--no_color_ouput`] (or just `--no_color`) to the command line. +* Adding test cases with the same name to the same test suite is reported as an error. This impacts + [link boost_test.tests_organization.test_cases.test_organization_templates template] and + [link boost_test.tests_organization.test_cases.param_test parametrized] test cases, as well as manually + registered tests. Make sure you have no duplicate names. [h5 New features] * Colour output on Windows @@ -24,6 +28,7 @@ # [pull_request 118] Update VxWorks support # [pull_request 121] fix compiler warning # [pull_request 122] Fix some fallthrough warnings with `gcc >= 7` +# [ticket 12597] Report tests with clashing names # [ticket 13149] Dependency decorators on parent suites [h4 Boost.Test v3.6 / boost 1.65] diff --git a/doc/test_organization/typed_parametrized_tests.qbk b/doc/test_organization/typed_parametrized_tests.qbk index 9c150ec7..62690fce 100644 --- a/doc/test_organization/typed_parametrized_tests.qbk +++ b/doc/test_organization/typed_parametrized_tests.qbk @@ -33,6 +33,11 @@ The macro __BOOST_AUTO_TEST_CASE_TEMPLATE__ requires three arguments: [bt_example example10..Test case template with automated registration..run-fail] +[warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], it is forbidden to have the same test case name + under the same test suite. For automatically registered tests, the test name is derived from the type + for which the test case is created. This indirectly means that having a duplicate of types in the + `collection_of_types` will yield an error.] + [#ref_BOOST_TEST_CASE_TEMPLATE][h4 Test case template with manual registration] One way to perform the same set of checks for a component instantiated with different template parameters is illustrated in the following example: @@ -52,7 +57,6 @@ void combined_test() } `` - There several problems/inconveniences with above approach, including: * Fatal error in one of the invocation will stop whole test case and will skip invocations with different types @@ -126,6 +130,11 @@ the sub test case. ] [bt_example example09..Manually registered test case template..run-fail] +[warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], it is forbidden to have the same test case name + under the same test suite. For manually registered tests, the test name is derived from the type + for which the test case is created. This indirectly means that having a duplicate of types in the + `collection_of_types` will yield an error.] + [endsect] [/template test cases] [/EOF] From 0d6227d4360758750db0f4c385fd0a9b50844b01 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 18 Jan 2018 09:36:57 +0100 Subject: [PATCH 26/41] Addressing build failures on mingw/windows --- include/boost/test/utils/setcolor.hpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/include/boost/test/utils/setcolor.hpp b/include/boost/test/utils/setcolor.hpp index 29758531..a37ccb88 100644 --- a/include/boost/test/utils/setcolor.hpp +++ b/include/boost/test/utils/setcolor.hpp @@ -25,7 +25,12 @@ #include #ifdef _WIN32 -#include + #include + + #if defined(__MINGW32__) && !defined(COMMON_LVB_UNDERSCORE) + // mingw badly mimicking windows.h + #define COMMON_LVB_UNDERSCORE 0x8000 + #endif #endif //____________________________________________________________________________// From 4e736b88e2bb47576bac3f1189c19ed8112ecf04 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sun, 31 Dec 2017 00:11:24 +0100 Subject: [PATCH 27/41] Documentation years update --- doc/test.qbk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/test.qbk b/doc/test.qbk index 6b998f48..4d5ed8fa 100644 --- a/doc/test.qbk +++ b/doc/test.qbk @@ -7,7 +7,7 @@ [library Boost.Test [quickbook 1.7] - [copyright 2001 - 2016 Boost.Test contributors] + [copyright 2001 - 2018 Boost.Test contributors] [id boost_test] [purpose Testing library] [license From e599a4653ed5d3e998186645f3660042f1269277 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 28 Dec 2017 22:57:18 +0100 Subject: [PATCH 28/41] Fix documentation list --- doc/runtime_configuration/runtime_config_reference.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/runtime_configuration/runtime_config_reference.qbk b/doc/runtime_configuration/runtime_config_reference.qbk index 55638157..9f807cf0 100644 --- a/doc/runtime_configuration/runtime_config_reference.qbk +++ b/doc/runtime_configuration/runtime_config_reference.qbk @@ -509,6 +509,7 @@ log_sink ::= 'stdout' | 'stderr' | filename ``` Examples: + * `--logger=HRF,all` will set the `all` log level for the `HRF` log format, and will use the default sink associated to `HRF` (`stdout`) * `--logger=JUNIT,,somefile.xml:HRF,warning` will use the default log level associated to the `JUNIT` log format, and will use the file `somefile.xml` as the log sink. It will also enable the `HRF` format with log level `warning`. The corresponding sink will be set to the `HRF` default (`stdout`). From 8ef0989de797ab23fb0e790308bb8b29ad28478e Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 28 Dec 2017 23:09:13 +0100 Subject: [PATCH 29/41] Fix JUNIT default log level --- doc/test_output/log_format.qbk | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/test_output/log_format.qbk b/doc/test_output/log_format.qbk index c166b88f..ef412f06 100644 --- a/doc/test_output/log_format.qbk +++ b/doc/test_output/log_format.qbk @@ -216,14 +216,14 @@ The [@http://junit.org/ JUNIT format] is log format supported by a wide range of This format defaults its log level to [link test_log_output_table `General information`] and its default stream to a file named after [link boost_test.tests_organization.test_suite.master_test_suite master test suite]. -The logger will attempt to not overwrite any existing output file, which is also usually understood Continuous Build tools. +The logger will attempt to not overwrite any existing output file, which is also usually understood by Continuous Build tools. This format is in fact both a log and a report format: most of the Continuous Build tools will summarize the content of a JUNIT file and show an overview of the failing/succeeding tests of a module (report format) while letting the user inspect the detailed logs (log format). -[caution The minimal log-level for the JUnit logger is `general information`. Any set-up to higher log level - will default to that minimal log-level.] +[caution The minimal log-level for the JUnit logger is [link test_log_output_table `non fatal error`]. + Any set-up to higher log level will default to that minimal log-level.] [note Until Boost 1.64, the log level was previously defaulting to `success` and was causing a heavy load on the logging part in some circumstances.] From ab9c5d734f670dbf5c65ce89a75feba4336f127b Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sat, 30 Dec 2017 23:59:35 +0100 Subject: [PATCH 30/41] Ticket 13170: BOOST_AUTO_TEST_CASE_TEMPLATE without a typedef - updating doc with an example using BOOST_IDENTITY_TYPE - reworked the template test case documentation a bit --- .../typed_parametrized_tests.qbk | 122 ++++++++++-------- 1 file changed, 69 insertions(+), 53 deletions(-) diff --git a/doc/test_organization/typed_parametrized_tests.qbk b/doc/test_organization/typed_parametrized_tests.qbk index 62690fce..b1dd7fc1 100644 --- a/doc/test_organization/typed_parametrized_tests.qbk +++ b/doc/test_organization/typed_parametrized_tests.qbk @@ -7,40 +7,10 @@ [section:test_organization_templates Template test cases] -To test a template based component it's frequently necessary to perform the same set of checks for a -component instantiated with different template parameters. The __UTF__ provides the ability to create a series of -test cases based on a list of desired types and function similar to nullary function template. This facility is -called test case template. Here are the two construction interfaces: +In order to test a template based component, it is frequently necessary to perform the same set of checks for a +component instantiated with different template parameters. -* Test case template with automated registration -* Manually registered test case template - -[#ref_BOOST_AUTO_TEST_CASE_TEMPLATE][h4 Test case template with automated registration] - -To create a test case template registered in place of implementation, employ the macro -__BOOST_AUTO_TEST_CASE_TEMPLATE__. This facility is also called ['auto test case template]. - -`` -BOOST_AUTO_TEST_CASE_TEMPLATE(test_case_name, formal_type_parameter_name, collection_of_types); -`` - -The macro __BOOST_AUTO_TEST_CASE_TEMPLATE__ requires three arguments: - -# `test_case_name` The test case template name: unique test cases template identifier -# `formal_type_parameter_name` The name of a formal template parameter: - name of the type the test case template is instantiated with -# The collection of types to instantiate test case template with: arbitrary MPL sequence - -[bt_example example10..Test case template with automated registration..run-fail] - -[warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], it is forbidden to have the same test case name - under the same test suite. For automatically registered tests, the test name is derived from the type - for which the test case is created. This indirectly means that having a duplicate of types in the - `collection_of_types` will yield an error.] - -[#ref_BOOST_TEST_CASE_TEMPLATE][h4 Test case template with manual registration] -One way to perform the same set of checks for a component instantiated with different template parameters is -illustrated in the following example: +One way to perform the same set of checks for a component instantiated with different template parameters would be: `` template @@ -63,12 +33,66 @@ There several problems/inconveniences with above approach, including: * You need to repeat function invocation manually for all the parameters you are interested in * You need two functions to implement the test -Ideally the test case template would be based on nullary function template (like single_test above). -Unfortunately function templates are neither addressable nor can be used as template parameters. To alleviate -the issue the manually registered test case template facility consists of two co-working macros: -__BOOST_TEST_CASE_TEMPLATE_FUNCTION__ and __BOOST_TEST_CASE_TEMPLATE__. Former is used to define the test case -template body, later - to create and register test cases based on it. +The __UTF__ provides a facility, the *template test case*, to create a series of +test cases based on a list of desired types and /nullary/ function. This facility comes with an +[link ref_BOOST_AUTO_TEST_CASE_TEMPLATE automatic] and +[link ref_BOOST_TEST_CASE_TEMPLATE manual] registration interface. +[tip The test case template facility is preferable to the approach in example above, since execution of each sub test +case is guarded and counted separately. It produces a better test log/results report (in example above in case of +failure you can't say which type is at fault) and allows you to test all types even if one of them causes termination of +the sub test case.] + +[#ref_BOOST_AUTO_TEST_CASE_TEMPLATE][h4 Template test case with automated registration] + +A template test case, registered automatically and in place of its implementation, is declared through the macro +__BOOST_AUTO_TEST_CASE_TEMPLATE__: + +`` +BOOST_AUTO_TEST_CASE_TEMPLATE(test_case_name, formal_type_parameter_name, collection_of_types); +`` + +The arguments are as follow: + +# `test_case_name`: the test case template name: unique test cases template identifier +# `formal_type_parameter_name`: the name of a formal template parameter: + name of the type the test case template is instantiated with +# `collection_of_types`: the collection of types to instantiate test case template with. + This is an *arbitrary MPL sequence* + +[bt_example example10..Test case template with automated registration..run-fail] + +[warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], the __UTF__ does not allow for duplicate test case name + under the same test suite. As test names are derived from the types in the `collection_of_types`, + this indirectly means that having a duplicate of types in the + `collection_of_types` will yield an error.] + +[note If you prefer having the template parameter list directly in the declaration of __BOOST_AUTO_TEST_CASE_TEMPLATE__, + you may use the macro [@www.boost.org/doc/libs/release/libs/utility/identity_type/doc/html/index.html `BOOST_IDENTITY_TYPE`]. + The previous example gives (note the double parenthesis around the MPL list): + + `` + #include + + BOOST_AUTO_TEST_CASE_TEMPLATE( + my_test, + T, + BOOST_IDENTITY_TYPE((boost::mpl::list< + int, + long, + unsigned char + >)) ) + { + BOOST_TEST( sizeof(T) == (unsigned)4 ); + } + `` +] + +[#ref_BOOST_TEST_CASE_TEMPLATE][h4 Test case template with manual registration] +To manually register template test cases, two macros should be used: + +* __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ to define the template test case body +* __BOOST_TEST_CASE_TEMPLATE__ to register the test case based on the previous declaration The macro __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ requires two arguments: @@ -100,7 +124,6 @@ void test_case_name() The only difference is that the __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ makes the test case template name usable in the template argument list. - __BOOST_TEST_CASE_TEMPLATE__ requires two arguments: # the name of the test case template and @@ -108,31 +131,24 @@ __BOOST_TEST_CASE_TEMPLATE__ requires two arguments: The names passed to both macros should be the same. - `` BOOST_TEST_CASE_TEMPLATE(test_case_name, collection_of_types); `` +[bt_example example09..Manually registered test case template..run-fail] + __BOOST_TEST_CASE_TEMPLATE__ creates an instance of the test case generator. When passed to the method [memberref boost::unit_test::test_suite::add `test_suite::add`], the generator produces a separate sub test case for each type in the supplied collection of types and registers it immediately in the test suite. Each test case is based on the test case template body instantiated with a particular test type. The names for the ['sub test cases] are deduced from the macro argument `test_case_name`. If you prefer to assign -different test case names, you need to use the underlying `make_test_case` interface instead. Both test cases creation -and registration is performed in the test module initialization function. +different test case names, you need to use the underlying [headerref boost/test/tree/test_unit.hpp `make_test_case`] interface instead. +Both test cases creation and registration is performed in the test module initialization function. -[tip The test case template facility is preferable to the approach in example above, since execution of each sub test -case is guarded and counted separately. It produces a better test log/results report (in example above in case of -failure you can't say which type is at fault) and allows you to test all types even if one of them causes termination of -the sub test case. ] - - -[bt_example example09..Manually registered test case template..run-fail] - -[warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], it is forbidden to have the same test case name - under the same test suite. For manually registered tests, the test name is derived from the type - for which the test case is created. This indirectly means that having a duplicate of types in the +[warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], the __UTF__ does not allow for duplicate test case name + under the same test suite. As test names are derived from the types in the `collection_of_types`, + this indirectly means that having a duplicate of types in the `collection_of_types` will yield an error.] [endsect] [/template test cases] From dc74e22c308af76bdd7e1c986284db4e5c31469b Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sat, 30 Dec 2017 23:35:13 +0100 Subject: [PATCH 31/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 22801167..4771a365 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -31,6 +31,7 @@ # [ticket 12597] Report tests with clashing names # [ticket 12969] Problem linking `print_helper_t` under Clang # [ticket 13149] Dependency decorators on parent suites +# [ticket 13170] `BOOST_AUTO_TEST_CASE_TEMPLATE` don't want `typedef` for list [h4 Boost.Test v3.6 / boost 1.65] From 036832069a3886f1286e4ce8a82b6d1c782e6763 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Sun, 7 Jan 2018 17:29:38 +0100 Subject: [PATCH 32/41] Some doxygen fixes --- include/boost/test/utils/named_params.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/test/utils/named_params.hpp b/include/boost/test/utils/named_params.hpp index 88b8a883..50de5bfb 100644 --- a/include/boost/test/utils/named_params.hpp +++ b/include/boost/test/utils/named_params.hpp @@ -72,7 +72,7 @@ struct is_named_param_pack > : public mpl::true // ************** param_type ************** // // ************************************************************************** // -/// param_type::type is is the type of the parameter +/// param_type::type is the type of the parameter /// corresponding to the Keyword (if parameter is present) or Default template @@ -91,7 +91,7 @@ struct param_type,Keyword,DefaultType> // ************** has_param ************** // // ************************************************************************** // -/// has_param::value is true id Params has parameter corresponding +/// has_param::value is true if Params has parameter corresponding /// to the Keyword template From 06d43a2177108f58e89aa975bd47d6af519b53f8 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Wed, 3 Jan 2018 01:26:51 +0100 Subject: [PATCH 33/41] Adding the possibility to instanciate a template test case with tuples Addresses 12092 --- .../boost/test/tree/test_case_template.hpp | 71 +++++++-- test/Jamfile.v2 | 1 + .../test_case_template-with-tuples-test.cpp | 148 ++++++++++++++++++ 3 files changed, 209 insertions(+), 11 deletions(-) create mode 100644 test/test-organization-ts/test_case_template-with-tuples-test.cpp diff --git a/include/boost/test/tree/test_case_template.hpp b/include/boost/test/tree/test_case_template.hpp index 6a1fc3e5..83a13f00 100644 --- a/include/boost/test/tree/test_case_template.hpp +++ b/include/boost/test/tree/test_case_template.hpp @@ -41,6 +41,12 @@ #include // for std::string #include // for std::list +#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \ + !defined(BOOST_NO_CXX11_HDR_TUPLE) && \ + !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) + #include +#endif + #include @@ -64,7 +70,7 @@ public: // ************** generate_test_case_4_type ************** // // ************************************************************************** // -template +template 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 -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,TestCaseTemplate> single_test_gen; - - mpl::for_each >( 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 m_test_cases; }; +template +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,TestCaseTemplate> single_test_gen; + + mpl::for_each >( 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 +class template_test_case_gen > : public template_test_case_gen_base { + + template + struct seq { }; + + template + struct gen_seq : gen_seq { }; + + template + struct gen_seq<0, Is...> : seq { }; + + template + void for_each(F &f, seq) + { + auto l = { (f(mpl::identity::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; + using this_type = template_test_case_gen; + using single_test_gen = generate_test_case_4_type; + + single_test_gen op( tc_name, tc_file, tc_line, *this ); + + this->for_each(op, gen_seq()); + } +}; + +#endif /* C++11 variadic and tuples */ + } // namespace ut_detail } // unit_test } // namespace boost diff --git a/test/Jamfile.v2 b/test/Jamfile.v2 index 414314f9..df76c7ab 100644 --- a/test/Jamfile.v2 +++ b/test/Jamfile.v2 @@ -169,6 +169,7 @@ test-suite "test-organization-ts" : [ boost.test-self-test run : test-organization-ts : parameterized_test-test ] [ boost.test-self-test run : test-organization-ts : test_case_template-test ] + [ boost.test-self-test run : test-organization-ts : test_case_template-with-tuples-test : : : : : : [ requires cxx11_hdr_tuple cxx11_auto_declarations cxx11_variadic_templates ] ] [ boost.test-self-test run : test-organization-ts : datasets-test : : : [ glob test-organization-ts/datasets-test/*.cpp ] : : : $(requirements_datasets) ] [ boost.test-self-test run : test-organization-ts : dataset-variadic_and_move_semantic-test : : : : : : $(requirements_datasets) ] [ boost.test-self-test run : test-organization-ts : test_unit-order-test ] diff --git a/test/test-organization-ts/test_case_template-with-tuples-test.cpp b/test/test-organization-ts/test_case_template-with-tuples-test.cpp new file mode 100644 index 00000000..438ef084 --- /dev/null +++ b/test/test-organization-ts/test_case_template-with-tuples-test.cpp @@ -0,0 +1,148 @@ +// (C) Copyright Raffi Enficiaud 2018. +// 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) + +// Checks the instanciation of template test cases with tuples instead of mpl::list +// See trac #12092 https://svn.boost.org/trac10/ticket/12092 +// *************************************************************************** + +// Boost.Test +#define BOOST_TEST_MODULE template_test_case_with_tuples +#include +#include +#include +#include +typedef boost::onullstream onullstream_type; + +#include +#include + +namespace ut = boost::unit_test; +namespace mpl = boost::mpl; + +#include + +struct logger_guard { + logger_guard(std::ostream& s_out) { + ut::unit_test_log.set_stream( s_out ); + } + ~logger_guard() { + ut::unit_test_log.set_stream( std::cout ); + } +}; + + +//____________________________________________________________________________// + +BOOST_TEST_CASE_TEMPLATE_FUNCTION( test0, Number ) +{ + BOOST_TEST( 2 == (int)Number::value ); +} + +BOOST_AUTO_TEST_CASE( test0_only_2 ) +{ + onullstream_type null_output; + logger_guard G(null_output); + + typedef std::tuple< mpl::integral_c > only_2; + + ut::test_suite* test = BOOST_TEST_SUITE( "" ); + + test->add( BOOST_TEST_CASE_TEMPLATE( test0, only_2 ) ); + + test->p_default_status.value = ut::test_unit::RS_ENABLED; + ut::framework::finalize_setup_phase( test->p_id ); + ut::framework::run( test ); + ut::test_results const& tr = ut::results_collector.results( test->p_id ); + + ut::unit_test_log.set_stream( std::cout ); + BOOST_TEST( tr.p_assertions_failed == 0U ); + BOOST_TEST( !tr.p_aborted ); +} + +BOOST_AUTO_TEST_CASE( test1_with_9_errors ) +{ + onullstream_type null_output; + logger_guard G(null_output); + + typedef std::tuple< + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c + > range_10; + + ut::test_suite* test = BOOST_TEST_SUITE( "" ); + + test->add( BOOST_TEST_CASE_TEMPLATE( test0, range_10 ) ); + + test->p_default_status.value = ut::test_unit::RS_ENABLED; + ut::framework::finalize_setup_phase( test->p_id ); + ut::framework::run( test ); + ut::test_results const& tr = ut::results_collector.results( test->p_id ); + + ut::unit_test_log.set_stream( std::cout ); + BOOST_TEST( tr.p_assertions_failed == 9U ); + BOOST_TEST( !tr.p_aborted ); +} + + +int counter = 0; +BOOST_TEST_CASE_TEMPLATE_FUNCTION( test_counter, Number ) +{ + BOOST_TEST( counter++ == (int)Number::value ); +} + +BOOST_AUTO_TEST_CASE( test_left_to_right_evaluation ) +{ + onullstream_type null_output; + logger_guard G(null_output); + + typedef std::tuple< + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c + > range_10; + + ut::test_suite* test = BOOST_TEST_SUITE( "" ); + + test->add( BOOST_TEST_CASE_TEMPLATE( test_counter, range_10 ) ); + + test->p_default_status.value = ut::test_unit::RS_ENABLED; + ut::framework::finalize_setup_phase( test->p_id ); + ut::framework::run( test ); + ut::test_results const& tr = ut::results_collector.results( test->p_id ); + + ut::unit_test_log.set_stream( std::cout ); + BOOST_TEST( tr.p_assertions_failed == 0U ); + BOOST_TEST( !tr.p_aborted ); +} + + +typedef std::tuple< + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c, + mpl::integral_c +> range_special; + +BOOST_AUTO_TEST_CASE_TEMPLATE(odd_or_above_5, T, range_special) { + BOOST_TEST( (T::value % 2 || T::value >= 5 ) ); +} From 3dcba76f275f0e6359f4dffdcf397b2914b34833 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 18 Jan 2018 14:48:35 +0100 Subject: [PATCH 34/41] Updating the doc --- doc/examples/example10.run-fail.cpp | 7 +++++++ doc/test_organization/typed_parametrized_tests.qbk | 7 ++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/doc/examples/example10.run-fail.cpp b/doc/examples/example10.run-fail.cpp index df6b905c..8a1cabe2 100644 --- a/doc/examples/example10.run-fail.cpp +++ b/doc/examples/example10.run-fail.cpp @@ -16,4 +16,11 @@ BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types ) { BOOST_TEST( sizeof(T) == (unsigned)4 ); } + +typedef std::tuple test_types_w_tuples; + +BOOST_AUTO_TEST_CASE_TEMPLATE( my_tuple_test, T, test_types_w_tuples ) +{ + BOOST_TEST( sizeof(T) == (unsigned)4 ); +} //] diff --git a/doc/test_organization/typed_parametrized_tests.qbk b/doc/test_organization/typed_parametrized_tests.qbk index b1dd7fc1..c1c30ef1 100644 --- a/doc/test_organization/typed_parametrized_tests.qbk +++ b/doc/test_organization/typed_parametrized_tests.qbk @@ -58,14 +58,15 @@ The arguments are as follow: # `formal_type_parameter_name`: the name of a formal template parameter: name of the type the test case template is instantiated with # `collection_of_types`: the collection of types to instantiate test case template with. - This is an *arbitrary MPL sequence* + This is an *arbitrary MPL sequence* or a sequence of types wrapped in a `std::tuple` + (since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], if supported by the compiler) [bt_example example10..Test case template with automated registration..run-fail] [warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], the __UTF__ does not allow for duplicate test case name under the same test suite. As test names are derived from the types in the `collection_of_types`, - this indirectly means that having a duplicate of types in the - `collection_of_types` will yield an error.] + this indirectly means that *having a duplicate type* in the + `collection_of_types` *yields an error*.] [note If you prefer having the template parameter list directly in the declaration of __BOOST_AUTO_TEST_CASE_TEMPLATE__, you may use the macro [@www.boost.org/doc/libs/release/libs/utility/identity_type/doc/html/index.html `BOOST_IDENTITY_TYPE`]. From 32bf0f2d0aff5d51618721e7a1b892b404f3374a Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Wed, 3 Jan 2018 01:45:50 +0100 Subject: [PATCH 35/41] Change log --- doc/closing_chapters/change_log.qbk | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 4771a365..1885ea7e 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -22,12 +22,14 @@ [h5 New features] * Colour output on Windows * Improved and clearer command line help +* `BOOST_AUTO_TEST_CASE_TEMPLATE` now accepts a sequence of types in an `std::tuple` [h5 Bugfixes and feature requests] # [pull_request 112] Deliberate-failure tests shouldn't be optimized # [pull_request 118] Update VxWorks support # [pull_request 121] fix compiler warning # [pull_request 122] Fix some fallthrough warnings with `gcc >= 7` +# [ticket 12092] Request: allow `std::tuple` typelists in `BOOST_AUTO_TEST_CASE_TEMPLATE` # [ticket 12597] Report tests with clashing names # [ticket 12969] Problem linking `print_helper_t` under Clang # [ticket 13149] Dependency decorators on parent suites From 5b6521c995ca4e5af7e5050b84852e640781a55e Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 18 Jan 2018 15:10:15 +0100 Subject: [PATCH 36/41] Fix missing includes --- include/boost/test/data/test_case.hpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/include/boost/test/data/test_case.hpp b/include/boost/test/data/test_case.hpp index 2275f90f..06f9ddd6 100644 --- a/include/boost/test/data/test_case.hpp +++ b/include/boost/test/data/test_case.hpp @@ -33,13 +33,16 @@ #include #include - #include -#include #include #include +#include +#include + +#include + #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \ && !defined(BOOST_TEST_DATASET_MAX_ARITY) # define BOOST_TEST_DATASET_MAX_ARITY 10 From 97d84abb9dcf6ce1da8167e7694f57315c7df632 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 18 Jan 2018 15:11:59 +0100 Subject: [PATCH 37/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 4771a365..fc496ab6 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -32,6 +32,7 @@ # [ticket 12969] Problem linking `print_helper_t` under Clang # [ticket 13149] Dependency decorators on parent suites # [ticket 13170] `BOOST_AUTO_TEST_CASE_TEMPLATE` don't want `typedef` for list +# [ticket 13387] Test header fails to compile [h4 Boost.Test v3.6 / boost 1.65] From ea44314e711f6b5016ac336d6fe2ca90309fdd10 Mon Sep 17 00:00:00 2001 From: Benjamin Roland Buch Date: Fri, 5 Jan 2018 13:47:47 +0100 Subject: [PATCH 38/41] prevent 2 unused parameter warnings --- include/boost/test/tools/detail/print_helper.hpp | 2 +- include/boost/test/utils/runtime/parameter.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/test/tools/detail/print_helper.hpp b/include/boost/test/tools/detail/print_helper.hpp index e95e27ab..2c6a3b5e 100644 --- a/include/boost/test/tools/detail/print_helper.hpp +++ b/include/boost/test/tools/detail/print_helper.hpp @@ -168,7 +168,7 @@ struct BOOST_TEST_DECL print_log_value { template<> struct print_log_value { // declaration and definition is here because of #12969 https://svn.boost.org/trac10/ticket/12969 - void operator()( std::ostream& ostr, std::nullptr_t t ) { + void operator()( std::ostream& ostr, std::nullptr_t /*t*/ ) { ostr << "nullptr"; } }; diff --git a/include/boost/test/utils/runtime/parameter.hpp b/include/boost/test/utils/runtime/parameter.hpp index 1389cf34..420b6026 100644 --- a/include/boost/test/utils/runtime/parameter.hpp +++ b/include/boost/test/utils/runtime/parameter.hpp @@ -270,7 +270,7 @@ protected: private: /// interface for usage/help customization - virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /* negation_prefix_ */, bool use_color = true) const + virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /*negation_prefix_*/, bool /*use_color*/ = true) const { ostr << cla_tag; } From 3218dabf76eac4316bbb2562fd81308eb4a8b952 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Thu, 18 Jan 2018 11:53:06 +0100 Subject: [PATCH 39/41] Change log --- doc/closing_chapters/change_log.qbk | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 4771a365..284660c2 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -28,6 +28,7 @@ # [pull_request 118] Update VxWorks support # [pull_request 121] fix compiler warning # [pull_request 122] Fix some fallthrough warnings with `gcc >= 7` +# [pull_request 125] Prevent 2 unused parameter warnings # [ticket 12597] Report tests with clashing names # [ticket 12969] Problem linking `print_helper_t` under Clang # [ticket 13149] Dependency decorators on parent suites From 724a839d827ec12b0ab72815e2ab9f7184c45865 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Fri, 19 Jan 2018 00:20:22 +0100 Subject: [PATCH 40/41] Fix non-initialized variable causing crash on Cygwin --- include/boost/test/impl/framework.ipp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/boost/test/impl/framework.ipp b/include/boost/test/impl/framework.ipp index 510eb29a..63073354 100644 --- a/include/boost/test/impl/framework.ipp +++ b/include/boost/test/impl/framework.ipp @@ -490,7 +490,8 @@ unsigned const TIMEOUT_EXCEEDED = static_cast( -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 ) From 285d9ddf263b9a2e7bb434aa8a0782ed2005c195 Mon Sep 17 00:00:00 2001 From: Raffi Enficiaud Date: Fri, 19 Jan 2018 09:14:30 +0100 Subject: [PATCH 41/41] Change log --- doc/closing_chapters/change_log.qbk | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/closing_chapters/change_log.qbk b/doc/closing_chapters/change_log.qbk index 4771a365..3168cc46 100644 --- a/doc/closing_chapters/change_log.qbk +++ b/doc/closing_chapters/change_log.qbk @@ -31,7 +31,8 @@ # [ticket 12597] Report tests with clashing names # [ticket 12969] Problem linking `print_helper_t` under Clang # [ticket 13149] Dependency decorators on parent suites -# [ticket 13170] `BOOST_AUTO_TEST_CASE_TEMPLATE` don't want `typedef` for list +# [ticket 13170] `BOOST_AUTO_TEST_CASE_TEMPLATE` don't want `typedef` for list +# [ticket 13407] Boost.Test appears to crash under Cygwin [h4 Boost.Test v3.6 / boost 1.65]