New upstream version 8.1.0

This commit is contained in:
geos_one
2025-08-10 01:34:16 +02:00
commit c891bb7105
4398 changed files with 838833 additions and 0 deletions

View File

@@ -0,0 +1,290 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements compiler like Log formatter
// ***************************************************************************
#ifndef BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER
#define BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER
// Boost.Test
#include <boost/test/output/compiler_log_formatter.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/lazy_ostream.hpp>
#include <boost/test/utils/setcolor.hpp>
// Boost
#include <boost/version.hpp>
// STL
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
// ************************************************************************** //
// ************** compiler_log_formatter ************** //
// ************************************************************************** //
namespace {
std::string
test_phase_identifier()
{
return framework::test_in_progress() ? framework::current_test_case().full_name() : std::string( "Test setup" );
}
} // local namespace
//____________________________________________________________________________//
void
compiler_log_formatter::log_start( std::ostream& output, counter_t test_cases_amount )
{
m_color_output = runtime_config::get<bool>( runtime_config::COLOR_OUTPUT );
if( test_cases_amount > 0 )
output << "Running " << test_cases_amount << " test "
<< (test_cases_amount > 1 ? "cases" : "case") << "...\n";
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_finish( std::ostream& ostr )
{
ostr.flush();
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_build_info( std::ostream& output )
{
output << "Platform: " << BOOST_PLATFORM << '\n'
<< "Compiler: " << BOOST_COMPILER << '\n'
<< "STL : " << BOOST_STDLIB << '\n'
<< "Boost : " << BOOST_VERSION/100000 << "."
<< BOOST_VERSION/100 % 1000 << "."
<< BOOST_VERSION % 100 << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::test_unit_start( std::ostream& output, test_unit const& tu )
{
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::BLUE );
print_prefix( output, tu.p_file_name, tu.p_line_num );
output << "Entering test " << tu.p_type_name << " \"" << tu.p_name << "\"" << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::test_unit_finish( std::ostream& output, test_unit const& tu, unsigned long elapsed )
{
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::BLUE );
print_prefix( output, tu.p_file_name, tu.p_line_num );
output << "Leaving test " << tu.p_type_name << " \"" << tu.p_name << "\"";
if( elapsed > 0 ) {
output << "; testing time: ";
if( elapsed % 1000 == 0 )
output << elapsed/1000 << "ms";
else
output << elapsed << "us";
}
output << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::test_unit_skipped( std::ostream& output, test_unit const& tu, const_string reason )
{
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::YELLOW );
print_prefix( output, tu.p_file_name, tu.p_line_num );
output << "Test " << tu.p_type_name << " \"" << tu.full_name() << "\"" << " is skipped because " << reason << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_exception_start( std::ostream& output, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
{
execution_exception::location const& loc = ex.where();
print_prefix( output, loc.m_file_name, loc.m_line_num );
{
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BLINK, term_color::RED );
output << "fatal error: in \"" << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function ) << "\": "
<< ex.what();
}
if( !checkpoint_data.m_file_name.is_empty() ) {
output << '\n';
print_prefix( output, checkpoint_data.m_file_name, checkpoint_data.m_line_num );
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::CYAN );
output << "last checkpoint";
if( !checkpoint_data.m_message.empty() )
output << ": " << checkpoint_data.m_message;
}
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_exception_finish( std::ostream& output )
{
output << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_entry_start( std::ostream& output, log_entry_data const& entry_data, log_entry_types let )
{
using namespace utils;
switch( let ) {
case BOOST_UTL_ET_INFO:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
if( m_color_output )
output << setcolor( term_attr::BRIGHT, term_color::GREEN );
output << "info: ";
break;
case BOOST_UTL_ET_MESSAGE:
if( m_color_output )
output << setcolor( term_attr::BRIGHT, term_color::CYAN );
break;
case BOOST_UTL_ET_WARNING:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
if( m_color_output )
output << setcolor( term_attr::BRIGHT, term_color::YELLOW );
output << "warning: in \"" << test_phase_identifier() << "\": ";
break;
case BOOST_UTL_ET_ERROR:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
if( m_color_output )
output << setcolor( term_attr::BRIGHT, term_color::RED );
output << "error: in \"" << test_phase_identifier() << "\": ";
break;
case BOOST_UTL_ET_FATAL_ERROR:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
if( m_color_output )
output << setcolor( term_attr::BLINK, term_color::RED );
output << "fatal error: in \"" << test_phase_identifier() << "\": ";
break;
}
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_entry_value( std::ostream& output, const_string value )
{
output << value;
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_entry_value( std::ostream& output, lazy_ostream const& value )
{
output << value;
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_entry_finish( std::ostream& output )
{
if( m_color_output )
output << utils::setcolor();
output << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::print_prefix( std::ostream& output, const_string file_name, std::size_t line_num )
{
if( !file_name.empty() ) {
#ifdef __APPLE_CC__
// Xcode-compatible logging format, idea by Richard Dingwall at
// <http://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3/>.
output << file_name << ':' << line_num << ": ";
#else
output << file_name << '(' << line_num << "): ";
#endif
}
}
//____________________________________________________________________________//
void
compiler_log_formatter::entry_context_start( std::ostream& output, log_level l )
{
output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:";
}
//____________________________________________________________________________//
void
compiler_log_formatter::entry_context_finish( std::ostream& output )
{
output.flush();
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_entry_context( std::ostream& output, const_string context_descr )
{
output << "\n " << context_descr;
}
//____________________________________________________________________________//
} // namespace output
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER

View File

@@ -0,0 +1,136 @@
// (C) Copyright Gennadiy Rozental 2001.
// (C) Copyright Beman Dawes 1995-2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : main function implementation for Program Executon Monitor
// ***************************************************************************
#ifndef BOOST_TEST_CPP_MAIN_IPP_012205GER
#define BOOST_TEST_CPP_MAIN_IPP_012205GER
// Boost.Test
#include <boost/test/execution_monitor.hpp>
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
// Boost
#include <boost/cstdlib.hpp> // for exit codes
#include <boost/config.hpp> // for workarounds
// STL
#include <iostream>
#include <cstdlib> // std::getenv
#include <cstring> // std::strerror
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::getenv; using ::strerror; }
#endif
namespace {
struct cpp_main_caller {
cpp_main_caller( int (*cpp_main_func)( int argc, char* argv[] ), int argc, char** argv )
: m_cpp_main_func( cpp_main_func )
, m_argc( argc )
, m_argv( argv ) {}
int operator()() { return (*m_cpp_main_func)( m_argc, m_argv ); }
private:
// Data members
int (*m_cpp_main_func)( int argc, char* argv[] );
int m_argc;
char** m_argv;
};
} // local namespace
// ************************************************************************** //
// ************** prg_exec_monitor_main ************** //
// ************************************************************************** //
namespace boost {
int BOOST_TEST_DECL
prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char* argv[] )
{
int result = 0;
BOOST_TEST_I_TRY {
boost::unit_test::const_string p( std::getenv( "BOOST_TEST_CATCH_SYSTEM_ERRORS" ) );
::boost::execution_monitor ex_mon;
ex_mon.p_catch_system_errors.value = p != "no";
result = ex_mon.execute( cpp_main_caller( cpp_main, argc, argv ) );
if( result == 0 )
result = ::boost::exit_success;
else if( result != ::boost::exit_success ) {
std::cout << "\n**** error return code: " << result << std::endl;
result = ::boost::exit_failure;
}
}
BOOST_TEST_I_CATCH( ::boost::execution_exception, exex ) {
std::cout << "\n**** exception(" << exex.code() << "): " << exex.what() << std::endl;
result = ::boost::exit_exception_failure;
}
BOOST_TEST_I_CATCH( ::boost::system_error, ex ) {
std::cout << "\n**** failed to initialize execution monitor."
<< "\n**** expression at fault: " << ex.p_failed_exp
<< "\n**** error(" << ex.p_errno << "): " << std::strerror( ex.p_errno ) << std::endl;
result = ::boost::exit_exception_failure;
}
if( result != ::boost::exit_success ) {
std::cerr << "******** errors detected; see standard output for details ********" << std::endl;
}
else {
// Some prefer a confirming message when all is well, while others don't
// like the clutter. Use an environment variable to avoid command
// line argument modifications; for use in production programs
// that's a no-no in some organizations.
::boost::unit_test::const_string p( std::getenv( "BOOST_PRG_MON_CONFIRM" ) );
if( p != "no" ) {
std::cerr << std::flush << "no errors detected" << std::endl;
}
}
return result;
}
} // namespace boost
#if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
// ************************************************************************** //
// ************** main function for tests using lib ************** //
// ************************************************************************** //
int cpp_main( int argc, char* argv[] ); // prototype for user's cpp_main()
int BOOST_TEST_CALL_DECL
main( int argc, char* argv[] )
{
return ::boost::prg_exec_monitor_main( &cpp_main, argc, argv );
}
//____________________________________________________________________________//
#endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_CPP_MAIN_IPP_012205GER

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,202 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : unit test decorators implementation
// ***************************************************************************
#ifndef BOOST_TEST_TREE_DECORATOR_IPP_091911GER
#define BOOST_TEST_TREE_DECORATOR_IPP_091911GER
// Boost.Test
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/framework.hpp>
#if BOOST_TEST_SUPPORT_TOKEN_ITERATOR
#include <boost/test/utils/iterator/token_iterator.hpp>
#endif
#include <boost/test/detail/throw_exception.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace decorator {
// ************************************************************************** //
// ************** decorator::collector ************** //
// ************************************************************************** //
collector&
collector::operator*( base const& d )
{
m_tu_decorators.push_back( d.clone() );
return *this;
}
//____________________________________________________________________________//
void
collector::store_in( test_unit& tu )
{
tu.p_decorators.value.insert( tu.p_decorators.value.end(), m_tu_decorators.begin(), m_tu_decorators.end() );
}
//____________________________________________________________________________//
void
collector::reset()
{
m_tu_decorators.clear();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::base ************** //
// ************************************************************************** //
collector&
base::operator*() const
{
return collector::instance() * *this;
}
// ************************************************************************** //
// ************** decorator::label ************** //
// ************************************************************************** //
void
label::apply( test_unit& tu )
{
tu.add_label( m_label );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::expected_failures ************** //
// ************************************************************************** //
void
expected_failures::apply( test_unit& tu )
{
tu.increase_exp_fail( m_exp_fail );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::timeout ************** //
// ************************************************************************** //
void
timeout::apply( test_unit& tu )
{
tu.p_timeout.value = m_timeout;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::description ************** //
// ************************************************************************** //
void
description::apply( test_unit& tu )
{
tu.p_description.value += m_description;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::depends_on ************** //
// ************************************************************************** //
void
depends_on::apply( test_unit& tu )
{
#if !BOOST_TEST_SUPPORT_TOKEN_ITERATOR
BOOST_TEST_SETUP_ASSERT( false, "depends_on decorator is not supported on this platform" );
#else
utils::string_token_iterator tit( m_dependency, (utils::dropped_delimeters = "/", utils::kept_delimeters = utils::dt_none) );
test_unit* dep = &framework::master_test_suite();
while( tit != utils::string_token_iterator() ) {
BOOST_TEST_SETUP_ASSERT( dep->p_type == TUT_SUITE, std::string( "incorrect dependency specification " ) + m_dependency );
test_unit_id next_id = static_cast<test_suite*>(dep)->get( *tit );
BOOST_TEST_SETUP_ASSERT( next_id != INV_TEST_UNIT_ID,
std::string( "incorrect dependency specification " ) + m_dependency );
dep = &framework::get( next_id, TUT_ANY );
++tit;
}
tu.depends_on( dep );
#endif
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::enable_if/enabled/disabled ************** //
// ************************************************************************** //
void
enable_if_impl::apply_impl( test_unit& tu, bool condition )
{
BOOST_TEST_SETUP_ASSERT(tu.p_default_status == test_unit::RS_INHERIT,
"Can't apply multiple enabled/disabled decorators "
"to the same test unit " + tu.full_name());
tu.p_default_status.value = condition ? test_unit::RS_ENABLED : test_unit::RS_DISABLED;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::fixture ************** //
// ************************************************************************** //
void
fixture_t::apply( test_unit& tu )
{
tu.p_fixtures.value.push_back( m_impl );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::depends_on ************** //
// ************************************************************************** //
void
precondition::apply( test_unit& tu )
{
tu.add_precondition( m_precondition );
}
//____________________________________________________________________________//
} // namespace decorator
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_DECORATOR_IPP_091911GER

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,207 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : plain report formatter definition
// ***************************************************************************
#ifndef BOOST_TEST_PLAIN_REPORT_FORMATTER_IPP_020105GER
#define BOOST_TEST_PLAIN_REPORT_FORMATTER_IPP_020105GER
// Boost.Test
#include <boost/test/output/plain_report_formatter.hpp>
#include <boost/test/utils/custom_manip.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/setcolor.hpp>
// STL
#include <iomanip>
#include <boost/config/no_tr1/cmath.hpp>
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::log10; }
# endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
namespace {
typedef utils::custom_manip<struct quote_t> quote;
template<typename T>
inline std::ostream&
operator<<( utils::custom_printer<quote> const& p, T const& value )
{
*p << '"' << value << '"';
return *p;
}
//____________________________________________________________________________//
void
print_stat_value( std::ostream& ostr, counter_t v, counter_t indent, counter_t total, const_string name, const_string res )
{
if( v == 0 )
return;
if( total > 0 )
ostr << std::setw( static_cast<int>(indent) ) << "" << v << ' ' << name << ( v != 1 ? "s" : "" )
<< " out of " << total << ' ' << res << '\n';
else
ostr << std::setw( static_cast<int>(indent) ) << "" << v << ' ' << res << ' ' << name << ( v != 1 ? "s" : "" ) << '\n';
}
//____________________________________________________________________________//
} // local namespace
// ************************************************************************** //
// ************** plain_report_formatter ************** //
// ************************************************************************** //
void
plain_report_formatter::results_report_start( std::ostream& ostr )
{
m_indent = 0;
m_color_output = runtime_config::get<bool>( runtime_config::COLOR_OUTPUT );
ostr << '\n';
}
//____________________________________________________________________________//
void
plain_report_formatter::results_report_finish( std::ostream& ostr )
{
ostr.flush();
}
//____________________________________________________________________________//
void
plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream& ostr )
{
test_results const& tr = results_collector.results( tu.p_id );
const_string descr;
if( tr.passed() )
descr = "has passed";
else if( tr.p_skipped )
descr = "was skipped";
else if( tr.p_aborted )
descr = "was aborted";
else
descr = "has failed";
ostr << std::setw( static_cast<int>(m_indent) ) << ""
<< "Test " << tu.p_type_name << ' ' << quote() << tu.full_name() << ' ' << descr;
if( tr.p_skipped ) {
ostr << "\n";
m_indent += 2;
return;
}
counter_t total_assertions = tr.p_assertions_passed + tr.p_assertions_failed;
counter_t total_tc = tr.p_test_cases_passed + tr.p_test_cases_warned + tr.p_test_cases_failed + tr.p_test_cases_skipped;
if( total_assertions > 0 || total_tc > 0 || tr.p_warnings_failed > 0)
ostr << " with:";
ostr << '\n';
m_indent += 2;
print_stat_value( ostr, tr.p_test_cases_passed , m_indent, total_tc , "test case", "passed" );
print_stat_value( ostr, tr.p_test_cases_warned , m_indent, total_tc , "test case", "passed with warnings" );
print_stat_value( ostr, tr.p_test_cases_failed , m_indent, total_tc , "test case", "failed" );
print_stat_value( ostr, tr.p_test_cases_skipped, m_indent, total_tc , "test case", "skipped" );
print_stat_value( ostr, tr.p_test_cases_aborted, m_indent, total_tc , "test case", "aborted" );
print_stat_value( ostr, tr.p_assertions_passed , m_indent, total_assertions, "assertion", "passed" );
print_stat_value( ostr, tr.p_assertions_failed , m_indent, total_assertions, "assertion", "failed" );
print_stat_value( ostr, tr.p_warnings_failed , m_indent, 0 , "warning" , "failed" );
print_stat_value( ostr, tr.p_expected_failures , m_indent, 0 , "failure" , "expected" );
ostr << '\n';
}
//____________________________________________________________________________//
void
plain_report_formatter::test_unit_report_finish( test_unit const&, std::ostream& )
{
m_indent -= 2;
}
//____________________________________________________________________________//
void
plain_report_formatter::do_confirmation_report( test_unit const& tu, std::ostream& ostr )
{
test_results const& tr = results_collector.results( tu.p_id );
if( tr.passed() ) {
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, ostr, term_attr::BRIGHT, term_color::GREEN );
ostr << "*** No errors detected\n";
return;
}
BOOST_TEST_SCOPE_SETCOLOR( m_color_output, ostr, term_attr::BRIGHT, term_color::RED );
if( tr.p_skipped ) {
ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " was skipped"
<< "; see standard output for details\n";
return;
}
if( tr.p_aborted ) {
ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " was aborted"
<< "; see standard output for details\n";
}
if( tr.p_assertions_failed == 0 ) {
if( !tr.p_aborted )
ostr << "*** Errors were detected in the test " << tu.p_type_name << ' ' << quote() << tu.full_name()
<< "; see standard output for details\n";
return;
}
counter_t num_failures = tr.p_assertions_failed;
ostr << "*** " << num_failures << " failure" << ( num_failures != 1 ? "s are" : " is" ) << " detected";
if( tr.p_expected_failures > 0 )
ostr << " (" << tr.p_expected_failures << " failure" << ( tr.p_expected_failures != 1 ? "s are" : " is" ) << " expected)";
ostr << " in the test " << tu.p_type_name << " " << quote() << tu.full_name() << "\n";
}
//____________________________________________________________________________//
} // namespace output
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PLAIN_REPORT_FORMATTER_IPP_020105GER

View File

@@ -0,0 +1,185 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements simple text based progress monitor
// ***************************************************************************
#ifndef BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER
#define BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER
// Boost.Test
#include <boost/test/progress_monitor.hpp>
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/utils/setcolor.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/test_case_counter.hpp>
#include <boost/test/tree/traverse.hpp>
// Boost
#include <boost/scoped_ptr.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** progress_monitor ************** //
// ************************************************************************** //
struct progress_display {
progress_display( counter_t expected_count, std::ostream& os )
: m_os(os)
, m_count( 0 )
, m_expected_count( expected_count )
, m_next_tic_count( 0 )
, m_tic( 0 )
{
m_os << "\n0% 10 20 30 40 50 60 70 80 90 100%"
<< "\n|----|----|----|----|----|----|----|----|----|----|"
<< std::endl;
if( !m_expected_count )
m_expected_count = 1; // prevent divide by zero
}
unsigned long operator+=( unsigned long increment )
{
if( (m_count += increment) < m_next_tic_count )
return m_count;
// use of floating point ensures that both large and small counts
// work correctly. static_cast<>() is also used several places
// to suppress spurious compiler warnings.
unsigned int tics_needed = static_cast<unsigned int>(
(static_cast<double>(m_count)/m_expected_count)*50.0 );
do {
m_os << '*' << std::flush;
} while( ++m_tic < tics_needed );
m_next_tic_count = static_cast<unsigned long>((m_tic/50.0) * m_expected_count);
if( m_count == m_expected_count ) {
if( m_tic < 51 )
m_os << '*';
m_os << std::endl;
}
return m_count;
}
unsigned long operator++() { return operator+=( 1 ); }
unsigned long count() const { return m_count; }
private:
BOOST_DELETED_FUNCTION(progress_display(progress_display const&))
BOOST_DELETED_FUNCTION(progress_display& operator=(progress_display const&))
std::ostream& m_os; // may not be present in all imps
unsigned long m_count;
unsigned long m_expected_count;
unsigned long m_next_tic_count;
unsigned int m_tic;
};
namespace {
struct progress_monitor_impl {
// Constructor
progress_monitor_impl()
: m_stream( &std::cout )
, m_color_output( false )
{
}
std::ostream* m_stream;
scoped_ptr<progress_display> m_progress_display;
bool m_color_output;
};
progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; return the_inst; }
#define PM_SCOPED_COLOR() \
BOOST_TEST_SCOPE_SETCOLOR( s_pm_impl().m_color_output, *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA )
} // local namespace
//____________________________________________________________________________//
void
progress_monitor_t::test_start( counter_t test_cases_amount )
{
s_pm_impl().m_color_output = runtime_config::get<bool>( runtime_config::COLOR_OUTPUT );
PM_SCOPED_COLOR();
s_pm_impl().m_progress_display.reset( new progress_display( test_cases_amount, *s_pm_impl().m_stream ) );
}
//____________________________________________________________________________//
void
progress_monitor_t::test_aborted()
{
PM_SCOPED_COLOR();
(*s_pm_impl().m_progress_display) += s_pm_impl().m_progress_display->count();
}
//____________________________________________________________________________//
void
progress_monitor_t::test_unit_finish( test_unit const& tu, unsigned long )
{
PM_SCOPED_COLOR();
if( tu.p_type == TUT_CASE )
++(*s_pm_impl().m_progress_display);
}
//____________________________________________________________________________//
void
progress_monitor_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
{
PM_SCOPED_COLOR();
test_case_counter tcc;
traverse_test_tree( tu, tcc );
(*s_pm_impl().m_progress_display) += tcc.p_count;
}
//____________________________________________________________________________//
void
progress_monitor_t::set_stream( std::ostream& ostr )
{
s_pm_impl().m_stream = &ostr;
}
//____________________________________________________________________________//
#undef PM_SCOPED_COLOR
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER

View File

@@ -0,0 +1,276 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements Unit Test results collecting facility.
// ***************************************************************************
#ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
#define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
// Boost.Test
#include <boost/test/unit_test_log.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/tree/test_case_counter.hpp>
#include <boost/test/tree/traverse.hpp>
// Boost
#include <boost/cstdlib.hpp>
// STL
#include <map>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_results ************** //
// ************************************************************************** //
test_results::test_results()
{
clear();
}
//____________________________________________________________________________//
bool
test_results::passed() const
{
return !p_skipped &&
p_test_cases_failed == 0 &&
p_assertions_failed <= p_expected_failures &&
p_test_cases_skipped == 0 &&
!p_aborted;
}
//____________________________________________________________________________//
int
test_results::result_code() const
{
return passed() ? exit_success
: ( (p_assertions_failed > p_expected_failures || p_skipped )
? exit_test_failure
: exit_exception_failure );
}
//____________________________________________________________________________//
void
test_results::operator+=( test_results const& tr )
{
p_assertions_passed.value += tr.p_assertions_passed;
p_assertions_failed.value += tr.p_assertions_failed;
p_warnings_failed.value += tr.p_warnings_failed;
p_test_cases_passed.value += tr.p_test_cases_passed;
p_test_cases_warned.value += tr.p_test_cases_warned;
p_test_cases_failed.value += tr.p_test_cases_failed;
p_test_cases_skipped.value += tr.p_test_cases_skipped;
p_test_cases_aborted.value += tr.p_test_cases_aborted;
}
//____________________________________________________________________________//
void
test_results::clear()
{
p_assertions_passed.value = 0;
p_assertions_failed.value = 0;
p_warnings_failed.value = 0;
p_expected_failures.value = 0;
p_test_cases_passed.value = 0;
p_test_cases_warned.value = 0;
p_test_cases_failed.value = 0;
p_test_cases_skipped.value = 0;
p_test_cases_aborted.value = 0;
p_aborted.value = false;
p_skipped.value = false;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** results_collector ************** //
// ************************************************************************** //
namespace {
struct results_collector_impl {
std::map<test_unit_id,test_results> m_results_store;
};
results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
} // local namespace
//____________________________________________________________________________//
void
results_collector_t::test_start( counter_t )
{
s_rc_impl().m_results_store.clear();
}
//____________________________________________________________________________//
void
results_collector_t::test_unit_start( test_unit const& tu )
{
// init test_results entry
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
tr.clear();
tr.p_expected_failures.value = tu.p_expected_failures;
}
//____________________________________________________________________________//
class results_collect_helper : public test_tree_visitor {
public:
explicit results_collect_helper( test_results& tr, test_unit const& ts ) : m_tr( tr ), m_ts( ts ) {}
void visit( test_case const& tc )
{
test_results const& tr = results_collector.results( tc.p_id );
m_tr += tr;
if( tr.passed() ) {
if( tr.p_warnings_failed )
m_tr.p_test_cases_warned.value++;
else
m_tr.p_test_cases_passed.value++;
}
else if( tr.p_skipped )
m_tr.p_test_cases_skipped.value++;
else {
if( tr.p_aborted )
m_tr.p_test_cases_aborted.value++;
m_tr.p_test_cases_failed.value++;
}
}
bool test_suite_start( test_suite const& ts )
{
if( m_ts.p_id == ts.p_id )
return true;
m_tr += results_collector.results( ts.p_id );
return false;
}
private:
// Data members
test_results& m_tr;
test_unit const& m_ts;
};
//____________________________________________________________________________//
void
results_collector_t::test_unit_finish( test_unit const& tu, unsigned long )
{
if( tu.p_type == TUT_SUITE ) {
results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
traverse_test_tree( tu, ch );
}
else {
test_results const& tr = s_rc_impl().m_results_store[tu.p_id];
bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
if( !num_failures_match )
BOOST_TEST_MESSAGE( "Test case " << tu.full_name() << " has fewer failures than expected" );
bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
if( !check_any_assertions )
BOOST_TEST_MESSAGE( "Test case " << tu.full_name() << " did not check any assertions" );
}
}
//____________________________________________________________________________//
void
results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ )
{
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
tr.clear();
tr.p_skipped.value = true;
if( tu.p_type == TUT_SUITE ) {
test_case_counter tcc;
traverse_test_tree( tu, tcc );
tr.p_test_cases_skipped.value = tcc.p_count;
}
}
//____________________________________________________________________________//
void
results_collector_t::assertion_result( unit_test::assertion_result ar )
{
test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
switch( ar ) {
case AR_PASSED: tr.p_assertions_passed.value++; break;
case AR_FAILED: tr.p_assertions_failed.value++; break;
case AR_TRIGGERED: tr.p_warnings_failed.value++; break;
}
if( tr.p_assertions_failed == 1 )
first_failed_assertion();
}
//____________________________________________________________________________//
void
results_collector_t::exception_caught( execution_exception const& )
{
test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
tr.p_assertions_failed.value++;
}
//____________________________________________________________________________//
void
results_collector_t::test_unit_aborted( test_unit const& tu )
{
s_rc_impl().m_results_store[tu.p_id].p_aborted.value = true;
}
//____________________________________________________________________________//
test_results const&
results_collector_t::results( test_unit_id id ) const
{
return s_rc_impl().m_results_store[id];
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER

View File

@@ -0,0 +1,197 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : result reporting facilties
// ***************************************************************************
#ifndef BOOST_TEST_RESULTS_REPORTER_IPP_020105GER
#define BOOST_TEST_RESULTS_REPORTER_IPP_020105GER
// Boost.Test
#include <boost/test/results_reporter.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/output/plain_report_formatter.hpp>
#include <boost/test/output/xml_report_formatter.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/traverse.hpp>
// Boost
#include <boost/scoped_ptr.hpp>
#include <boost/io/ios_state.hpp>
typedef ::boost::io::ios_base_all_saver io_saver_type;
// STL
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace results_reporter {
// ************************************************************************** //
// ************** result reporter implementation ************** //
// ************************************************************************** //
namespace {
struct results_reporter_impl : test_tree_visitor {
// Constructor
results_reporter_impl()
: m_stream( &std::cerr )
, m_stream_state_saver( new io_saver_type( std::cerr ) )
, m_report_level( CONFIRMATION_REPORT )
, m_formatter( new output::plain_report_formatter )
{}
// test tree visitor interface implementation
void visit( test_case const& tc )
{
m_formatter->test_unit_report_start( tc, *m_stream );
m_formatter->test_unit_report_finish( tc, *m_stream );
}
bool test_suite_start( test_suite const& ts )
{
m_formatter->test_unit_report_start( ts, *m_stream );
if( m_report_level == DETAILED_REPORT && !results_collector.results( ts.p_id ).p_skipped )
return true;
m_formatter->test_unit_report_finish( ts, *m_stream );
return false;
}
void test_suite_finish( test_suite const& ts )
{
m_formatter->test_unit_report_finish( ts, *m_stream );
}
typedef scoped_ptr<io_saver_type> saver_ptr;
// Data members
std::ostream* m_stream;
saver_ptr m_stream_state_saver;
report_level m_report_level;
scoped_ptr<format> m_formatter;
};
results_reporter_impl& s_rr_impl() { static results_reporter_impl the_inst; return the_inst; }
} // local namespace
// ************************************************************************** //
// ************** report configuration ************** //
// ************************************************************************** //
void
set_level( report_level l )
{
if( l != INV_REPORT_LEVEL )
s_rr_impl().m_report_level = l;
}
//____________________________________________________________________________//
void
set_stream( std::ostream& ostr )
{
s_rr_impl().m_stream = &ostr;
s_rr_impl().m_stream_state_saver.reset( new io_saver_type( ostr ) );
}
//____________________________________________________________________________//
std::ostream&
get_stream()
{
return *s_rr_impl().m_stream;
}
//____________________________________________________________________________//
void
set_format( output_format rf )
{
switch( rf ) {
default:
case OF_CLF:
set_format( new output::plain_report_formatter );
break;
case OF_XML:
set_format( new output::xml_report_formatter );
break;
}
}
//____________________________________________________________________________//
void
set_format( results_reporter::format* f )
{
if( f )
s_rr_impl().m_formatter.reset( f );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** report initiation ************** //
// ************************************************************************** //
void
make_report( report_level l, test_unit_id id )
{
if( l == INV_REPORT_LEVEL )
l = s_rr_impl().m_report_level;
if( l == NO_REPORT )
return;
if( id == INV_TEST_UNIT_ID )
id = framework::master_test_suite().p_id;
s_rr_impl().m_stream_state_saver->restore();
report_level bkup = s_rr_impl().m_report_level;
s_rr_impl().m_report_level = l;
s_rr_impl().m_formatter->results_report_start( *s_rr_impl().m_stream );
switch( l ) {
case CONFIRMATION_REPORT:
s_rr_impl().m_formatter->do_confirmation_report( framework::get<test_unit>( id ), *s_rr_impl().m_stream );
break;
case SHORT_REPORT:
case DETAILED_REPORT:
traverse_test_tree( id, s_rr_impl() );
break;
default:
break;
}
s_rr_impl().m_formatter->results_report_finish( *s_rr_impl().m_stream );
s_rr_impl().m_report_level = bkup;
}
//____________________________________________________________________________//
} // namespace results_reporter
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_REPORTER_IPP_020105GER

View File

@@ -0,0 +1,65 @@
// (C) Copyright Gennadiy Rozental 2001.
// (C) Copyright Beman Dawes 1995-2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Implements main function for Test Execution Monitor.
// ***************************************************************************
#ifndef BOOST_TEST_TEST_MAIN_IPP_012205GER
#define BOOST_TEST_TEST_MAIN_IPP_012205GER
// Boost.Test
#include <boost/test/framework.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_suite.hpp>
// Boost
#include <boost/cstdlib.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
extern int test_main( int argc, char* argv[] ); // prototype for user's test_main()
struct test_main_caller {
test_main_caller( int argc, char** argv ) : m_argc( argc ), m_argv( argv ) {}
void operator()() {
int test_main_result = test_main( m_argc, m_argv );
// translate a test_main non-success return into a test error
BOOST_CHECK( test_main_result == 0 || test_main_result == boost::exit_success );
}
private:
// Data members
int m_argc;
char** m_argv;
};
// ************************************************************************** //
// ************** test main ************** //
// ************************************************************************** //
::boost::unit_test::test_suite*
init_unit_test_suite( int argc, char* argv[] ) {
using namespace ::boost::unit_test;
framework::master_test_suite().p_name.value = "Test Program";
framework::master_test_suite().add( BOOST_TEST_CASE( test_main_caller( argc, argv ) ) );
return 0;
}
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_MAIN_IPP_012205GER

View File

@@ -0,0 +1,680 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : supplies offline implementation for the Test Tools
// ***************************************************************************
#ifndef BOOST_TEST_TEST_TOOLS_IPP_012205GER
#define BOOST_TEST_TEST_TOOLS_IPP_012205GER
// Boost.Test
#include <boost/test/unit_test_log.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/detail/throw_exception.hpp>
// Boost
#include <boost/config.hpp>
// STL
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
#include <cwchar>
#include <stdexcept>
#include <vector>
#include <utility>
#include <ios>
// !! should we use #include <cstdarg>
#include <stdarg.h>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strcmp; using ::strlen; using ::isprint; }
#if !defined( BOOST_NO_CWCHAR )
namespace std { using ::wcscmp; }
#endif
# endif
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** print_log_value ************** //
// ************************************************************************** //
void
print_log_value<char>::operator()( std::ostream& ostr, char t )
{
if( (std::isprint)( static_cast<unsigned char>(t) ) )
ostr << '\'' << t << '\'';
else
ostr << std::hex
#if BOOST_TEST_USE_STD_LOCALE
<< std::showbase
#else
<< "0x"
#endif
<< static_cast<int>(t);
}
//____________________________________________________________________________//
void
print_log_value<unsigned char>::operator()( std::ostream& ostr, unsigned char t )
{
ostr << std::hex
// showbase is only available for new style streams:
#if BOOST_TEST_USE_STD_LOCALE
<< std::showbase
#else
<< "0x"
#endif
<< static_cast<int>(t);
}
//____________________________________________________________________________//
void
print_log_value<char const*>::operator()( std::ostream& ostr, char const* t )
{
ostr << ( t ? t : "null string" );
}
//____________________________________________________________________________//
void
print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const* t )
{
ostr << ( t ? t : L"null string" );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** TOOL BOX Implementation ************** //
// ************************************************************************** //
using ::boost::unit_test::lazy_ostream;
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;
switch( ct ) {
case CHECK_PRED:
os << prefix << assertion_descr << suffix;
if( !pr.has_empty_message() )
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:
if( tl == PASS )
os << prefix << "'" << assertion_descr << "'" << suffix;
else
os << assertion_descr;
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_GE: {
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* );
os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
if( tl != PASS )
os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_CLOSE:
case CHECK_CLOSE_FRACTION: {
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* );
/* toler_descr = */ va_arg( args, char const* );
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
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 )
os << "%";
break;
}
case CHECK_SMALL: {
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* );
os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
<< ( tl == PASS ? " doesn't exceed " : " exceeds " )
<< *toler_val;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_PRED_WITH_ARGS: {
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
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 ) {
os << " for ( ";
for( std::size_t i = 0; i < num_args; ++i ) {
os << *args_copy[i].second;
if( i != num_args-1 )
os << ", ";
}
os << " )";
}
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_EQUAL_COLL: {
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* );
os << prefix << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
<< right_begin_descr << ", " << right_end_descr << " }"
<< suffix;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_BITWISE_EQUAL: {
char const* left_descr = va_arg( args, char const* );
char const* right_descr = va_arg( args, char const* );
os << prefix << left_descr << " =.= " << right_descr << suffix;
if( !pr.has_empty_message() )
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;
BOOST_TEST_I_ASSRT( framework::current_test_case_id() != INV_TEST_UNIT_ID,
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:
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( AR_FAILED );
return false;
case REQUIRE:
framework::assertion_result( AR_FAILED );
framework::test_unit_aborted( framework::current_test_case() );
BOOST_TEST_I_THROW( execution_aborted() );
}
return true;
}
//____________________________________________________________________________//
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);
}
//____________________________________________________________________________//
#if !defined( BOOST_NO_CWCHAR )
assertion_result
equal_impl( wchar_t const* left, wchar_t const* right )
{
return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right);
}
#endif // !defined( BOOST_NO_CWCHAR )
//____________________________________________________________________________//
bool
is_defined_impl( const_string symbol_name, const_string symbol_value )
{
symbol_value.trim_left( 2 );
return symbol_name != 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
// ************************************************************************** //
// ************** output_test_stream ************** //
// ************************************************************************** //
struct output_test_stream::Impl
{
std::fstream m_pattern;
bool m_match_or_save;
bool m_text_or_binary;
std::string m_synced_string;
char get_char()
{
char res;
do {
m_pattern.get( res );
} while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );
return res;
}
void check_and_fill( assertion_result& res )
{
if( !res.p_predicate_value )
res.message() << "Output content: \"" << m_synced_string << '\"';
}
};
//____________________________________________________________________________//
output_test_stream::output_test_stream( const_string pattern_file_name, bool match_or_save, bool text_or_binary )
: m_pimpl( new Impl )
{
if( !pattern_file_name.is_empty() ) {
std::ios::openmode m = match_or_save ? std::ios::in : std::ios::out;
if( !text_or_binary )
m |= std::ios::binary;
m_pimpl->m_pattern.open( pattern_file_name.begin(), m );
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;
m_pimpl->m_text_or_binary = text_or_binary;
}
//____________________________________________________________________________//
output_test_stream::~output_test_stream()
{
delete m_pimpl;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::is_empty( bool flush_stream )
{
sync();
assertion_result res( m_pimpl->m_synced_string.empty() );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::check_length( std::size_t length_, bool flush_stream )
{
sync();
assertion_result res( m_pimpl->m_synced_string.length() == length_ );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::is_equal( const_string arg, bool flush_stream )
{
sync();
assertion_result res( const_string( m_pimpl->m_synced_string ) == arg );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::match_pattern( bool flush_stream )
{
sync();
assertion_result result( true );
if( !m_pimpl->m_pattern.is_open() ) {
result = false;
result.message() << "Pattern file can't be opened!";
}
else {
if( m_pimpl->m_match_or_save ) {
for ( std::string::size_type i = 0; i < m_pimpl->m_synced_string.length(); ++i ) {
char c = m_pimpl->get_char();
result = !m_pimpl->m_pattern.fail() &&
!m_pimpl->m_pattern.eof() &&
(m_pimpl->m_synced_string[i] == c);
if( !result ) {
std::string::size_type suffix_size = (std::min)( m_pimpl->m_synced_string.length() - i,
static_cast<std::string::size_type>(5) );
// try to log area around the mismatch
result.message() << "Mismatch at position " << i << '\n'
<< "..." << m_pimpl->m_synced_string.substr( i, suffix_size ) << "..." << '\n'
<< "..." << c;
std::string::size_type counter = suffix_size;
while( --counter ) {
char c2 = m_pimpl->get_char();
if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
break;
result.message() << c2;
}
result.message() << "...";
// skip rest of the bytes. May help for further matching
m_pimpl->m_pattern.ignore(
static_cast<std::streamsize>( m_pimpl->m_synced_string.length() - i - suffix_size) );
break;
}
}
}
else {
m_pimpl->m_pattern.write( m_pimpl->m_synced_string.c_str(),
static_cast<std::streamsize>( m_pimpl->m_synced_string.length() ) );
m_pimpl->m_pattern.flush();
}
}
if( flush_stream )
flush();
return result;
}
//____________________________________________________________________________//
void
output_test_stream::flush()
{
m_pimpl->m_synced_string.erase();
#ifndef BOOST_NO_STRINGSTREAM
str( std::string() );
#else
seekp( 0, std::ios::beg );
#endif
}
//____________________________________________________________________________//
std::size_t
output_test_stream::length()
{
sync();
return m_pimpl->m_synced_string.length();
}
//____________________________________________________________________________//
void
output_test_stream::sync()
{
#ifdef BOOST_NO_STRINGSTREAM
m_pimpl->m_synced_string.assign( str(), pcount() );
freeze( false );
#else
m_pimpl->m_synced_string = str();
#endif
}
//____________________________________________________________________________//
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_TOOLS_IPP_012205GER

View File

@@ -0,0 +1,460 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Provides core implementation for Unit Test Framework.
/// Extensions can be provided in separate files
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
// Boost.Test
#include <boost/detail/workaround.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/tree/traverse.hpp>
#include <boost/test/tree/auto_registration.hpp>
#include <boost/test/tree/global_fixture.hpp>
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/unit_test_parameters.hpp>
// Boost
#include <boost/timer.hpp>
// STL
#include <algorithm>
#include <vector>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_unit ************** //
// ************************************************************************** //
test_unit::test_unit( const_string name, const_string file_name, std::size_t line_num, test_unit_type t )
: p_type( t )
, p_type_name( t == TUT_CASE ? "case" : "suite" )
, p_file_name( file_name )
, p_line_num( line_num )
, p_id( INV_TEST_UNIT_ID )
, p_parent_id( INV_TEST_UNIT_ID )
, p_name( std::string( name.begin(), name.size() ) )
, p_timeout( 0 )
, p_expected_failures( 0 )
, p_default_status( RS_INHERIT )
, p_run_status( RS_INVALID )
, p_sibling_rank(0)
{
}
//____________________________________________________________________________//
test_unit::test_unit( const_string module_name )
: p_type( TUT_SUITE )
, p_type_name( "module" )
, p_line_num( 0 )
, p_id( INV_TEST_UNIT_ID )
, p_parent_id( INV_TEST_UNIT_ID )
, p_name( std::string( module_name.begin(), module_name.size() ) )
, p_timeout( 0 )
, p_expected_failures( 0 )
, p_default_status( RS_INHERIT )
, p_run_status( RS_INVALID )
, p_sibling_rank(0)
{
}
//____________________________________________________________________________//
test_unit::~test_unit()
{
framework::deregister_test_unit( this );
}
//____________________________________________________________________________//
void
test_unit::depends_on( test_unit* tu )
{
BOOST_TEST_SETUP_ASSERT( p_id != framework::master_test_suite().p_id,
"Can't add dependency to the master test suite" );
p_dependencies.value.push_back( tu->p_id );
}
//____________________________________________________________________________//
void
test_unit::add_precondition( precondition_t const& pc )
{
p_preconditions.value.push_back( pc );
}
//____________________________________________________________________________//
test_tools::assertion_result
test_unit::check_preconditions() const
{
BOOST_TEST_FOREACH( test_unit_id, dep_id, p_dependencies.get() ) {
test_unit const& dep = framework::get( dep_id, TUT_ANY );
if( !dep.is_enabled() ) {
test_tools::assertion_result res(false);
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" is disabled";
return res;
}
test_results const& test_rslt = unit_test::results_collector.results( dep_id );
if( !test_rslt.passed() ) {
test_tools::assertion_result res(false);
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has failed";
return res;
}
if( test_rslt.p_test_cases_skipped > 0 ) {
test_tools::assertion_result res(false);
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has skipped test cases";
return res;
}
}
BOOST_TEST_FOREACH( precondition_t, precondition, p_preconditions.get() ) {
test_tools::assertion_result res = precondition( p_id );
if( !res ) {
test_tools::assertion_result res_out(false);
res_out.message() << "precondition failed";
if( !res.has_empty_message() )
res_out.message() << ": " << res.message();
return res_out;
}
}
return true;
}
//____________________________________________________________________________//
void
test_unit::increase_exp_fail( counter_t num )
{
p_expected_failures.value += num;
if( p_parent_id != INV_TEST_UNIT_ID )
framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
}
//____________________________________________________________________________//
std::string
test_unit::full_name() const
{
if( p_parent_id == INV_TEST_UNIT_ID || p_parent_id == framework::master_test_suite().p_id )
return p_name;
std::string res = framework::get<test_suite>( p_parent_id ).full_name();
res.append("/");
res.append( p_name );
return res;
}
//____________________________________________________________________________//
void
test_unit::add_label( const_string l )
{
p_labels.value.push_back( std::string() + l );
}
//____________________________________________________________________________//
bool
test_unit::has_label( const_string l ) const
{
return std::find( p_labels->begin(), p_labels->end(), l ) != p_labels->end();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** test_case ************** //
// ************************************************************************** //
test_case::test_case( const_string name, boost::function<void ()> const& test_func )
: test_unit( name, "", 0, static_cast<test_unit_type>(type) )
, p_test_func( test_func )
{
framework::register_test_unit( this );
}
//____________________________________________________________________________//
test_case::test_case( const_string name, const_string file_name, std::size_t line_num, boost::function<void ()> const& test_func )
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
, p_test_func( test_func )
{
framework::register_test_unit( this );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** test_suite ************** //
// ************************************************************************** //
//____________________________________________________________________________//
test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
{
framework::register_test_unit( this );
}
//____________________________________________________________________________//
test_suite::test_suite( const_string module_name )
: test_unit( module_name )
{
framework::register_test_unit( this );
}
//____________________________________________________________________________//
void
test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
{
tu->p_timeout.value = timeout;
m_children.push_back( tu->p_id );
tu->p_parent_id.value = p_id;
if( tu->p_expected_failures != 0 )
increase_exp_fail( tu->p_expected_failures );
if( expected_failures )
tu->increase_exp_fail( expected_failures );
}
//____________________________________________________________________________//
void
test_suite::add( test_unit_generator const& gen, unsigned timeout )
{
test_unit* tu;
while((tu = gen.next()) != 0)
add( tu, 0, timeout );
}
//____________________________________________________________________________//
void
test_suite::add( test_unit_generator const& gen, decorator::collector& decorators )
{
test_unit* tu;
while((tu = gen.next()) != 0) {
decorators.store_in( *tu );
add( tu, 0 );
}
decorators.reset();
}
//____________________________________________________________________________//
void
test_suite::remove( test_unit_id id )
{
test_unit_id_list::iterator it = std::find( m_children.begin(), m_children.end(), id );
if( it != m_children.end() )
m_children.erase( it );
}
//____________________________________________________________________________//
test_unit_id
test_suite::get( const_string tu_name ) const
{
BOOST_TEST_FOREACH( test_unit_id, id, m_children ) {
if( tu_name == framework::get( id, ut_detail::test_id_2_unit_type( id ) ).p_name.get() )
return id;
}
return INV_TEST_UNIT_ID;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** master_test_suite ************** //
// ************************************************************************** //
master_test_suite_t::master_test_suite_t()
: test_suite( "Master Test Suite" )
, argc( 0 )
, argv( 0 )
{
p_default_status.value = RS_ENABLED;
}
// ************************************************************************** //
// ************** traverse_test_tree ************** //
// ************************************************************************** //
void
traverse_test_tree( test_case const& tc, test_tree_visitor& V, bool ignore_status )
{
if( tc.is_enabled() || ignore_status )
V.visit( tc );
}
//____________________________________________________________________________//
void
traverse_test_tree( test_suite const& suite, test_tree_visitor& V, bool ignore_status )
{
// skip disabled test suite unless we asked to ignore this condition
if( !ignore_status && !suite.is_enabled() )
return;
// Invoke test_suite_start callback
if( !V.test_suite_start( suite ) )
return;
// Recurse into children
std::size_t total_children = suite.m_children.size();
for( std::size_t i=0; i < total_children; ) {
// this statement can remove the test unit from this list
traverse_test_tree( suite.m_children[i], V, ignore_status );
if( total_children > suite.m_children.size() )
total_children = suite.m_children.size();
else
++i;
}
// Invoke test_suite_finish callback
V.test_suite_finish( suite );
}
//____________________________________________________________________________//
void
traverse_test_tree( test_unit_id id, test_tree_visitor& V, bool ignore_status )
{
if( ut_detail::test_id_2_unit_type( id ) == TUT_CASE )
traverse_test_tree( framework::get<test_case>( id ), V, ignore_status );
else
traverse_test_tree( framework::get<test_suite>( id ), V, ignore_status );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** object generators ************** //
// ************************************************************************** //
namespace ut_detail {
std::string
normalize_test_case_name( const_string name )
{
std::string norm_name( name.begin(), name.size() );
if( name[0] == '&' )
norm_name = norm_name.substr( 1 );
std::replace(norm_name.begin(), norm_name.end(), ' ', '_');
return norm_name;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** auto_test_unit_registrar ************** //
// ************************************************************************** //
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail )
{
framework::current_auto_test_suite().add( tc, exp_fail );
decorators.store_in( *tc );
decorators.reset();
}
//____________________________________________________________________________//
auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators )
{
test_unit_id id = framework::current_auto_test_suite().get( ts_name );
test_suite* ts;
if( id != INV_TEST_UNIT_ID ) {
ts = &framework::get<test_suite>( id );
BOOST_ASSERT( ts->p_parent_id == framework::current_auto_test_suite().p_id );
}
else {
ts = new test_suite( ts_name, ts_file, ts_line );
framework::current_auto_test_suite().add( ts );
}
decorators.store_in( *ts );
decorators.reset();
framework::current_auto_test_suite( ts );
}
//____________________________________________________________________________//
auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators )
{
framework::current_auto_test_suite().add( tc_gen, decorators );
}
//____________________________________________________________________________//
auto_test_unit_registrar::auto_test_unit_registrar( int )
{
framework::current_auto_test_suite( 0, false );
}
//____________________________________________________________________________//
} // namespace ut_detail
// ************************************************************************** //
// ************** global_fixture ************** //
// ************************************************************************** //
global_fixture::global_fixture()
{
framework::register_observer( *this );
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER

View File

@@ -0,0 +1,469 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implemets Unit Test Log
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
// Boost.Test
#include <boost/test/unit_test_log.hpp>
#include <boost/test/unit_test_log_formatter.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/output/compiler_log_formatter.hpp>
#include <boost/test/output/xml_log_formatter.hpp>
// Boost
#include <boost/scoped_ptr.hpp>
#include <boost/io/ios_state.hpp>
typedef ::boost::io::ios_base_all_saver io_saver_type;
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** entry_value_collector ************** //
// ************************************************************************** //
namespace ut_detail {
entry_value_collector const&
entry_value_collector::operator<<( lazy_ostream const& v ) const
{
unit_test_log << v;
return *this;
}
//____________________________________________________________________________//
entry_value_collector const&
entry_value_collector::operator<<( const_string v ) const
{
unit_test_log << v;
return *this;
}
//____________________________________________________________________________//
entry_value_collector::~entry_value_collector()
{
if( m_last )
unit_test_log << log::end();
}
//____________________________________________________________________________//
} // namespace ut_detail
// ************************************************************************** //
// ************** unit_test_log ************** //
// ************************************************************************** //
namespace {
struct unit_test_log_impl {
// Constructor
unit_test_log_impl()
: m_stream( &std::cout )
, m_stream_state_saver( new io_saver_type( std::cout ) )
, m_threshold_level( log_all_errors )
, m_log_formatter( new output::compiler_log_formatter )
{
}
// log data
typedef scoped_ptr<unit_test_log_formatter> formatter_ptr;
typedef scoped_ptr<io_saver_type> saver_ptr;
std::ostream* m_stream;
saver_ptr m_stream_state_saver;
log_level m_threshold_level;
formatter_ptr m_log_formatter;
// entry data
bool m_entry_in_progress;
bool m_entry_started;
log_entry_data m_entry_data;
// check point data
log_checkpoint_data m_checkpoint_data;
// helper functions
std::ostream& stream()
{
return *m_stream;
}
void set_checkpoint( const_string file, std::size_t line_num, const_string msg )
{
assign_op( m_checkpoint_data.m_message, msg, 0 );
m_checkpoint_data.m_file_name = file;
m_checkpoint_data.m_line_num = line_num;
}
};
unit_test_log_impl& s_log_impl() { static unit_test_log_impl the_inst; return the_inst; }
} // local namespace
//____________________________________________________________________________//
void
unit_test_log_t::test_start( counter_t test_cases_amount )
{
if( s_log_impl().m_threshold_level == log_nothing )
return;
s_log_impl().m_log_formatter->log_start( s_log_impl().stream(), test_cases_amount );
if( runtime_config::get<bool>( runtime_config::BUILD_INFO ) )
s_log_impl().m_log_formatter->log_build_info( s_log_impl().stream() );
s_log_impl().m_entry_in_progress = false;
}
//____________________________________________________________________________//
void
unit_test_log_t::test_finish()
{
if( s_log_impl().m_threshold_level == log_nothing )
return;
s_log_impl().m_log_formatter->log_finish( s_log_impl().stream() );
s_log_impl().stream().flush();
}
//____________________________________________________________________________//
void
unit_test_log_t::test_aborted()
{
BOOST_TEST_LOG_ENTRY( log_messages ) << "Test is aborted";
}
//____________________________________________________________________________//
void
unit_test_log_t::test_unit_start( test_unit const& tu )
{
if( s_log_impl().m_threshold_level > log_test_units )
return;
if( s_log_impl().m_entry_in_progress )
*this << log::end();
s_log_impl().m_log_formatter->test_unit_start( s_log_impl().stream(), tu );
}
//____________________________________________________________________________//
void
unit_test_log_t::test_unit_finish( test_unit const& tu, unsigned long elapsed )
{
if( s_log_impl().m_threshold_level > log_test_units )
return;
s_log_impl().m_checkpoint_data.clear();
if( s_log_impl().m_entry_in_progress )
*this << log::end();
s_log_impl().m_log_formatter->test_unit_finish( s_log_impl().stream(), tu, elapsed );
}
//____________________________________________________________________________//
void
unit_test_log_t::test_unit_skipped( test_unit const& tu, const_string reason )
{
if( s_log_impl().m_threshold_level > log_test_units )
return;
if( s_log_impl().m_entry_in_progress )
*this << log::end();
s_log_impl().m_log_formatter->test_unit_skipped( s_log_impl().stream(), tu, reason );
}
//____________________________________________________________________________//
void
unit_test_log_t::exception_caught( execution_exception const& ex )
{
log_level l =
ex.code() <= execution_exception::cpp_exception_error ? log_cpp_exception_errors :
(ex.code() <= execution_exception::timeout_error ? log_system_errors
: log_fatal_errors );
if( l >= s_log_impl().m_threshold_level ) {
if( s_log_impl().m_entry_in_progress )
*this << log::end();
s_log_impl().m_log_formatter->log_exception_start( s_log_impl().stream(), s_log_impl().m_checkpoint_data, ex );
log_entry_context( l );
s_log_impl().m_log_formatter->log_exception_finish( s_log_impl().stream() );
}
clear_entry_context();
}
//____________________________________________________________________________//
void
unit_test_log_t::set_checkpoint( const_string file, std::size_t line_num, const_string msg )
{
s_log_impl().set_checkpoint( file, line_num, msg );
}
//____________________________________________________________________________//
char
set_unix_slash( char in )
{
return in == '\\' ? '/' : in;
}
unit_test_log_t&
unit_test_log_t::operator<<( log::begin const& b )
{
if( s_log_impl().m_entry_in_progress )
*this << log::end();
s_log_impl().m_stream_state_saver->restore();
s_log_impl().m_entry_data.clear();
assign_op( s_log_impl().m_entry_data.m_file_name, b.m_file_name, 0 );
// normalize file name
std::transform( s_log_impl().m_entry_data.m_file_name.begin(), s_log_impl().m_entry_data.m_file_name.end(),
s_log_impl().m_entry_data.m_file_name.begin(),
&set_unix_slash );
s_log_impl().m_entry_data.m_line_num = b.m_line_num;
return *this;
}
//____________________________________________________________________________//
unit_test_log_t&
unit_test_log_t::operator<<( log::end const& )
{
if( s_log_impl().m_entry_in_progress ) {
log_entry_context( s_log_impl().m_entry_data.m_level );
s_log_impl().m_log_formatter->log_entry_finish( s_log_impl().stream() );
s_log_impl().m_entry_in_progress = false;
}
clear_entry_context();
return *this;
}
//____________________________________________________________________________//
unit_test_log_t&
unit_test_log_t::operator<<( log_level l )
{
s_log_impl().m_entry_data.m_level = l;
return *this;
}
//____________________________________________________________________________//
ut_detail::entry_value_collector
unit_test_log_t::operator()( log_level l )
{
*this << l;
return ut_detail::entry_value_collector();
}
//____________________________________________________________________________//
bool
unit_test_log_t::log_entry_start()
{
if( s_log_impl().m_entry_in_progress )
return true;
switch( s_log_impl().m_entry_data.m_level ) {
case log_successful_tests:
s_log_impl().m_log_formatter->log_entry_start( s_log_impl().stream(), s_log_impl().m_entry_data,
unit_test_log_formatter::BOOST_UTL_ET_INFO );
break;
case log_messages:
s_log_impl().m_log_formatter->log_entry_start( s_log_impl().stream(), s_log_impl().m_entry_data,
unit_test_log_formatter::BOOST_UTL_ET_MESSAGE );
break;
case log_warnings:
s_log_impl().m_log_formatter->log_entry_start( s_log_impl().stream(), s_log_impl().m_entry_data,
unit_test_log_formatter::BOOST_UTL_ET_WARNING );
break;
case log_all_errors:
case log_cpp_exception_errors:
case log_system_errors:
s_log_impl().m_log_formatter->log_entry_start( s_log_impl().stream(), s_log_impl().m_entry_data,
unit_test_log_formatter::BOOST_UTL_ET_ERROR );
break;
case log_fatal_errors:
s_log_impl().m_log_formatter->log_entry_start( s_log_impl().stream(), s_log_impl().m_entry_data,
unit_test_log_formatter::BOOST_UTL_ET_FATAL_ERROR );
break;
case log_nothing:
case log_test_units:
case invalid_log_level:
return false;
}
s_log_impl().m_entry_in_progress = true;
return true;
}
//____________________________________________________________________________//
unit_test_log_t&
unit_test_log_t::operator<<( const_string value )
{
if( s_log_impl().m_entry_data.m_level >= s_log_impl().m_threshold_level && !value.empty() && log_entry_start() )
s_log_impl().m_log_formatter->log_entry_value( s_log_impl().stream(), value );
return *this;
}
//____________________________________________________________________________//
unit_test_log_t&
unit_test_log_t::operator<<( lazy_ostream const& value )
{
if( s_log_impl().m_entry_data.m_level >= s_log_impl().m_threshold_level && !value.empty() && log_entry_start() )
s_log_impl().m_log_formatter->log_entry_value( s_log_impl().stream(), value );
return *this;
}
//____________________________________________________________________________//
void
unit_test_log_t::log_entry_context( log_level l )
{
framework::context_generator const& context = framework::get_context();
if( context.is_empty() )
return;
const_string frame;
s_log_impl().m_log_formatter->entry_context_start( s_log_impl().stream(), l );
while( !(frame=context.next()).is_empty() )
s_log_impl().m_log_formatter->log_entry_context( s_log_impl().stream(), frame );
s_log_impl().m_log_formatter->entry_context_finish( s_log_impl().stream() );
}
//____________________________________________________________________________//
void
unit_test_log_t::clear_entry_context()
{
framework::clear_context();
}
//____________________________________________________________________________//
void
unit_test_log_t::set_stream( std::ostream& str )
{
if( s_log_impl().m_entry_in_progress )
return;
s_log_impl().m_stream = &str;
s_log_impl().m_stream_state_saver.reset( new io_saver_type( str ) );
}
//____________________________________________________________________________//
void
unit_test_log_t::set_threshold_level( log_level lev )
{
if( s_log_impl().m_entry_in_progress || lev == invalid_log_level )
return;
s_log_impl().m_threshold_level = lev;
}
//____________________________________________________________________________//
void
unit_test_log_t::set_format( output_format log_format )
{
if( s_log_impl().m_entry_in_progress )
return;
switch( log_format ) {
default:
case OF_CLF:
set_formatter( new output::compiler_log_formatter );
break;
case OF_XML:
set_formatter( new output::xml_log_formatter );
break;
}
}
//____________________________________________________________________________//
void
unit_test_log_t::set_formatter( unit_test_log_formatter* the_formatter )
{
s_log_impl().m_log_formatter.reset( the_formatter );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** unit_test_log_formatter ************** //
// ************************************************************************** //
void
unit_test_log_formatter::log_entry_value( std::ostream& ostr, lazy_ostream const& value )
{
log_entry_value( ostr, (wrap_stringstream().ref() << value).str() );
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER

View File

@@ -0,0 +1,293 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : main function implementation for Unit Test Framework
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
// Boost.Test
#include <boost/test/framework.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/traverse.hpp>
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
// Boost
#include <boost/cstdlib.hpp>
// STL
#include <cstdio>
#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <set>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
// ************************************************************************** //
// ************** hrf_content_reporter ************** //
// ************************************************************************** //
struct hrf_content_reporter : test_tree_visitor {
explicit hrf_content_reporter( std::ostream& os ) : m_os( os ), m_indent( -4 ) {} // skip master test suite
private:
void report_test_unit( test_unit const& tu )
{
m_os << std::setw( m_indent ) << "" << tu.p_name;
m_os << (tu.p_default_status == test_unit::RS_ENABLED ? "*" : " ");
//m_os << '[' << tu.p_sibling_rank << ']';
if( !tu.p_description->empty() )
m_os << ": " << tu.p_description;
m_os << "\n";
}
virtual void visit( test_case const& tc ) { report_test_unit( tc ); }
virtual bool test_suite_start( test_suite const& ts )
{
if( m_indent >= 0 )
report_test_unit( ts );
m_indent += 4;
return true;
}
virtual void test_suite_finish( test_suite const& )
{
m_indent -= 4;
}
// Data members
std::ostream& m_os;
int m_indent;
};
// ************************************************************************** //
// ************** dot_content_reporter ************** //
// ************************************************************************** //
struct dot_content_reporter : test_tree_visitor {
explicit dot_content_reporter( std::ostream& os ) : m_os( os ) {}
private:
void report_test_unit( test_unit const& tu )
{
bool master_ts = tu.p_parent_id == INV_TEST_UNIT_ID;
m_os << "tu" << tu.p_id;
m_os << (master_ts ? "[shape=ellipse,peripheries=2" : "[shape=Mrecord" );
m_os << ",fontname=Helvetica";
m_os << (tu.p_default_status == test_unit::RS_ENABLED ? ",color=green" : ",color=yellow");
if( master_ts )
m_os << ",label=\"" << tu.p_name << "\"];\n";
else {
m_os << ",label=\"" << tu.p_name << "|" << tu.p_file_name << "(" << tu.p_line_num << ")";
if( tu.p_timeout > 0 )
m_os << "|timeout=" << tu.p_timeout;
if( tu.p_expected_failures != 0 )
m_os << "|expected failures=" << tu.p_expected_failures;
if( !tu.p_labels->empty() ) {
m_os << "|labels:";
BOOST_TEST_FOREACH( std::string const&, l, tu.p_labels.get() )
m_os << " @" << l;
}
m_os << "\"];\n";
}
if( !master_ts )
m_os << "tu" << tu.p_parent_id << " -> " << "tu" << tu.p_id << ";\n";
BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
test_unit const& dep = framework::get( dep_id, TUT_ANY );
m_os << "tu" << tu.p_id << " -> " << "tu" << dep.p_id << "[color=red,style=dotted,constraint=false];\n";
}
}
virtual void visit( test_case const& tc )
{
report_test_unit( tc );
}
virtual bool test_suite_start( test_suite const& ts )
{
if( ts.p_parent_id == INV_TEST_UNIT_ID )
m_os << "digraph G {rankdir=LR;\n";
report_test_unit( ts );
m_os << "{\n";
return true;
}
virtual void test_suite_finish( test_suite const& ts )
{
m_os << "}\n";
if( ts.p_parent_id == INV_TEST_UNIT_ID )
m_os << "}\n";
}
std::ostream& m_os;
};
// ************************************************************************** //
// ************** labels_collector ************** //
// ************************************************************************** //
struct labels_collector : test_tree_visitor {
std::set<std::string> const& labels() const { return m_labels; }
private:
virtual bool visit( test_unit const& tu )
{
m_labels.insert( tu.p_labels->begin(), tu.p_labels->end() );
return true;
}
// Data members
std::set<std::string> m_labels;
};
} // namespace ut_detail
// ************************************************************************** //
// ************** unit_test_main ************** //
// ************************************************************************** //
int BOOST_TEST_DECL
unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
{
int result_code = 0;
BOOST_TEST_I_TRY {
framework::init( init_func, argc, argv );
if( runtime_config::get<bool>( runtime_config::WAIT_FOR_DEBUGGER ) ) {
results_reporter::get_stream() << "Press any key to continue..." << std::endl;
std::getchar();
results_reporter::get_stream() << "Continuing..." << std::endl;
}
framework::finalize_setup_phase();
output_format list_cont = runtime_config::get<output_format>( runtime_config::LIST_CONTENT );
if( list_cont != unit_test::OF_INVALID ) {
if( list_cont == unit_test::OF_DOT ) {
ut_detail::dot_content_reporter reporter( results_reporter::get_stream() );
traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
}
else {
ut_detail::hrf_content_reporter reporter( results_reporter::get_stream() );
traverse_test_tree( framework::master_test_suite().p_id, reporter, true );
}
return boost::exit_success;
}
if( runtime_config::get<bool>( runtime_config::LIST_LABELS ) ) {
ut_detail::labels_collector collector;
traverse_test_tree( framework::master_test_suite().p_id, collector, true );
results_reporter::get_stream() << "Available labels:\n ";
std::copy( collector.labels().begin(), collector.labels().end(),
std::ostream_iterator<std::string>( results_reporter::get_stream(), "\n " ) );
results_reporter::get_stream() << "\n";
return boost::exit_success;
}
framework::run();
results_reporter::make_report();
result_code = !runtime_config::get<bool>( runtime_config::RESULT_CODE )
? boost::exit_success
: results_collector.results( framework::master_test_suite().p_id ).result_code();
}
BOOST_TEST_I_CATCH( framework::nothing_to_test, ex ) {
result_code = ex.m_result_code;
}
BOOST_TEST_I_CATCH( framework::internal_error, ex ) {
results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
result_code = boost::exit_exception_failure;
}
BOOST_TEST_I_CATCH( framework::setup_error, ex ) {
results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
result_code = boost::exit_exception_failure;
}
BOOST_TEST_I_CATCHALL() {
results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
result_code = boost::exit_exception_failure;
}
framework::shutdown();
return result_code;
}
} // namespace unit_test
} // namespace boost
#if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
// ************************************************************************** //
// ************** main function for tests using lib ************** //
// ************************************************************************** //
int BOOST_TEST_CALL_DECL
main( int argc, char* argv[] )
{
// prototype for user's unit test init function
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
extern bool init_unit_test();
boost::unit_test::init_unit_test_func init_func = &init_unit_test;
#else
extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
#endif
return ::boost::unit_test::unit_test_main( init_func, argc, argv );
}
#endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER

View File

@@ -0,0 +1,75 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements specific subclass of Executon Monitor used by Unit
// Test Framework to monitor test cases run.
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_MONITOR_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_MONITOR_IPP_012205GER
// Boost.Test
#include <boost/test/unit_test_monitor.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** unit_test_monitor ************** //
// ************************************************************************** //
unit_test_monitor_t::error_level
unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func, unsigned timeout )
{
BOOST_TEST_I_TRY {
p_catch_system_errors.value = runtime_config::get<bool>( runtime_config::CATCH_SYS_ERRORS );
p_timeout.value = timeout;
p_auto_start_dbg.value = runtime_config::get<bool>( runtime_config::AUTO_START_DBG );
p_use_alt_stack.value = runtime_config::get<bool>( runtime_config::USE_ALT_STACK );
p_detect_fp_exceptions.value = runtime_config::get<bool>( runtime_config::DETECT_FP_EXCEPT );
vexecute( func );
}
BOOST_TEST_I_CATCH( execution_exception, ex ) {
framework::exception_caught( ex );
framework::test_unit_aborted( framework::current_test_case() );
// translate execution_exception::error_code to error_level
switch( ex.code() ) {
case execution_exception::no_error: return test_ok;
case execution_exception::user_error: return unexpected_exception;
case execution_exception::cpp_exception_error: return unexpected_exception;
case execution_exception::system_error: return os_exception;
case execution_exception::timeout_error: return os_timeout;
case execution_exception::user_fatal_error:
case execution_exception::system_fatal_error: return fatal_error;
default: return unexpected_exception;
}
}
return test_ok;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_MONITOR_IPP_012205GER

View File

@@ -0,0 +1,729 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple implementation for Unit Test Framework parameter
// handling routines. May be rewritten in future to use some kind of
// command-line arguments parsing facility and environment variable handling
// facility
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
#define BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER
// Boost.Test
#include <boost/test/unit_test_parameters.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/debug.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/throw_exception.hpp>
// Boost.Runtime.Param
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/finalize.hpp>
#include <boost/test/utils/runtime/cla/parser.hpp>
#include <boost/test/utils/runtime/env/fetch.hpp>
// Boost
#include <boost/config.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#include <boost/test/detail/enable_warnings.hpp>
#include <boost/optional.hpp>
#include <boost/cstdlib.hpp>
// STL
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::getenv; using ::strncmp; using ::strcmp; }
# endif
namespace boost {
namespace unit_test {
namespace rt = boost::runtime;
// ************************************************************************** //
// ************** runtime_config ************** //
// ************************************************************************** //
namespace runtime_config {
// UTF parameters
std::string AUTO_START_DBG = "auto_start_dbg";
std::string BREAK_EXEC_PATH = "break_exec_path";
std::string BUILD_INFO = "build_info";
std::string CATCH_SYS_ERRORS = "catch_system_errors";
std::string COLOR_OUTPUT = "color_output";
std::string DETECT_FP_EXCEPT = "detect_fp_exceptions";
std::string DETECT_MEM_LEAKS = "detect_memory_leaks";
std::string LIST_CONTENT = "list_content";
std::string LIST_LABELS = "list_labels";
std::string LOG_FORMAT = "log_format";
std::string LOG_LEVEL = "log_level";
std::string LOG_SINK = "log_sink";
std::string OUTPUT_FORMAT = "output_format";
std::string RANDOM_SEED = "random";
std::string REPORT_FORMAT = "report_format";
std::string REPORT_LEVEL = "report_level";
std::string REPORT_MEM_LEAKS = "report_memory_leaks_to";
std::string REPORT_SINK = "report_sink";
std::string RESULT_CODE = "result_code";
std::string RUN_FILTERS = "run_test";
std::string SAVE_TEST_PATTERN = "save_pattern";
std::string SHOW_PROGRESS = "show_progress";
std::string USE_ALT_STACK = "use_alt_stack";
std::string WAIT_FOR_DEBUGGER = "wait_for_debugger";
std::string HELP = "help";
std::string USAGE = "usage";
//____________________________________________________________________________//
namespace {
void
register_parameters( rt::parameters_store& store )
{
rt::option auto_start_dbg( AUTO_START_DBG, (
rt::description = "Automatically attaches debugger in case of system level failure (signal).",
rt::env_var = "BOOST_TEST_AUTO_START_DBG",
rt::help = "Option " + AUTO_START_DBG + " 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 "
"different debugger. For more details on how to configure the debugger see the "
"Boost.Test debug API, specifically the function boost::debug::set_debugger."
));
auto_start_dbg.add_cla_id( "--", AUTO_START_DBG, "=" );
auto_start_dbg.add_cla_id( "-", "d", " " );
store.add( auto_start_dbg );
///////////////////////////////////////////////
rt::parameter<std::string> break_exec_path( BREAK_EXEC_PATH, (
rt::description = "For the exception safety testing allows to break at specific execution path.",
rt::env_var = "BOOST_TEST_BREAK_EXEC_PATH"
#ifndef BOOST_NO_CXX11_LAMBDAS
,
rt::callback = [](rt::cstring) {
BOOST_TEST_SETUP_ASSERT( false, "parameter break_exec_path is disabled in this release" );
}
#endif
));
break_exec_path.add_cla_id( "--", BREAK_EXEC_PATH, "=" );
store.add( break_exec_path );
rt::option build_info( BUILD_INFO, (
rt::description = "Displays library build information.",
rt::env_var = "BOOST_TEST_BUILD_INFO",
rt::help = "Option " + BUILD_INFO + " displays library build information, including: platform, "
"compiler, STL version and Boost version."
));
///////////////////////////////////////////////
build_info.add_cla_id( "--", BUILD_INFO, "=" );
build_info.add_cla_id( "-", "i", " " );
store.add( build_info );
rt::option catch_sys_errors( CATCH_SYS_ERRORS, (
rt::description = "Allows to switch between catching and ignoring system errors (signals).",
rt::env_var = "BOOST_TEST_CATCH_SYSTEM_ERRORS",
rt::default_value =
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
false,
#else
true,
#endif
rt::help = "If option " + 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
"no."
#else
"true."
#endif
));
catch_sys_errors.add_cla_id( "--", CATCH_SYS_ERRORS, "=", true );
catch_sys_errors.add_cla_id( "-", "s", " " );
store.add( catch_sys_errors );
///////////////////////////////////////////////
rt::option color_output( 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."
));
color_output.add_cla_id( "--", COLOR_OUTPUT, "=", true );
color_output.add_cla_id( "-", "x", " " );
store.add( color_output );
///////////////////////////////////////////////
rt::option detect_fp_except( DETECT_FP_EXCEPT, (
rt::description = "Enables/disables floating point exceptions traps.",
rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS",
rt::help = "Option " + DETECT_FP_EXCEPT + " enables/disables hardware traps for the floating "
"point exceptions (if supported on your platfrom)."
));
detect_fp_except.add_cla_id( "--", DETECT_FP_EXCEPT, "=", true );
store.add( detect_fp_except );
///////////////////////////////////////////////
rt::parameter<unsigned long> detect_mem_leaks( DETECT_MEM_LEAKS, (
rt::description = "Turns on/off memory leaks detection (optionally breaking on specified alloc order number).",
rt::env_var = "BOOST_TEST_DETECT_MEMORY_LEAK",
rt::default_value = 1L,
rt::optional_value = 1L,
rt::value_hint = "<alloc order number>",
rt::help = "Parameter " + DETECT_MEM_LEAKS + " 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 "
"framework to setup runtime breakpoint at Nth heap allocation. If value is "
"omitted the default value is assumed."
));
detect_mem_leaks.add_cla_id( "--", DETECT_MEM_LEAKS, "=" );
store.add( detect_mem_leaks );
///////////////////////////////////////////////
rt::enum_parameter<unit_test::output_format> list_content( LIST_CONTENT, (
rt::description = "Lists the content of test tree - names of all test suites and test cases.",
rt::env_var = "BOOST_TEST_LIST_CONTENT",
rt::default_value = OF_INVALID,
rt::optional_value = OF_CLF,
rt::enum_values<unit_test::output_format>::value =
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
{ "HRF", OF_CLF },
{ "DOT", OF_DOT }
},
#else
rt::enum_values_list<unit_test::output_format>()
( "HRF", OF_CLF )
( "DOT", OF_DOT )
,
#endif
rt::help = "Parameter " + 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 "
"framework supports two formats: human readable format (HRF) and dot graph "
"format (DOT). If value is omitted HRF value is assumed."
));
list_content.add_cla_id( "--", LIST_CONTENT, "=" );
store.add( list_content );
///////////////////////////////////////////////
rt::option list_labels( LIST_LABELS, (
rt::description = "Lists all available labels.",
rt::env_var = "BOOST_TEST_LIST_LABELS",
rt::help = "Option " + LIST_LABELS + " instructs the framework to list all the the labels "
"defined in the test module instead of executing the test cases."
));
list_labels.add_cla_id( "--", LIST_LABELS, "=" );
store.add( list_labels );
///////////////////////////////////////////////
rt::enum_parameter<unit_test::output_format> log_format( LOG_FORMAT, (
rt::description = "Specifies log format.",
rt::env_var = "BOOST_TEST_LOG_FORMAT",
rt::default_value = OF_CLF,
rt::enum_values<unit_test::output_format>::value =
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
{ "HRF", OF_CLF },
{ "CLF", OF_CLF },
{ "XML", OF_XML }
},
#else
rt::enum_values_list<unit_test::output_format>()
( "HRF", OF_CLF )
( "CLF", OF_CLF )
( "XML", OF_XML )
,
#endif
rt::help = "Parameter " + LOG_FORMAT + " allows to 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 "
"format is similar to compiler error format. Alternatively you can specify XML "
"as log format. This format is easier to process by testing automation tools."
));
log_format.add_cla_id( "--", LOG_FORMAT, "=" );
log_format.add_cla_id( "-", "f", " " );
store.add( log_format );
///////////////////////////////////////////////
rt::enum_parameter<unit_test::log_level> log_level( LOG_LEVEL, (
rt::description = "Specifies log level.",
rt::env_var = "BOOST_TEST_LOG_LEVEL",
rt::default_value = log_all_errors,
rt::enum_values<unit_test::log_level>::value =
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
{ "all" , log_successful_tests },
{ "success" , log_successful_tests },
{ "test_suite" , log_test_units },
{ "unit_scope" , log_test_units },
{ "message" , log_messages },
{ "warning" , log_warnings },
{ "error" , log_all_errors },
{ "cpp_exception" , log_cpp_exception_errors },
{ "system_error" , log_system_errors },
{ "fatal_error" , log_fatal_errors },
{ "nothing" , log_nothing }
},
#else
rt::enum_values_list<unit_test::log_level>()
( "all" , log_successful_tests )
( "success" , log_successful_tests )
( "test_suite" , log_test_units )
( "unit_scope" , log_test_units )
( "message" , log_messages )
( "warning" , log_warnings )
( "error" , log_all_errors )
( "cpp_exception" , log_cpp_exception_errors )
( "system_error" , log_system_errors )
( "fatal_error" , log_fatal_errors )
( "nothing" , log_nothing )
,
#endif
rt::help = "Parameter " + LOG_LEVEL + " allows to set the framework's log level. "
"Log level defines the verbosity of testing log produced by a testing "
"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 "
"is reported to a testing log stream."
));
log_level.add_cla_id( "--", LOG_LEVEL, "=" );
log_level.add_cla_id( "-", "l", " " );
store.add( log_level );
///////////////////////////////////////////////
rt::parameter<std::string> log_sink( LOG_SINK, (
rt::description = "Specifies log sink: stdout(default), stderr or file name.",
rt::env_var = "BOOST_TEST_LOG_SINK",
rt::value_hint = "<stderr|stdout|file name>",
rt::help = "Parameter " + LOG_SINK + " allows to set the log sink - location "
"where we report the log to, thus it allows to easily redirect the "
"test logs to file or standard streams. By default testing log is "
"directed to standard output."
));
log_sink.add_cla_id( "--", LOG_SINK, "=" );
log_sink.add_cla_id( "-", "k", " " );
store.add( log_sink );
///////////////////////////////////////////////
rt::enum_parameter<unit_test::output_format> output_format( OUTPUT_FORMAT, (
rt::description = "Specifies output format (both log and report).",
rt::env_var = "BOOST_TEST_OUTPUT_FORMAT",
rt::enum_values<unit_test::output_format>::value =
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
{ "HRF", OF_CLF },
{ "CLF", OF_CLF },
{ "XML", OF_XML }
},
#else
rt::enum_values_list<unit_test::output_format>()
( "HRF", OF_CLF )
( "CLF", OF_CLF )
( "XML", OF_XML )
,
#endif
rt::help = "Parameter " + OUTPUT_FORMAT + " combines an effect of " + REPORT_FORMAT +
" and " + 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 "
"have a default value. The only acceptable values are string names of "
"output formats: HRF - human readable format and XML - XML formats for "
"automation tools processing."
));
output_format.add_cla_id( "--", OUTPUT_FORMAT, "=" );
output_format.add_cla_id( "-", "o", " " );
store.add( output_format );
///////////////////////////////////////////////
rt::parameter<unsigned> random_seed( RANDOM_SEED, (
rt::description = "Allows to switch between sequential and random order of test units execution."
" Optionally allows to specify concrete seed for random number generator.",
rt::env_var = "BOOST_TEST_RANDOM",
rt::default_value = 0U,
rt::optional_value = 1U,
rt::value_hint = "<seed>",
rt::help = "Parameter " + 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 "
"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."
));
random_seed.add_cla_id( "--", RANDOM_SEED, "=" );
store.add( random_seed );
///////////////////////////////////////////////
rt::enum_parameter<unit_test::output_format> report_format( REPORT_FORMAT, (
rt::description = "Specifies report format.",
rt::env_var = "BOOST_TEST_REPORT_FORMAT",
rt::default_value = OF_CLF,
rt::enum_values<unit_test::output_format>::value =
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
{ "HRF", OF_CLF },
{ "CLF", OF_CLF },
{ "XML", OF_XML }
},
#else
rt::enum_values_list<unit_test::output_format>()
( "HRF", OF_CLF )
( "CLF", OF_CLF )
( "XML", OF_XML )
,
#endif
rt::help = "Parameter " + REPORT_FORMAT + " allows to 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 "
"specify XML as report format. This format is easier to process by testing "
"automation tools."
));
report_format.add_cla_id( "--", REPORT_FORMAT, "=" );
report_format.add_cla_id( "-", "m", " " );
store.add( report_format );
///////////////////////////////////////////////
rt::enum_parameter<unit_test::report_level> report_level( REPORT_LEVEL, (
rt::description = "Specifies report level.",
rt::env_var = "BOOST_TEST_REPORT_LEVEL",
rt::default_value = CONFIRMATION_REPORT,
rt::enum_values<unit_test::report_level>::value =
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
{
{ "confirm", CONFIRMATION_REPORT },
{ "short", SHORT_REPORT },
{ "detailed", DETAILED_REPORT },
{ "no", NO_REPORT }
},
#else
rt::enum_values_list<unit_test::report_level>()
( "confirm", CONFIRMATION_REPORT )
( "short", SHORT_REPORT )
( "detailed", DETAILED_REPORT )
( "no", NO_REPORT )
,
#endif
rt::help = "Parameter " + 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."
));
report_level.add_cla_id( "--", REPORT_LEVEL, "=" );
report_level.add_cla_id( "-", "r", " " );
store.add( report_level );
///////////////////////////////////////////////
rt::parameter<std::string> report_mem_leaks( REPORT_MEM_LEAKS, (
rt::description = "File where to report memory leaks to.",
rt::env_var = "BOOST_TEST_REPORT_MEMORY_LEAKS_TO",
rt::default_value = std::string(),
rt::value_hint = "<file name>",
rt::help = "Parameter " + REPORT_MEM_LEAKS + " allows to specify a file where to report "
"memory leaks to. The parameter does not have default value. If it is not specified, "
"memory leaks (if any) are reported to the standard error stream."
));
report_mem_leaks.add_cla_id( "--", REPORT_MEM_LEAKS, "=" );
store.add( report_mem_leaks );
///////////////////////////////////////////////
rt::parameter<std::string> report_sink( REPORT_SINK, (
rt::description = "Specifies report sink: stderr(default), stdout or file name.",
rt::env_var = "BOOST_TEST_REPORT_SINK",
rt::value_hint = "<stderr|stdout|file name>",
rt::help = "Parameter " + 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 "
"standard error stream."
));
report_sink.add_cla_id( "--", REPORT_SINK, "=" );
report_sink.add_cla_id( "-", "e", " " );
store.add( report_sink );
///////////////////////////////////////////////
rt::option result_code( RESULT_CODE, (
rt::description = "Disables test modules's result code generation.",
rt::env_var = "BOOST_TEST_RESULT_CODE",
rt::default_value = true,
rt::help = "The 'no' argument value for the parameter " + RESULT_CODE + " instructs the "
"framework to always return zero result code. This can be used for test programs "
"executed within IDE. By default this parameter has value 'yes'."
));
result_code.add_cla_id( "--", RESULT_CODE, "=", true );
result_code.add_cla_id( "-", "c", " " );
store.add( result_code );
///////////////////////////////////////////////
rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( RUN_FILTERS, (
rt::description = "Filters, which test units to include or exclude from test module execution.",
rt::env_var = "BOOST_TEST_RUN_FILTERS",
rt::value_hint = "<test unit filter>",
rt::help = "Parameter " + RUN_FILTERS + " allows to filter which test units to execute during "
"testing. 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 "
"enabling/disabling test units at compile time. These settings identify the default "
"set of test units to run. Parameter " + RUN_FILTERS + " is used to change this default. "
"This parameter is repeatable, so you can specify more than one filter if necessary."
));
tests_to_run.add_cla_id( "--", RUN_FILTERS, "=" );
tests_to_run.add_cla_id( "-", "t", " " );
store.add( tests_to_run );
///////////////////////////////////////////////
rt::option save_test_pattern( SAVE_TEST_PATTERN, (
rt::description = "Allows to switch between saving or matching test pattern file.",
rt::env_var = "BOOST_TEST_SAVE_PATTERN",
rt::help = "Parameter " + SAVE_TEST_PATTERN + " facilitates switching mode of operation for "
"testing output streams.\n\nThis parameter serves no particular purpose within the "
"framework itself. It can be used by test modules relying on output_test_stream to "
"implement testing logic. Default mode is 'match' (false)."
));
save_test_pattern.add_cla_id( "--", SAVE_TEST_PATTERN, "=" );
store.add( save_test_pattern );
///////////////////////////////////////////////
rt::option show_progress( SHOW_PROGRESS, (
rt::description = "Turns on progress display.",
rt::env_var = "BOOST_TEST_SHOW_PROGRESS",
rt::help = "Parameter " + SHOW_PROGRESS + " instructs the framework to display test progress "
"information. By default the test progress is not shown."
));
show_progress.add_cla_id( "--", SHOW_PROGRESS, "=" );
show_progress.add_cla_id( "-", "p", " " );
store.add( show_progress );
///////////////////////////////////////////////
rt::option use_alt_stack( USE_ALT_STACK, (
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 " + 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."
));
use_alt_stack.add_cla_id( "--", USE_ALT_STACK, "=", true );
store.add( use_alt_stack );
///////////////////////////////////////////////
rt::option wait_for_debugger( 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 " + 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."
));
wait_for_debugger.add_cla_id( "--", WAIT_FOR_DEBUGGER, "=" );
wait_for_debugger.add_cla_id( "-", "w", " " );
store.add( wait_for_debugger );
///////////////////////////////////////////////
rt::parameter<std::string> help( HELP, (
rt::description = "Help for framework parameters.",
rt::optional_value = std::string(),
rt::value_hint = "<parameter name>",
rt::help = "Parameter " + 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 "
"or ambiguous error is reported. If argument value is absent, a summary of all "
"framework's parameter is displayed."
));
help.add_cla_id( "--", HELP, "=" );
store.add( help );
///////////////////////////////////////////////
rt::option usage( USAGE, (
rt::description = "Short message explaining usage of Boost.Test parameters."
));
usage.add_cla_id( "-", "?", " " );
store.add( usage );
}
static rt::arguments_store s_arguments_store;
static rt::parameters_store s_parameters_store;
//____________________________________________________________________________//
} // local namespace
void
init( int& argc, char** argv )
{
shared_ptr<rt::cla::parser> parser;
BOOST_TEST_I_TRY {
// Initialize parameters list
if( s_parameters_store.is_empty() )
register_parameters( s_parameters_store );
// Clear up arguments store just in case (of multiple init invocations)
s_arguments_store.clear();
// Parse CLA they take precedence over environment
parser.reset( new rt::cla::parser( s_parameters_store, (rt::end_of_params = "--", rt::negation_prefix = "no_") ) );
argc = parser->parse( argc, argv, s_arguments_store );
// Try to fetch missing arguments from environment
rt::env::fetch_absent( s_parameters_store, s_arguments_store );
// Set arguments to default values if defined and perform all the validations
rt::finalize_arguments( s_parameters_store, s_arguments_store );
// Report help if requested
if( runtime_config::get<bool>( USAGE ) ) {
parser->usage( std::cerr );
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
}
else if( s_arguments_store.has( HELP ) ) {
parser->help( std::cerr, s_parameters_store, runtime_config::get<std::string>( HELP ) );
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
}
// A bit of business logic: output_format takes precedence over log/report formats
if( s_arguments_store.has( OUTPUT_FORMAT ) ) {
unit_test::output_format of = s_arguments_store.get<unit_test::output_format>( OUTPUT_FORMAT );
s_arguments_store.set( REPORT_FORMAT, of );
s_arguments_store.set( LOG_FORMAT, of );
}
}
BOOST_TEST_I_CATCH( rt::init_error, ex ) {
BOOST_TEST_SETUP_ASSERT( false, ex.msg );
}
BOOST_TEST_I_CATCH( rt::ambiguous_param, ex ) {
std::cerr << ex.msg << "\n Did you mean one of these?\n";
BOOST_TEST_FOREACH( rt::cstring, name, ex.m_amb_candidates )
std::cerr << " " << name << "\n";
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) );
}
BOOST_TEST_I_CATCH( rt::unrecognized_param, ex ) {
std::cerr << ex.msg << "\n";
if( !ex.m_typo_candidates.empty() ) {
std::cerr << " Did you mean one of these?\n";
BOOST_TEST_FOREACH( rt::cstring, name, ex.m_typo_candidates )
std::cerr << " " << name << "\n";
}
else if( parser ) {
std::cerr << "\n";
parser->usage( std::cerr );
}
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) );
}
BOOST_TEST_I_CATCH( rt::input_error, ex ) {
std::cerr << ex.msg << "\n\n";
if( parser )
parser->usage( std::cerr, ex.param_name );
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_exception_failure ) );
}
}
//____________________________________________________________________________//
rt::arguments_store const&
argument_store()
{
return s_arguments_store;
}
//____________________________________________________________________________//
bool
save_pattern()
{
return runtime_config::get<bool>( SAVE_TEST_PATTERN );
}
//____________________________________________________________________________//
} // namespace runtime_config
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_IPP_012205GER

View File

@@ -0,0 +1,223 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements OF_XML Log formatter
// ***************************************************************************
#ifndef BOOST_TEST_XML_LOG_FORMATTER_IPP_020105GER
#define BOOST_TEST_XML_LOG_FORMATTER_IPP_020105GER
// Boost.Test
#include <boost/test/output/xml_log_formatter.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/xml_printer.hpp>
// Boost
#include <boost/version.hpp>
// STL
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
static const_string tu_type_name( test_unit const& tu )
{
return tu.p_type == TUT_CASE ? "TestCase" : "TestSuite";
}
// ************************************************************************** //
// ************** xml_log_formatter ************** //
// ************************************************************************** //
void
xml_log_formatter::log_start( std::ostream& ostr, counter_t )
{
ostr << "<TestLog>";
}
//____________________________________________________________________________//
void
xml_log_formatter::log_finish( std::ostream& ostr )
{
ostr << "</TestLog>";
}
//____________________________________________________________________________//
void
xml_log_formatter::log_build_info( std::ostream& ostr )
{
ostr << "<BuildInfo"
<< " platform" << utils::attr_value() << BOOST_PLATFORM
<< " compiler" << utils::attr_value() << BOOST_COMPILER
<< " stl" << utils::attr_value() << BOOST_STDLIB
<< " boost=\"" << BOOST_VERSION/100000 << "."
<< BOOST_VERSION/100 % 1000 << "."
<< BOOST_VERSION % 100 << '\"'
<< "/>";
}
//____________________________________________________________________________//
void
xml_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu )
{
ostr << "<" << tu_type_name( tu ) << " name" << utils::attr_value() << tu.p_name.get();
if( !tu.p_file_name.empty() )
ostr << BOOST_TEST_L( " file" ) << utils::attr_value() << tu.p_file_name
<< BOOST_TEST_L( " line" ) << utils::attr_value() << tu.p_line_num;
ostr << ">";
}
//____________________________________________________________________________//
void
xml_log_formatter::test_unit_finish( std::ostream& ostr, test_unit const& tu, unsigned long elapsed )
{
if( tu.p_type == TUT_CASE )
ostr << "<TestingTime>" << elapsed << "</TestingTime>";
ostr << "</" << tu_type_name( tu ) << ">";
}
//____________________________________________________________________________//
void
xml_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu, const_string reason )
{
ostr << "<" << tu_type_name( tu )
<< " name" << utils::attr_value() << tu.p_name
<< " skipped" << utils::attr_value() << "yes"
<< " reason" << utils::attr_value() << reason
<< "/>";
}
//____________________________________________________________________________//
void
xml_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
{
execution_exception::location const& loc = ex.where();
ostr << "<Exception file" << utils::attr_value() << loc.m_file_name
<< " line" << utils::attr_value() << loc.m_line_num;
if( !loc.m_function.is_empty() )
ostr << " function" << utils::attr_value() << loc.m_function;
ostr << ">" << utils::cdata() << ex.what();
if( !checkpoint_data.m_file_name.is_empty() ) {
ostr << "<LastCheckpoint file" << utils::attr_value() << checkpoint_data.m_file_name
<< " line" << utils::attr_value() << checkpoint_data.m_line_num
<< ">"
<< utils::cdata() << checkpoint_data.m_message
<< "</LastCheckpoint>";
}
}
//____________________________________________________________________________//
void
xml_log_formatter::log_exception_finish( std::ostream& ostr )
{
ostr << "</Exception>";
}
//____________________________________________________________________________//
void
xml_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& entry_data, log_entry_types let )
{
static literal_string xml_tags[] = { "Info", "Message", "Warning", "Error", "FatalError" };
m_curr_tag = xml_tags[let];
ostr << '<' << m_curr_tag
<< BOOST_TEST_L( " file" ) << utils::attr_value() << entry_data.m_file_name
<< BOOST_TEST_L( " line" ) << utils::attr_value() << entry_data.m_line_num
<< BOOST_TEST_L( "><![CDATA[" );
m_value_closed = false;
}
//____________________________________________________________________________//
void
xml_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
{
utils::print_escaped_cdata( ostr, value );
}
//____________________________________________________________________________//
void
xml_log_formatter::log_entry_finish( std::ostream& ostr )
{
if( !m_value_closed ) {
ostr << BOOST_TEST_L( "]]>" );
m_value_closed = true;
}
ostr << BOOST_TEST_L( "</" ) << m_curr_tag << BOOST_TEST_L( ">" );
m_curr_tag.clear();
}
//____________________________________________________________________________//
void
xml_log_formatter::entry_context_start( std::ostream& ostr, log_level )
{
if( !m_value_closed ) {
ostr << BOOST_TEST_L( "]]>" );
m_value_closed = true;
}
ostr << BOOST_TEST_L( "<Context>" );
}
//____________________________________________________________________________//
void
xml_log_formatter::entry_context_finish( std::ostream& ostr )
{
ostr << BOOST_TEST_L( "</Context>" );
}
//____________________________________________________________________________//
void
xml_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr )
{
ostr << BOOST_TEST_L( "<Frame>" ) << utils::cdata() << context_descr << BOOST_TEST_L( "</Frame>" );
}
//____________________________________________________________________________//
} // namespace output
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_LOG_FORMATTER_IPP_020105GER

View File

@@ -0,0 +1,111 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : OF_XML report formatter
// ***************************************************************************
#ifndef BOOST_TEST_XML_REPORT_FORMATTER_IPP_020105GER
#define BOOST_TEST_XML_REPORT_FORMATTER_IPP_020105GER
// Boost.Test
#include <boost/test/results_collector.hpp>
#include <boost/test/output/xml_report_formatter.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/utils/xml_printer.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
void
xml_report_formatter::results_report_start( std::ostream& ostr )
{
ostr << "<TestResult>";
}
//____________________________________________________________________________//
void
xml_report_formatter::results_report_finish( std::ostream& ostr )
{
ostr << "</TestResult>";
}
//____________________________________________________________________________//
void
xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream& ostr )
{
test_results const& tr = results_collector.results( tu.p_id );
const_string descr;
if( tr.passed() )
descr = "passed";
else if( tr.p_skipped )
descr = "skipped";
else if( tr.p_aborted )
descr = "aborted";
else
descr = "failed";
ostr << '<' << ( tu.p_type == TUT_CASE ? "TestCase" : "TestSuite" )
<< " name" << utils::attr_value() << tu.p_name.get()
<< " result" << utils::attr_value() << descr
<< " assertions_passed" << utils::attr_value() << tr.p_assertions_passed
<< " assertions_failed" << utils::attr_value() << tr.p_assertions_failed
<< " warnings_failed" << utils::attr_value() << tr.p_warnings_failed
<< " expected_failures" << utils::attr_value() << tr.p_expected_failures;
if( tu.p_type == TUT_SUITE ) {
ostr << " test_cases_passed" << utils::attr_value() << tr.p_test_cases_passed
<< " test_cases_passed_with_warnings" << utils::attr_value() << tr.p_test_cases_warned
<< " test_cases_failed" << utils::attr_value() << tr.p_test_cases_failed
<< " test_cases_skipped" << utils::attr_value() << tr.p_test_cases_skipped
<< " test_cases_aborted" << utils::attr_value() << tr.p_test_cases_aborted;
}
ostr << '>';
}
//____________________________________________________________________________//
void
xml_report_formatter::test_unit_report_finish( test_unit const& tu, std::ostream& ostr )
{
ostr << "</" << ( tu.p_type == TUT_CASE ? "TestCase" : "TestSuite" ) << '>';
}
//____________________________________________________________________________//
void
xml_report_formatter::do_confirmation_report( test_unit const& tu, std::ostream& ostr )
{
test_unit_report_start( tu, ostr );
test_unit_report_finish( tu, ostr );
}
//____________________________________________________________________________//
} // namespace output
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_REPORT_FORMATTER_IPP_020105GER