diff options
Diffstat (limited to 'boost/test/impl/test_tools.ipp')
-rw-r--r-- | boost/test/impl/test_tools.ipp | 431 |
1 files changed, 242 insertions, 189 deletions
diff --git a/boost/test/impl/test_tools.ipp b/boost/test/impl/test_tools.ipp index 6f5d7e9edf..03fea91605 100644 --- a/boost/test/impl/test_tools.ipp +++ b/boost/test/impl/test_tools.ipp @@ -1,4 +1,4 @@ -// (C) Copyright Gennadiy Rozental 2005-2008. +// (C) Copyright Gennadiy Rozental 2005-2014. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) @@ -16,12 +16,18 @@ #define BOOST_TEST_TEST_TOOLS_IPP_012205GER // Boost.Test -#include <boost/test/test_tools.hpp> #include <boost/test/unit_test_log.hpp> -#include <boost/test/output_test_stream.hpp> +#include <boost/test/tools/context.hpp> +#include <boost/test/tools/output_test_stream.hpp> + +#include <boost/test/tools/detail/fwd.hpp> +#include <boost/test/tools/detail/print_helper.hpp> + #include <boost/test/framework.hpp> +#include <boost/test/tree/test_unit.hpp> #include <boost/test/execution_monitor.hpp> // execution_aborted -#include <boost/test/unit_test_suite_impl.hpp> + +#include <boost/test/detail/throw_exception.hpp> // Boost #include <boost/config.hpp> @@ -33,6 +39,8 @@ #include <cctype> #include <cwchar> #include <stdexcept> +#include <vector> +#include <utility> #include <ios> // !! should we use #include <cstdarg> @@ -50,8 +58,8 @@ namespace std { using ::wcscmp; } # endif namespace boost { - namespace test_tools { +namespace tt_detail { // ************************************************************************** // // ************** print_log_value ************** // @@ -105,119 +113,78 @@ print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const* //____________________________________________________________________________// -namespace tt_detail { - // ************************************************************************** // // ************** TOOL BOX Implementation ************** // // ************************************************************************** // using ::boost::unit_test::lazy_ostream; -bool -check_impl( predicate_result const& pr, lazy_ostream const& check_descr, - const_string file_name, std::size_t line_num, - tool_level tl, check_type ct, - std::size_t num_of_args, ... ) +static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " }; +static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " }; + +template<typename OutStream> +void +format_report( OutStream& os, assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr, + tool_level tl, check_type ct, + std::size_t num_args, va_list args, + char const* prefix, char const* suffix ) { using namespace unit_test; - if( !framework::is_initialized() ) - throw std::runtime_error( "can't use testing tools before framework is initialized" ); - - if( !!pr ) - tl = PASS; - - log_level ll; - char const* prefix; - char const* suffix; - - switch( tl ) { - case PASS: - ll = log_successful_tests; - prefix = "check "; - suffix = " passed"; - break; - case WARN: - ll = log_warnings; - prefix = "condition "; - suffix = " is not satisfied"; - break; - case CHECK: - ll = log_all_errors; - prefix = "check "; - suffix = " failed"; - break; - case REQUIRE: - ll = log_fatal_errors; - prefix = "critical check "; - suffix = " failed"; - break; - default: - return true; - } - switch( ct ) { case CHECK_PRED: - unit_test_log << unit_test::log::begin( file_name, line_num ) - << ll << prefix << check_descr << suffix; - + os << prefix << assertion_descr << suffix; + if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); - - unit_test_log << unit_test::log::end(); + os << ". " << pr.message(); break; + case CHECK_BUILT_ASSERTION: { + os << prefix << assertion_descr << suffix; + + if( tl != PASS ) { + const_string details_message = pr.message(); + + if( !details_message.is_empty() ) { + os << details_message; + } + } + break; + } + case CHECK_MSG: - unit_test_log << unit_test::log::begin( file_name, line_num ) << ll; - if( tl == PASS ) - unit_test_log << prefix << "'" << check_descr << "'" << suffix; + os << prefix << "'" << assertion_descr << "'" << suffix; else - unit_test_log << check_descr; - - if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); + os << assertion_descr; - unit_test_log << unit_test::log::end(); + if( !pr.has_empty_message() ) + os << ". " << pr.message(); break; - case CHECK_EQUAL: - case CHECK_NE: - case CHECK_LT: - case CHECK_LE: - case CHECK_GT: + case CHECK_EQUAL: + case CHECK_NE: + case CHECK_LT: + case CHECK_LE: + case CHECK_GT: case CHECK_GE: { - static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " }; - static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " }; - - va_list args; - - va_start( args, num_of_args ); char const* arg1_descr = va_arg( args, char const* ); lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* ); char const* arg2_descr = va_arg( args, char const* ); lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* ); - unit_test_log << unit_test::log::begin( file_name, line_num ) - << ll << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix; + os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix; if( tl != PASS ) - unit_test_log << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ; + os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ; - va_end( args ); - if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); - - unit_test_log << unit_test::log::end(); + os << ". " << pr.message(); break; } case CHECK_CLOSE: case CHECK_CLOSE_FRACTION: { - va_list args; - - va_start( args, num_of_args ); char const* arg1_descr = va_arg( args, char const* ); lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* ); char const* arg2_descr = va_arg( args, char const* ); @@ -225,151 +192,172 @@ check_impl( predicate_result const& pr, lazy_ostream const& check_descr, /* toler_descr = */ va_arg( args, char const* ); lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* ); - unit_test_log << unit_test::log::begin( file_name, line_num ) << ll; - - unit_test_log << "difference{" << pr.message() << (ct == CHECK_CLOSE ? "%" : "") - << "} between " << arg1_descr << "{" << *arg1_val - << "} and " << arg2_descr << "{" << *arg2_val - << ( tl == PASS ? "} doesn't exceed " : "} exceeds " ) - << *toler_val; + os << "difference{" << pr.message() + << "} between " << arg1_descr << "{" << *arg1_val + << "} and " << arg2_descr << "{" << *arg2_val + << ( tl == PASS ? "} doesn't exceed " : "} exceeds " ) + << *toler_val; if( ct == CHECK_CLOSE ) - unit_test_log << "%"; - - va_end( args ); - - unit_test_log << unit_test::log::end(); + os << "%"; break; } case CHECK_SMALL: { - va_list args; - - va_start( args, num_of_args ); char const* arg1_descr = va_arg( args, char const* ); lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* ); /* toler_descr = */ va_arg( args, char const* ); lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* ); - unit_test_log << unit_test::log::begin( file_name, line_num ) << ll; - - unit_test_log << "absolute value of " << arg1_descr << "{" << *arg1_val << "}" - << ( tl == PASS ? " doesn't exceed " : " exceeds " ) - << *toler_val; + os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}" + << ( tl == PASS ? " doesn't exceed " : " exceeds " ) + << *toler_val; - va_end( args ); - if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); - - unit_test_log << unit_test::log::end(); + os << ". " << pr.message(); break; } case CHECK_PRED_WITH_ARGS: { - unit_test_log << unit_test::log::begin( file_name, line_num ) - << ll << prefix << check_descr; + std::vector< std::pair<char const*, lazy_ostream const*> > args_copy; + args_copy.reserve( num_args ); + for( std::size_t i = 0; i < num_args; ++i ) { + char const* desc = va_arg( args, char const* ); + lazy_ostream const* value = va_arg( args, lazy_ostream const* ); + args_copy.push_back( std::make_pair( desc, value ) ); + } + + os << prefix << assertion_descr; // print predicate call description - { - va_list args; - va_start( args, num_of_args ); - - unit_test_log << "( "; - for( std::size_t i = 0; i < num_of_args; ++i ) { - unit_test_log << va_arg( args, char const* ); - va_arg( args, lazy_ostream const* ); // skip argument value; - - if( i != num_of_args-1 ) - unit_test_log << ", "; - } - unit_test_log << " )" << suffix; - va_end( args ); + os << "( "; + for( std::size_t i = 0; i < num_args; ++i ) { + os << args_copy[i].first; + + if( i != num_args-1 ) + os << ", "; } - + os << " )" << suffix; + if( tl != PASS ) { - va_list args; - va_start( args, num_of_args ); - - unit_test_log << " for ( "; - for( std::size_t i = 0; i < num_of_args; ++i ) { - va_arg( args, char const* ); // skip argument description; - unit_test_log << *va_arg( args, lazy_ostream const* ); - - if( i != num_of_args-1 ) - unit_test_log << ", "; + os << " for ( "; + for( std::size_t i = 0; i < num_args; ++i ) { + os << *args_copy[i].second; + + if( i != num_args-1 ) + os << ", "; } - unit_test_log << " )"; - va_end( args ); + os << " )"; } - - if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); - unit_test_log << unit_test::log::end(); + if( !pr.has_empty_message() ) + os << ". " << pr.message(); break; } case CHECK_EQUAL_COLL: { - va_list args; - - va_start( args, num_of_args ); char const* left_begin_descr = va_arg( args, char const* ); char const* left_end_descr = va_arg( args, char const* ); char const* right_begin_descr = va_arg( args, char const* ); char const* right_end_descr = va_arg( args, char const* ); - unit_test_log << unit_test::log::begin( file_name, line_num ) - << ll << prefix - << "{ " << left_begin_descr << ", " << left_end_descr << " } == { " - << right_begin_descr << ", " << right_end_descr << " }" - << suffix; + os << prefix << "{ " << left_begin_descr << ", " << left_end_descr << " } == { " + << right_begin_descr << ", " << right_end_descr << " }" + << suffix; - va_end( args ); - if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); - - unit_test_log << unit_test::log::end(); + os << ". " << pr.message(); break; } case CHECK_BITWISE_EQUAL: { - va_list args; - - va_start( args, num_of_args ); char const* left_descr = va_arg( args, char const* ); char const* right_descr = va_arg( args, char const* ); - unit_test_log << unit_test::log::begin( file_name, line_num ) - << ll << prefix << left_descr << " =.= " << right_descr << suffix; + os << prefix << left_descr << " =.= " << right_descr << suffix; - va_end( args ); - if( !pr.has_empty_message() ) - unit_test_log << ". " << pr.message(); - - unit_test_log << unit_test::log::end(); + os << ". " << pr.message(); break; } } +} + +//____________________________________________________________________________// + +bool +report_assertion( assertion_result const& ar, + lazy_ostream const& assertion_descr, + const_string file_name, + std::size_t line_num, + tool_level tl, + check_type ct, + std::size_t num_args, ... ) +{ + using namespace unit_test; + + if( framework::current_test_case_id() == INV_TEST_UNIT_ID ) + BOOST_TEST_IMPL_THROW( + std::runtime_error( "can't use testing tools outside of test case implementation" ) ); + + if( !!ar ) + tl = PASS; + + log_level ll; + char const* prefix; + char const* suffix; switch( tl ) { case PASS: - framework::assertion_result( true ); + ll = log_successful_tests; + prefix = "check "; + suffix = " has passed"; + break; + case WARN: + ll = log_warnings; + prefix = "condition "; + suffix = " is not satisfied"; + break; + case CHECK: + ll = log_all_errors; + prefix = "check "; + suffix = " has failed"; + break; + case REQUIRE: + ll = log_fatal_errors; + prefix = "critical check "; + suffix = " has failed"; + break; + default: + return true; + } + + unit_test_log << unit_test::log::begin( file_name, line_num ) << ll; + va_list args; + va_start( args, num_args ); + + format_report( unit_test_log, ar, assertion_descr, tl, ct, num_args, args, prefix, suffix ); + + va_end( args ); + unit_test_log << unit_test::log::end(); + + switch( tl ) { + case PASS: + framework::assertion_result( AR_PASSED ); return true; case WARN: + framework::assertion_result( AR_TRIGGERED ); return false; case CHECK: - framework::assertion_result( false ); + framework::assertion_result( AR_FAILED ); return false; - + case REQUIRE: - framework::assertion_result( false ); + framework::assertion_result( AR_FAILED ); framework::test_unit_aborted( framework::current_test_case() ); - throw execution_aborted(); + BOOST_TEST_IMPL_THROW( execution_aborted() ); } return true; @@ -377,7 +365,51 @@ check_impl( predicate_result const& pr, lazy_ostream const& check_descr, //____________________________________________________________________________// -predicate_result +assertion_result +format_assertion_result( const_string expr_val, const_string details ) +{ + assertion_result res(false); + + bool starts_new_line = first_char( expr_val ) == '\n'; + + if( !starts_new_line && !expr_val.is_empty() ) + res.message().stream() << " [" << expr_val << "]"; + + if( !details.is_empty() ) { + if( first_char(details) != '[' ) + res.message().stream() << ". "; + else + res.message().stream() << " "; + + res.message().stream() << details; + } + + if( starts_new_line ) + res.message().stream() << "." << expr_val; + + return res; +} + +//____________________________________________________________________________// + +BOOST_TEST_DECL std::string +prod_report_format( assertion_result const& ar, unit_test::lazy_ostream const& assertion_descr, check_type ct, std::size_t num_args, ... ) +{ + std::ostringstream msg_buff; + + va_list args; + va_start( args, num_args ); + + format_report( msg_buff, ar, assertion_descr, CHECK, ct, num_args, args, "assertion ", " failed" ); + + va_end( args ); + + return msg_buff.str(); +} + +//____________________________________________________________________________// + +assertion_result equal_impl( char const* left, char const* right ) { return (left && right) ? std::strcmp( left, right ) == 0 : (left == right); @@ -387,7 +419,7 @@ equal_impl( char const* left, char const* right ) #if !defined( BOOST_NO_CWCHAR ) -predicate_result +assertion_result equal_impl( wchar_t const* left, wchar_t const* right ) { return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right); @@ -406,6 +438,31 @@ is_defined_impl( const_string symbol_name, const_string symbol_value ) //____________________________________________________________________________// +// ************************************************************************** // +// ************** context_frame ************** // +// ************************************************************************** // + +context_frame::context_frame( ::boost::unit_test::lazy_ostream const& context_descr ) +: m_frame_id( unit_test::framework::add_context( context_descr, true ) ) +{ +} + +//____________________________________________________________________________// + +context_frame::~context_frame() +{ + unit_test::framework::clear_context( m_frame_id ); +} + +//____________________________________________________________________________// + +context_frame::operator bool() +{ + return true; +} + +//____________________________________________________________________________// + } // namespace tt_detail // ************************************************************************** // @@ -429,7 +486,7 @@ struct output_test_stream::Impl return res; } - void check_and_fill( predicate_result& res ) + void check_and_fill( assertion_result& res ) { if( !res.p_predicate_value ) res.message() << "Output content: \"" << m_synced_string << '\"'; @@ -448,9 +505,8 @@ output_test_stream::output_test_stream( const_string pattern_file_name, bool mat m_pimpl->m_pattern.open( pattern_file_name.begin(), m ); - BOOST_WARN_MESSAGE( m_pimpl->m_pattern.is_open(), - "Can't open pattern file " << pattern_file_name - << " for " << (match_or_save ? "reading" : "writing") ); + if( !m_pimpl->m_pattern.is_open() ) + BOOST_TEST_MESSAGE( "Can't open pattern file " << pattern_file_name << " for " << (match_or_save ? "reading" : "writing") ); } m_pimpl->m_match_or_save = match_or_save; @@ -466,12 +522,12 @@ output_test_stream::~output_test_stream() //____________________________________________________________________________// -predicate_result +assertion_result output_test_stream::is_empty( bool flush_stream ) { sync(); - result_type res( m_pimpl->m_synced_string.empty() ); + assertion_result res( m_pimpl->m_synced_string.empty() ); m_pimpl->check_and_fill( res ); @@ -483,12 +539,12 @@ output_test_stream::is_empty( bool flush_stream ) //____________________________________________________________________________// -predicate_result +assertion_result output_test_stream::check_length( std::size_t length_, bool flush_stream ) { sync(); - result_type res( m_pimpl->m_synced_string.length() == length_ ); + assertion_result res( m_pimpl->m_synced_string.length() == length_ ); m_pimpl->check_and_fill( res ); @@ -500,12 +556,12 @@ output_test_stream::check_length( std::size_t length_, bool flush_stream ) //____________________________________________________________________________// -predicate_result +assertion_result output_test_stream::is_equal( const_string arg, bool flush_stream ) { sync(); - result_type res( const_string( m_pimpl->m_synced_string ) == arg ); + assertion_result res( const_string( m_pimpl->m_synced_string ) == arg ); m_pimpl->check_and_fill( res ); @@ -517,12 +573,12 @@ output_test_stream::is_equal( const_string arg, bool flush_stream ) //____________________________________________________________________________// -predicate_result +assertion_result output_test_stream::match_pattern( bool flush_stream ) { sync(); - result_type result( true ); + assertion_result result( true ); if( !m_pimpl->m_pattern.is_open() ) { result = false; @@ -548,18 +604,18 @@ output_test_stream::match_pattern( bool flush_stream ) std::string::size_type counter = suffix_size; while( --counter ) { - char c = m_pimpl->get_char(); + char c2 = m_pimpl->get_char(); if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() ) break; - result.message() << c; + result.message() << c2; } result.message() << "..."; // skip rest of the bytes. May help for further matching - m_pimpl->m_pattern.ignore( + m_pimpl->m_pattern.ignore( static_cast<std::streamsize>( m_pimpl->m_synced_string.length() - i - suffix_size) ); break; } @@ -618,11 +674,8 @@ output_test_stream::sync() //____________________________________________________________________________// } // namespace test_tools - } // namespace boost -//____________________________________________________________________________// - #include <boost/test/detail/enable_warnings.hpp> #endif // BOOST_TEST_TEST_TOOLS_IPP_012205GER |