Imported existing code

This commit is contained in:
Hazim Gazov
2010-04-02 02:48:44 -03:00
parent 48fbc5ae91
commit 7a86d01598
13996 changed files with 2468699 additions and 0 deletions

View File

@@ -0,0 +1,20 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : deprecated
// ***************************************************************************
#ifndef BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
#define BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
#include <boost/test/unit_test.hpp>
#endif // BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER

View File

@@ -0,0 +1,101 @@
// (C) Copyright Gennadiy Rozental 2006-2008.
// 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: 49312 $
//
// Description : defines portable debug interfaces
// ***************************************************************************
#ifndef BOOST_TEST_DEBUG_API_HPP_112006GER
#define BOOST_TEST_DEBUG_API_HPP_112006GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <string>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace debug {
// ************************************************************************** //
// ************** check if program is running under debugger ************** //
// ************************************************************************** //
bool BOOST_TEST_DECL under_debugger();
// ************************************************************************** //
// ************** cause program to break execution ************** //
// ************** in debugger at call point ************** //
// ************************************************************************** //
void BOOST_TEST_DECL debugger_break();
// ************************************************************************** //
// ************** gui debugger setup ************** //
// ************************************************************************** //
struct dbg_startup_info {
long pid;
bool break_or_continue;
unit_test::const_string binary_path;
unit_test::const_string display;
unit_test::const_string init_done_lock;
};
typedef unit_test::callback1<dbg_startup_info const&> dbg_starter;
// ************************************************************************** //
// ************** debugger setup ************** //
// ************************************************************************** //
#if BOOST_WORKAROUND( BOOST_MSVC, <1300)
std::string BOOST_TEST_DECL set_debugger( unit_test::const_string dbg_id );
#else
std::string BOOST_TEST_DECL set_debugger( unit_test::const_string dbg_id, dbg_starter s = dbg_starter() );
#endif
// ************************************************************************** //
// ************** attach debugger to the current process ************** //
// ************************************************************************** //
bool BOOST_TEST_DECL attach_debugger( bool break_or_continue = true );
// ************************************************************************** //
// ************** switch on/off detect memory leaks feature ************** //
// ************************************************************************** //
void BOOST_TEST_DECL detect_memory_leaks( bool on_off );
// ************************************************************************** //
// ************** cause program to break execution in ************** //
// ************** debugger at specific allocation point ************** //
// ************************************************************************** //
void BOOST_TEST_DECL break_memory_alloc( long mem_alloc_order_num );
} // namespace debug
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif

View File

@@ -0,0 +1,24 @@
// (C) Copyright Gennadiy Rozental 2006-2008.
// 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: 49312 $
//
// Description : user's config for Boost.Test debugging support
// ***************************************************************************
#ifndef BOOST_TEST_DEBUG_CONFIG_HPP_112006GER
#define BOOST_TEST_DEBUG_CONFIG_HPP_112006GER
// ';' separated list of supported debuggers
// #define BOOST_TEST_DBG_LIST gdb;dbx
// maximum size of /proc/pid/stat file
// #define BOOST_TEST_STAT_LINE_MAX
#endif

View File

@@ -0,0 +1,109 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : as a central place for global configuration switches
// ***************************************************************************
#ifndef BOOST_TEST_CONFIG_HPP_071894GER
#define BOOST_TEST_CONFIG_HPP_071894GER
// Boost
#include <boost/config.hpp> // compilers workarounds
#include <boost/detail/workaround.hpp>
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570)) || \
BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
(defined __sgi && BOOST_WORKAROUND(_COMPILER_VERSION, BOOST_TESTED_AT(730)))
# define BOOST_TEST_SHIFTED_LINE
#endif
//____________________________________________________________________________//
#if defined(BOOST_MSVC) || (defined(__BORLANDC__) && !defined(BOOST_DISABLE_WIN32))
# define BOOST_TEST_CALL_DECL __cdecl
#else
# define BOOST_TEST_CALL_DECL /**/
#endif
//____________________________________________________________________________//
#if !defined(BOOST_NO_STD_LOCALE) && \
!BOOST_WORKAROUND(BOOST_MSVC, < 1310) && \
!defined(__MWERKS__)
# define BOOST_TEST_USE_STD_LOCALE 1
#endif
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x570) || \
BOOST_WORKAROUND( __COMO__, <= 0x433 ) || \
BOOST_WORKAROUND( __INTEL_COMPILER, <= 800 ) || \
defined(__sgi) && _COMPILER_VERSION <= 730 || \
BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) || \
defined(__DECCXX) || \
defined(__DMC__)
# define BOOST_TEST_NO_PROTECTED_USING
#endif
//____________________________________________________________________________//
#if defined(__GNUC__) || BOOST_WORKAROUND(BOOST_MSVC, == 1400)
#define BOOST_TEST_PROTECTED_VIRTUAL virtual
#else
#define BOOST_TEST_PROTECTED_VIRTUAL
#endif
//____________________________________________________________________________//
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
!BOOST_WORKAROUND(BOOST_MSVC, <1310) && \
!BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x530))
# define BOOST_TEST_SUPPORT_INTERACTION_TESTING 1
#endif
//____________________________________________________________________________//
#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_TEST_DYN_LINK)
# define BOOST_TEST_DYN_LINK
#endif
#if defined(BOOST_TEST_INCLUDED)
# undef BOOST_TEST_DYN_LINK
#endif
#if defined(BOOST_TEST_DYN_LINK)
# define BOOST_TEST_ALTERNATIVE_INIT_API
# if defined(BOOST_HAS_DECLSPEC) && defined(BOOST_TEST_DYN_LINK)
# ifdef BOOST_TEST_SOURCE
# define BOOST_TEST_DECL __declspec(dllexport)
# else
# define BOOST_TEST_DECL __declspec(dllimport)
# endif // BOOST_TEST_SOURCE
# endif // BOOST_HAS_DECLSPEC
#endif // BOOST_TEST_DYN_LINK
#ifndef BOOST_TEST_DECL
# define BOOST_TEST_DECL
#endif
#if !defined(BOOST_TEST_MAIN) && defined(BOOST_AUTO_TEST_MAIN)
#define BOOST_TEST_MAIN BOOST_AUTO_TEST_MAIN
#endif
#if !defined(BOOST_TEST_MAIN) && defined(BOOST_TEST_MODULE)
#define BOOST_TEST_MAIN BOOST_TEST_MODULE
#endif
#endif // BOOST_TEST_CONFIG_HPP_071894GER

View File

@@ -0,0 +1,28 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : enable previosly suppressed warnings
// ***************************************************************************
#ifdef BOOST_MSVC
# pragma warning(default: 4511) // copy constructor could not be generated
# pragma warning(default: 4512) // assignment operator could not be generated
# pragma warning(default: 4100) // unreferenced formal parameter
# pragma warning(default: 4996) // <symbol> was declared deprecated
# pragma warning(default: 4355) // 'this' : used in base member initializer list
# pragma warning(default: 4706) // assignment within conditional expression
# pragma warning(default: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
# pragma warning(default: 4127) // conditional expression is constant
# pragma warning(default: 4290) // C++ exception specification ignored except to ...
# pragma warning(default: 4180) // qualifier applied to function type has no meaning; ignored
# pragma warning(default: 4275) // non dll-interface class ... used as base for dll-interface class ...
# pragma warning(pop)
#endif

View File

@@ -0,0 +1,48 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : contains forward eclarations for Boost.Test data types
// ***************************************************************************
#ifndef BOOST_TEST_FWD_DECL_HPP_011605GER
#define BOOST_TEST_FWD_DECL_HPP_011605GER
namespace boost {
class execution_monitor;
class execution_exception;
namespace unit_test {
class test_unit;
class test_case;
class test_suite;
class master_test_suite_t;
class test_tree_visitor;
class test_observer;
// singletons
class unit_test_monitor_t;
class unit_test_log_t;
class unit_test_log_formatter;
struct log_entry_data;
struct log_checkpoint_data;
class lazy_ostream;
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_FWD_DECL_HPP_011605GER

View File

@@ -0,0 +1,72 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : some trivial global typedefs
// ***************************************************************************
#ifndef BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
#define BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#define BOOST_TEST_L( s ) boost::unit_test::const_string( s, sizeof( s ) - 1 )
#define BOOST_TEST_STRINGIZE( s ) BOOST_TEST_L( BOOST_STRINGIZE( s ) )
#define BOOST_TEST_EMPTY_STRING BOOST_TEST_L( "" )
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
typedef unsigned long counter_t;
//____________________________________________________________________________//
enum report_level { CONFIRMATION_REPORT, SHORT_REPORT, DETAILED_REPORT, NO_REPORT, INV_REPORT_LEVEL };
//____________________________________________________________________________//
enum output_format { CLF /* compiler log format */, XML /* XML */ };
//____________________________________________________________________________//
enum test_unit_type { tut_case = 0x01, tut_suite = 0x10, tut_any = 0x11 };
//____________________________________________________________________________//
typedef unsigned long test_unit_id;
const test_unit_id INV_TEST_UNIT_ID = 0xFFFFFFFF;
const test_unit_id MAX_TEST_CASE_ID = 0xFFFFFFFE;
const test_unit_id MIN_TEST_CASE_ID = 0x00010000;
const test_unit_id MAX_TEST_SUITE_ID = 0x0000FF00;
const test_unit_id MIN_TEST_SUITE_ID = 0x00000001;
//____________________________________________________________________________//
inline test_unit_type
test_id_2_unit_type( test_unit_id id )
{
return (id & 0xFFFF0000) != 0 ? tut_case : tut_suite;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER

View File

@@ -0,0 +1,43 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : shared definition for unit test log levels
// ***************************************************************************
#ifndef BOOST_TEST_LOG_LEVEL_HPP_011605GER
#define BOOST_TEST_LOG_LEVEL_HPP_011605GER
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** log levels ************** //
// ************************************************************************** //
// each log level includes all subsequent higher loging levels
enum log_level {
invalid_log_level = -1,
log_successful_tests = 0,
log_test_units = 1,
log_messages = 2,
log_warnings = 3,
log_all_errors = 4, // reported by unit test macros
log_cpp_exception_errors = 5, // uncaught C++ exceptions
log_system_errors = 6, // including timeouts, signals, traps
log_fatal_errors = 7, // including unit test macros or
// fatal system errors
log_nothing = 8
};
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_LOG_LEVEL_HPP_011605GER

View File

@@ -0,0 +1,29 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : suppress some warnings
// ***************************************************************************
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4511) // copy constructor could not be generated
# pragma warning(disable: 4512) // assignment operator could not be generated
# pragma warning(disable: 4100) // unreferenced formal parameter
# pragma warning(disable: 4996) // <symbol> was declared deprecated
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
# pragma warning(disable: 4706) // assignment within conditional expression
# pragma warning(disable: 4251) // class 'A<T>' needs to have dll-interface to be used by clients of class 'B'
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4290) // C++ exception specification ignored except to ...
# pragma warning(disable: 4180) // qualifier applied to function type has no meaning; ignored
# pragma warning(disable: 4275) // non dll-interface class ... used as base for dll-interface class ...
#endif

View File

@@ -0,0 +1,64 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : storage for unit test framework parameters information
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** runtime_config ************** //
// ************************************************************************** //
namespace runtime_config {
void BOOST_TEST_DECL init( int* argc, char** argv );
unit_test::log_level BOOST_TEST_DECL log_level();
bool BOOST_TEST_DECL no_result_code();
unit_test::report_level BOOST_TEST_DECL report_level();
const_string BOOST_TEST_DECL test_to_run();
const_string BOOST_TEST_DECL break_exec_path();
bool BOOST_TEST_DECL save_pattern();
bool BOOST_TEST_DECL show_build_info();
bool BOOST_TEST_DECL show_progress();
bool BOOST_TEST_DECL catch_sys_errors();
bool BOOST_TEST_DECL auto_start_dbg();
bool BOOST_TEST_DECL use_alt_stack();
bool BOOST_TEST_DECL detect_fp_exceptions();
output_format BOOST_TEST_DECL report_format();
output_format BOOST_TEST_DECL log_format();
long BOOST_TEST_DECL detect_memory_leaks();
int BOOST_TEST_DECL random_seed();
} // namespace runtime_config
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER

View File

@@ -0,0 +1,62 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : contains mics. workarounds
// ***************************************************************************
#ifndef BOOST_TEST_WORKAROUND_HPP_021005GER
#define BOOST_TEST_WORKAROUND_HPP_021005GER
// Boost
#include <boost/config.hpp> // compilers workarounds and std::ptrdiff_t
// STL
#include <iterator> // for std::distance
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
#ifdef BOOST_NO_STD_DISTANCE
template <class T>
std::ptrdiff_t distance( T const& x_, T const& y_ )
{
std::ptrdiff_t res = 0;
std::distance( x_, y_, res );
return res;
}
#else
using std::distance;
#endif
template <class T> inline void ignore_unused_variable_warning(const T&) {}
} // namespace ut_detail
} // namespace unit_test
namespace unit_test_framework = unit_test;
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_WORKAROUND_HPP_021005GER

View File

@@ -0,0 +1,187 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : Facilities to perform exception safety tests
// ***************************************************************************
#ifndef BOOST_TEST_EXCEPTION_SAFETY_HPP_111705GER
#define BOOST_TEST_EXCEPTION_SAFETY_HPP_111705GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <memory>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** BOOST_TEST_EXCEPTION_SAFETY ************** //
// ************************************************************************** //
#define BOOST_TEST_EXCEPTION_SAFETY( test_name ) \
struct test_name : public BOOST_AUTO_TEST_CASE_FIXTURE \
{ void test_method(); }; \
\
static void BOOST_AUTO_TC_INVOKER( test_name )() \
{ \
test_name t; \
::boost::itest::exception_safety( \
boost::bind( &test_name::test_method, t ), \
BOOST_STRINGIZE(test_name) ); \
} \
\
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
\
BOOST_AUTO_TU_REGISTRAR( test_name )( \
boost::unit_test::make_test_case( \
&BOOST_AUTO_TC_INVOKER( test_name ), #test_name ), \
boost::unit_test::ut_detail::auto_tc_exp_fail< \
BOOST_AUTO_TC_UNIQUE_ID( test_name )>::instance()->value() ); \
\
void test_name::test_method() \
/**/
namespace boost {
namespace itest {
// ************************************************************************** //
// ************** exception safety test ************** //
// ************************************************************************** //
void BOOST_TEST_DECL exception_safety( unit_test::callback0<> const& F,
unit_test::const_string test_name = "" );
} // namespace itest
} // namespace boost
// ************************************************************************** //
// ************** global operator new/delete overloads ************** //
// ************************************************************************** //
#ifndef BOOST_ITEST_NO_NEW_OVERLOADS
#include <boost/test/interaction_based.hpp>
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::isprint; using ::malloc; using ::free; }
# endif
inline void*
operator new( std::size_t s ) throw(std::bad_alloc)
{
void* res = std::malloc(s ? s : 1);
if( res )
::boost::itest::manager::instance().allocated( 0, 0, res, s );
else
throw std::bad_alloc();
return res;
}
//____________________________________________________________________________//
inline void*
operator new( std::size_t s, std::nothrow_t const& ) throw()
{
void* res = std::malloc(s ? s : 1);
if( res )
::boost::itest::manager::instance().allocated( 0, 0, res, s );
return res;
}
//____________________________________________________________________________//
inline void*
operator new[]( std::size_t s ) throw(std::bad_alloc)
{
void* res = std::malloc(s ? s : 1);
if( res )
::boost::itest::manager::instance().allocated( 0, 0, res, s );
else
throw std::bad_alloc();
return res;
}
//____________________________________________________________________________//
inline void*
operator new[]( std::size_t s, std::nothrow_t const& ) throw()
{
void* res = std::malloc(s ? s : 1);
if( res )
::boost::itest::manager::instance().allocated( 0, 0, res, s );
return res;
}
//____________________________________________________________________________//
inline void
operator delete( void* p ) throw()
{
::boost::itest::manager::instance().freed( p );
std::free( p );
}
//____________________________________________________________________________//
inline void
operator delete( void* p, std::nothrow_t const& ) throw()
{
::boost::itest::manager::instance().freed( p );
std::free( p );
}
//____________________________________________________________________________//
inline void
operator delete[]( void* p ) throw()
{
::boost::itest::manager::instance().freed( p );
std::free( p );
}
//____________________________________________________________________________//
inline void
operator delete[]( void* p, std::nothrow_t const& ) throw()
{
::boost::itest::manager::instance().freed( p );
std::free( p );
}
//____________________________________________________________________________//
#endif // BOOST_ITEST_NO_NEW_OVERLOADS
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_EXCEPTION_SAFETY_HPP_111705GER

View File

@@ -0,0 +1,254 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// (C) Copyright Beman Dawes 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: 49312 $
//
// Description : defines abstract monitor interfaces and implements execution exception
// The original Boost Test Library included an implementation detail function
// named catch_exceptions() which caught otherwise uncaught C++ exceptions.
// It was derived from an existing test framework by Beman Dawes. The
// intent was to expand later to catch other detectable but platform dependent
// error events like Unix signals or Windows structured C exceptions.
//
// Requests from early adopters of the Boost Test Library included
// configurable levels of error message detail, elimination of templates,
// separation of error reporting, and making the catch_exceptions() facilities
// available as a public interface. Support for unit testing also stretched
// the function based design. Implementation within the header became less
// attractive due to the need to include many huge system dependent headers,
// although still preferable in certain cases.
//
// All those issues have been addressed by introducing the class-based
// design presented here.
// ***************************************************************************
#ifndef BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
#define BOOST_TEST_EXECUTION_MONITOR_HPP_071894GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/class_properties.hpp>
// Boost
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/type.hpp>
#include <boost/cstdlib.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace detail {
// ************************************************************************** //
// ************** detail::translate_exception_base ************** //
// ************************************************************************** //
class BOOST_TEST_DECL translate_exception_base {
public:
// Constructor
explicit translate_exception_base( boost::scoped_ptr<translate_exception_base>& next )
{
next.swap( m_next );
}
// Destructor
virtual ~translate_exception_base() {}
virtual int operator()( unit_test::callback0<int> const& F ) = 0;
protected:
// Data members
boost::scoped_ptr<translate_exception_base> m_next;
};
} // namespace detail
// ************************************************************************** //
// ************** execution_exception ************** //
// ************************************************************************** //
// design rationale: fear of being out (or nearly out) of memory.
class BOOST_TEST_DECL execution_exception {
typedef boost::unit_test::const_string const_string;
public:
enum error_code {
// These values are sometimes used as program return codes.
// The particular values have been chosen to avoid conflicts with
// commonly used program return codes: values < 100 are often user
// assigned, values > 255 are sometimes used to report system errors.
// Gaps in values allow for orderly expansion.
no_error = 0, // for completeness only; never returned
user_error = 200, // user reported non-fatal error
cpp_exception_error = 205, // see note (1) below
system_error = 210, // see note (2) below
timeout_error = 215, // only detectable on certain platforms
user_fatal_error = 220, // user reported fatal error
system_fatal_error = 225 // see note (2) below
// Note 1: Only uncaught C++ exceptions are treated as errors.
// If the application catches a C++ exception, it will never reach
// the execution_monitor.
// Note 2: These errors include Unix signals and Windows structured
// exceptions. They are often initiated by hardware traps.
//
// The implementation decides what is a fatal_system_exception and what is
// just a system_exception. Fatal errors are so likely to have corrupted
// machine state (like a stack overflow or addressing exception) that it
// is unreasonable to continue execution.
};
// Constructor
execution_exception( error_code ec_, const_string what_msg_ ) // max length 256 inc '\0'
: m_error_code( ec_ ), m_what( what_msg_ ) {}
// access methods
error_code code() const { return m_error_code; }
const_string what() const { return m_what; }
private:
// Data members
error_code m_error_code;
const_string m_what;
}; // execution_exception
// ************************************************************************** //
// ************** execution_monitor ************** //
// ************************************************************************** //
class BOOST_TEST_DECL execution_monitor {
public:
// Constructor
execution_monitor()
: p_catch_system_errors( true )
, p_auto_start_dbg( false )
, p_timeout( 0 )
, p_use_alt_stack( true )
, p_detect_fp_exceptions( false )
{}
// Public properties
// The p_catch_system_errors parameter specifies whether the monitor should
// try to catch system errors/exceptions that would cause program to crash
// in regular case
unit_test::readwrite_property<bool> p_catch_system_errors;
// The p_auto_start_dbg parameter specifies whether the monitor should
// try to attach debugger in case of caught system error
unit_test::readwrite_property<bool> p_auto_start_dbg;
// The p_timeout parameter specifies the seconds that elapse before
// a timer_error occurs. May be ignored on some platforms.
unit_test::readwrite_property<int> p_timeout;
// The p_use_alt_stack parameter specifies whether the monitor should
// use alternative stack for the signal catching
unit_test::readwrite_property<bool> p_use_alt_stack;
// The p_detect_fp_exceptions parameter specifies whether the monitor should
// try to detect hardware floating point exceptions
unit_test::readwrite_property<bool> p_detect_fp_exceptions;
int execute( unit_test::callback0<int> const& F );
// Returns: Value returned by function call F().
//
// Effects: Calls executes supplied function F inside a try/catch block which also may
// include other unspecified platform dependent error detection code.
//
// Throws: execution_exception on an uncaught C++ exception,
// a hardware or software signal, trap, or other exception.
//
// Note: execute() doesn't consider it an error for F to return a non-zero value.
// register custom (user supplied) exception translator
template<typename Exception, typename ExceptionTranslator>
void register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* = 0 );
private:
// implementation helpers
int catch_signals( unit_test::callback0<int> const& F );
// Data members
boost::scoped_ptr<detail::translate_exception_base> m_custom_translators;
boost::scoped_array<char> m_alt_stack;
}; // execution_monitor
namespace detail {
// ************************************************************************** //
// ************** detail::translate_exception ************** //
// ************************************************************************** //
template<typename Exception, typename ExceptionTranslator>
class translate_exception : public translate_exception_base
{
typedef boost::scoped_ptr<translate_exception_base> base_ptr;
public:
explicit translate_exception( ExceptionTranslator const& tr, base_ptr& next )
: translate_exception_base( next ), m_translator( tr ) {}
int operator()( unit_test::callback0<int> const& F )
{
try {
return m_next ? (*m_next)( F ) : F();
} catch( Exception const& e ) {
m_translator( e );
return boost::exit_exception_failure;
}
}
private:
// Data members
ExceptionTranslator m_translator;
};
} // namespace detail
template<typename Exception, typename ExceptionTranslator>
void
execution_monitor::register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* )
{
m_custom_translators.reset(
new detail::translate_exception<Exception,ExceptionTranslator>( tr,m_custom_translators ) );
}
// ************************************************************************** //
// ************** execution_aborted ************** //
// ************************************************************************** //
struct execution_aborted {};
// ************************************************************************** //
// ************** system_error ************** //
// ************************************************************************** //
class system_error {
public:
// Constructor
explicit system_error( char const* exp );
unit_test::readonly_property<long> p_errno;
unit_test::readonly_property<char const*> p_failed_exp;
};
#define BOOST_TEST_SYS_ASSERT( exp ) if( (exp) ) ; else throw ::boost::system_error( BOOST_STRINGIZE( exp ) )
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif

View File

@@ -0,0 +1,259 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines algoirthms for comparing 2 floating point values
// ***************************************************************************
#ifndef BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
#define BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
#include <boost/limits.hpp> // for std::numeric_limits
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
using unit_test::readonly_property;
// ************************************************************************** //
// ************** floating_point_comparison_type ************** //
// ************************************************************************** //
enum floating_point_comparison_type {
FPC_STRONG, // "Very close" - equation 1' in docs, the default
FPC_WEAK // "Close enough" - equation 2' in docs.
};
// ************************************************************************** //
// ************** details ************** //
// ************************************************************************** //
namespace tt_detail {
// FPT is Floating-Point Type: float, double, long double or User-Defined.
template<typename FPT>
inline FPT
fpt_abs( FPT arg )
{
return arg < static_cast<FPT>(0) ? -arg : arg;
}
//____________________________________________________________________________//
template<typename FPT>
struct fpt_limits {
static FPT min_value()
{
return std::numeric_limits<FPT>::is_specialized
? (std::numeric_limits<FPT>::min)()
: 0;
}
static FPT max_value()
{
return std::numeric_limits<FPT>::is_specialized
? (std::numeric_limits<FPT>::max)()
: static_cast<FPT>(1000000); // for the our purpuses it doesn't really matter what value is returned here
}
};
//____________________________________________________________________________//
// both f1 and f2 are unsigned here
template<typename FPT>
inline FPT
safe_fpt_division( FPT f1, FPT f2 )
{
// Avoid overflow.
if( f2 < static_cast<FPT>(1) && f1 > f2*fpt_limits<FPT>::max_value() )
return fpt_limits<FPT>::max_value();
// Avoid underflow.
if( f1 == static_cast<FPT>(0) ||
f2 > static_cast<FPT>(1) && f1 < f2*fpt_limits<FPT>::min_value() )
return static_cast<FPT>(0);
return f1/f2;
}
//____________________________________________________________________________//
} // namespace tt_detail
// ************************************************************************** //
// ************** tolerance presentation types ************** //
// ************************************************************************** //
template<typename FPT>
struct percent_tolerance_t {
explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
FPT m_value;
};
//____________________________________________________________________________//
template<typename Out,typename FPT>
Out& operator<<( Out& out, percent_tolerance_t<FPT> t )
{
return out << t.m_value;
}
//____________________________________________________________________________//
template<typename FPT>
inline percent_tolerance_t<FPT>
percent_tolerance( FPT v )
{
return percent_tolerance_t<FPT>( v );
}
//____________________________________________________________________________//
template<typename FPT>
struct fraction_tolerance_t {
explicit fraction_tolerance_t( FPT v ) : m_value( v ) {}
FPT m_value;
};
//____________________________________________________________________________//
template<typename Out,typename FPT>
Out& operator<<( Out& out, fraction_tolerance_t<FPT> t )
{
return out << t.m_value;
}
//____________________________________________________________________________//
template<typename FPT>
inline fraction_tolerance_t<FPT>
fraction_tolerance( FPT v )
{
return fraction_tolerance_t<FPT>( v );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** close_at_tolerance ************** //
// ************************************************************************** //
template<typename FPT>
class close_at_tolerance {
public:
// Public typedefs
typedef bool result_type;
// Constructor
template<typename ToleranceBaseType>
explicit close_at_tolerance( percent_tolerance_t<ToleranceBaseType> tolerance,
floating_point_comparison_type fpc_type = FPC_STRONG )
: p_fraction_tolerance( tt_detail::fpt_abs( static_cast<FPT>(0.01)*tolerance.m_value ) )
, p_strong_or_weak( fpc_type == FPC_STRONG )
{}
template<typename ToleranceBaseType>
explicit close_at_tolerance( fraction_tolerance_t<ToleranceBaseType> tolerance,
floating_point_comparison_type fpc_type = FPC_STRONG )
: p_fraction_tolerance( tt_detail::fpt_abs( tolerance.m_value ) )
, p_strong_or_weak( fpc_type == FPC_STRONG )
{}
bool operator()( FPT left, FPT right ) const
{
FPT diff = tt_detail::fpt_abs( left - right );
FPT d1 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( right ) );
FPT d2 = tt_detail::safe_fpt_division( diff, tt_detail::fpt_abs( left ) );
return p_strong_or_weak
? (d1 <= p_fraction_tolerance.get() && d2 <= p_fraction_tolerance.get())
: (d1 <= p_fraction_tolerance.get() || d2 <= p_fraction_tolerance.get());
}
// Public properties
readonly_property<FPT> p_fraction_tolerance;
readonly_property<bool> p_strong_or_weak;
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** check_is_close ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL check_is_close_t {
// Public typedefs
typedef bool result_type;
template<typename FPT, typename ToleranceBaseType>
bool
operator()( FPT left, FPT right, percent_tolerance_t<ToleranceBaseType> tolerance,
floating_point_comparison_type fpc_type = FPC_STRONG )
{
close_at_tolerance<FPT> pred( tolerance, fpc_type );
return pred( left, right );
}
template<typename FPT, typename ToleranceBaseType>
bool
operator()( FPT left, FPT right, fraction_tolerance_t<ToleranceBaseType> tolerance,
floating_point_comparison_type fpc_type = FPC_STRONG )
{
close_at_tolerance<FPT> pred( tolerance, fpc_type );
return pred( left, right );
}
};
namespace {
check_is_close_t check_is_close;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** check_is_small ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL check_is_small_t {
// Public typedefs
typedef bool result_type;
template<typename FPT>
bool
operator()( FPT fpv, FPT tolerance )
{
return tt_detail::fpt_abs( fpv ) < tt_detail::fpt_abs( tolerance );
}
};
namespace {
check_is_small_t check_is_small;
}
//____________________________________________________________________________//
} // namespace test_tools
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_FLOATING_POINT_COMAPARISON_HPP_071894GER

View File

@@ -0,0 +1,108 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : defines framework interface
// ***************************************************************************
#ifndef BOOST_TEST_FRAMEWORK_HPP_020805GER
#define BOOST_TEST_FRAMEWORK_HPP_020805GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// STL
#include <stdexcept>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** init_unit_test_func ************** //
// ************************************************************************** //
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
typedef bool (*init_unit_test_func)();
#else
typedef test_suite* (*init_unit_test_func)( int, char* [] );
#endif
// ************************************************************************** //
// ************** framework ************** //
// ************************************************************************** //
namespace framework {
// initialization
BOOST_TEST_DECL void init( init_unit_test_func init_func, int argc, char* argv[] );
BOOST_TEST_DECL bool is_initialized();
// mutation access methods
BOOST_TEST_DECL void register_test_unit( test_case* tc );
BOOST_TEST_DECL void register_test_unit( test_suite* ts );
BOOST_TEST_DECL void deregister_test_unit( test_unit* tu );
BOOST_TEST_DECL void clear();
BOOST_TEST_DECL void register_observer( test_observer& );
BOOST_TEST_DECL void deregister_observer( test_observer& );
BOOST_TEST_DECL void reset_observers();
BOOST_TEST_DECL master_test_suite_t& master_test_suite();
// constant access methods
BOOST_TEST_DECL test_case const& current_test_case();
BOOST_TEST_DECL test_unit& get( test_unit_id, test_unit_type );
template<typename UnitType>
UnitType& get( test_unit_id id )
{
return static_cast<UnitType&>( get( id, (test_unit_type)UnitType::type ) );
}
// test initiation
BOOST_TEST_DECL void run( test_unit_id = INV_TEST_UNIT_ID, bool continue_test = true );
BOOST_TEST_DECL void run( test_unit const*, bool continue_test = true );
// public test events dispatchers
BOOST_TEST_DECL void assertion_result( bool passed );
BOOST_TEST_DECL void exception_caught( execution_exception const& );
BOOST_TEST_DECL void test_unit_aborted( test_unit const& );
// ************************************************************************** //
// ************** framework errors ************** //
// ************************************************************************** //
struct internal_error : std::runtime_error {
internal_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {}
};
struct setup_error : std::runtime_error {
setup_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {}
};
} // namespace framework
} // unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_FRAMEWORK_HPP_020805GER

View File

@@ -0,0 +1,210 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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/unit_test_suite_impl.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/lazy_ostream.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 ************** //
// ************************************************************************** //
void
compiler_log_formatter::log_start( std::ostream& output, counter_t test_cases_amount )
{
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 )
{
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 )
{
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 << "mks";
}
output << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::test_unit_skipped( std::ostream& output, test_unit const& tu )
{
output << "Test " << tu.p_type_name << " \"" << tu.p_name << "\"" << "is skipped" << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_exception( std::ostream& output, log_checkpoint_data const& checkpoint_data, const_string explanation )
{
print_prefix( output, BOOST_TEST_L( "unknown location" ), 0 );
output << "fatal error in \"" << framework::current_test_case().p_name << "\": ";
if( !explanation.is_empty() )
output << explanation;
else
output << "uncaught exception, system error or abort requested";
if( !checkpoint_data.m_file_name.is_empty() ) {
output << '\n';
print_prefix( output, checkpoint_data.m_file_name, checkpoint_data.m_line_num );
output << "last checkpoint";
if( !checkpoint_data.m_message.empty() )
output << ": " << checkpoint_data.m_message;
}
output << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::log_entry_start( std::ostream& output, log_entry_data const& entry_data, log_entry_types let )
{
switch( let ) {
case BOOST_UTL_ET_INFO:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
output << "info: ";
break;
case BOOST_UTL_ET_MESSAGE:
break;
case BOOST_UTL_ET_WARNING:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
output << "warning in \"" << framework::current_test_case().p_name << "\": ";
break;
case BOOST_UTL_ET_ERROR:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
output << "error in \"" << framework::current_test_case().p_name << "\": ";
break;
case BOOST_UTL_ET_FATAL_ERROR:
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
output << "fatal error in \"" << framework::current_test_case().p_name << "\": ";
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 )
{
output << std::endl;
}
//____________________________________________________________________________//
void
compiler_log_formatter::print_prefix( std::ostream& output, const_string file, std::size_t line )
{
#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 << ':' << line << ": ";
#else
output << file << '(' << line << "): ";
#endif
}
//____________________________________________________________________________//
} // 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,139 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// (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: 49312 $
//
// 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;
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(
::boost::unit_test::callback0<int>( 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;
}
}
catch( ::boost::execution_exception const& exex ) {
std::cout << "\n**** exception(" << exex.code() << "): " << exex.what() << std::endl;
result = ::boost::exit_exception_failure;
}
catch( ::boost::system_error const& 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

View File

@@ -0,0 +1,970 @@
// (C) Copyright Gennadiy Rozental 2006-2008.
// Use, modification, and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 49312 $
//
// Description : debug interfaces implementation
// ***************************************************************************
#ifndef BOOST_TEST_DEBUG_API_IPP_112006GER
#define BOOST_TEST_DEBUG_API_IPP_112006GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/debug.hpp>
#include <boost/test/debug_config.hpp>
// Implementation in windows
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(BOOST_DISABLE_WIN32) // ******* WIN32
# define BOOST_WIN32_BASED_DEBUG
// SYSTEM API
# include <windows.h>
# include <winreg.h>
# include <cstdio>
# include <cstring>
# if !defined(NDEBUG) && defined(_MSC_VER)
# define BOOST_MS_CRT_BASED_DEBUG
# include <crtdbg.h>
# endif
# if BOOST_WORKAROUND( BOOST_MSVC, <1300)
# define snprintf _snprintf
# endif
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::memset; using ::sprintf; }
# endif
#elif defined(unix) || defined(__unix) // ********************* UNIX
# define BOOST_UNIX_BASED_DEBUG
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/algorithm.hpp>
// STL
#include <cstring> // std::memcpy
#include <map>
#include <cstdio>
#include <stdarg.h> // !! ?? cstdarg
// SYSTEM API
# include <unistd.h>
# include <signal.h>
# include <fcntl.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <sys/wait.h>
# include <sys/time.h>
# include <stdio.h>
# include <stdlib.h>
# if defined(sun) || defined(__sun)
# define BOOST_SUN_BASED_DEBUG
# ifndef BOOST_TEST_DBG_LIST
# define BOOST_TEST_DBG_LIST dbx;gdb
# endif
# define BOOST_TEST_CNL_DBG dbx
# define BOOST_TEST_GUI_DBG dbx-ddd
# include <procfs.h>
# elif defined(linux) || defined(__linux)
# define BOOST_LINUX_BASED_DEBUG
# include <sys/ptrace.h>
# ifndef BOOST_TEST_STAT_LINE_MAX
# define BOOST_TEST_STAT_LINE_MAX 500
# endif
# ifndef BOOST_TEST_DBG_LIST
# define BOOST_TEST_DBG_LIST gdb
# endif
# define BOOST_TEST_CNL_DBG gdb
# define BOOST_TEST_GUI_DBG gdb-xterm
# endif
#endif
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace debug {
using unit_test::const_string;
// ************************************************************************** //
// ************** debug::info_t ************** //
// ************************************************************************** //
namespace {
#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32
template<typename T>
inline void
dyn_symbol( T& res, char const* module_name, char const* symbol_name )
{
HMODULE m = ::GetModuleHandleA( module_name );
if( !m )
m = ::LoadLibraryA( module_name );
res = reinterpret_cast<T>( ::GetProcAddress( m, symbol_name ) );
}
//____________________________________________________________________________//
static struct info_t {
typedef BOOL (WINAPI* IsDebuggerPresentT)();
typedef LONG (WINAPI* RegQueryValueExT)( HKEY, char const* /*LPTSTR*/, LPDWORD, LPDWORD, LPBYTE, LPDWORD );
typedef LONG (WINAPI* RegOpenKeyT)( HKEY, char const* /*LPCTSTR*/, PHKEY );
typedef LONG (WINAPI* RegCloseKeyT)( HKEY );
info_t();
IsDebuggerPresentT m_is_debugger_present;
RegOpenKeyT m_reg_open_key;
RegQueryValueExT m_reg_query_value;
RegCloseKeyT m_reg_close_key;
} s_info;
//____________________________________________________________________________//
info_t::info_t()
{
dyn_symbol( m_is_debugger_present, "kernel32", "IsDebuggerPresent" );
dyn_symbol( m_reg_open_key, "advapi32", "RegOpenKeyA" );
dyn_symbol( m_reg_query_value, "advapi32", "RegQueryValueExA" );
dyn_symbol( m_reg_close_key, "advapi32", "RegCloseKey" );
}
//____________________________________________________________________________//
#elif defined(BOOST_UNIX_BASED_DEBUG)
// ************************************************************************** //
// ************** fd_holder ************** //
// ************************************************************************** //
struct fd_holder {
explicit fd_holder( int fd ) : m_fd( fd ) {}
~fd_holder()
{
if( m_fd != -1 )
::close( m_fd );
}
operator int() { return m_fd; }
private:
// Data members
int m_fd;
};
// ************************************************************************** //
// ************** process_info ************** //
// ************************************************************************** //
struct process_info {
// Constructor
explicit process_info( int pid );
// access methods
int parent_pid() const { return m_parent_pid; }
const_string binary_name() const { return m_binary_name; }
const_string binary_path() const { return m_binary_path; }
private:
// Data members
int m_parent_pid;
const_string m_binary_name;
const_string m_binary_path;
#if defined(BOOST_SUN_BASED_DEBUG)
struct psinfo m_psi;
#elif defined(BOOST_LINUX_BASED_DEBUG)
char m_stat_line[BOOST_TEST_STAT_LINE_MAX+1];
#endif
char m_binary_path_buff[500+1]; // !! ??
};
//____________________________________________________________________________//
process_info::process_info( int pid )
: m_parent_pid( 0 )
{
#if defined(BOOST_SUN_BASED_DEBUG)
char fname_buff[30];
::snprintf( fname_buff, sizeof(fname_buff), "/proc/%d/psinfo", pid );
fd_holder psinfo_fd( ::open( fname_buff, O_RDONLY ) );
if( psinfo_fd == -1 )
return;
if( ::read( psinfo_fd, &m_psi, sizeof(m_psi) ) == -1 )
return;
m_parent_pid = m_psi.pr_ppid;
m_binary_name.assign( m_psi.pr_fname );
//-------------------------- //
::snprintf( fname_buff, sizeof(fname_buff), "/proc/%d/as", pid );
fd_holder as_fd( ::open( fname_buff, O_RDONLY ) );
uintptr_t binary_name_pos;
// !! ?? could we avoid reading whole m_binary_path_buff?
if( as_fd == -1 ||
::lseek( as_fd, m_psi.pr_argv, SEEK_SET ) == -1 ||
::read ( as_fd, &binary_name_pos, sizeof(binary_name_pos) ) == -1 ||
::lseek( as_fd, binary_name_pos, SEEK_SET ) == -1 ||
::read ( as_fd, m_binary_path_buff, sizeof(m_binary_path_buff) ) == -1 )
return;
m_binary_path.assign( m_binary_path_buff );
#elif defined(BOOST_LINUX_BASED_DEBUG)
char fname_buff[30];
::snprintf( fname_buff, sizeof(fname_buff), "/proc/%d/stat", pid );
fd_holder psinfo_fd( ::open( fname_buff, O_RDONLY ) );
if( psinfo_fd == -1 )
return;
ssize_t num_read = ::read( psinfo_fd, m_stat_line, sizeof(m_stat_line)-1 );
if( num_read == -1 )
return;
m_stat_line[num_read] = 0;
char const* name_beg = m_stat_line;
while( *name_beg && *name_beg != '(' )
++name_beg;
char const* name_end = name_beg+1;
while( *name_end && *name_end != ')' )
++name_end;
std::sscanf( name_end+1, "%*s%d", &m_parent_pid );
m_binary_name.assign( name_beg+1, name_end );
::snprintf( fname_buff, sizeof(fname_buff), "/proc/%d/exe", pid );
num_read = ::readlink( fname_buff, m_binary_path_buff, sizeof(m_binary_path_buff)-1 );
if( num_read == -1 )
return;
m_binary_path_buff[num_read] = 0;
m_binary_path.assign( m_binary_path_buff, num_read );
#endif
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** prepare_window_title ************** //
// ************************************************************************** //
static char*
prepare_window_title( dbg_startup_info const& dsi )
{
typedef unit_test::const_string str_t;
static char title_str[50];
str_t path_sep( "\\/" );
str_t::iterator it = unit_test::find_last_of( dsi.binary_path.begin(), dsi.binary_path.end(),
path_sep.begin(), path_sep.end() );
if( it == dsi.binary_path.end() )
it = dsi.binary_path.begin();
else
++it;
::snprintf( title_str, sizeof(title_str), "%*s %ld", (int)(dsi.binary_path.end()-it), it, dsi.pid );
return title_str;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** save_execlp ************** //
// ************************************************************************** //
typedef unit_test::basic_cstring<char> mbuffer;
inline char*
copy_arg( mbuffer& dest, const_string arg )
{
if( dest.size() < arg.size()+1 )
return 0;
char* res = dest.begin();
std::memcpy( res, arg.begin(), arg.size()+1 );
dest.trim_left( arg.size()+1 );
return res;
}
//____________________________________________________________________________//
bool
safe_execlp( char const* file, ... )
{
static char* argv_buff[200];
va_list args;
char const* arg;
// first calculate actual number of arguments
int num_args = 2; // file name and 0 at least
va_start( args, file );
while( !!(arg = va_arg( args, char const* )) )
num_args++;
va_end( args );
// reserve space for the argument pointers array
char** argv_it = argv_buff;
mbuffer work_buff( reinterpret_cast<char*>(argv_buff), sizeof(argv_buff) );
work_buff.trim_left( num_args * sizeof(char*) );
// copy all the argument values into local storage
if( !(*argv_it++ = copy_arg( work_buff, file )) )
return false;
printf( "!! %s\n", file );
va_start( args, file );
while( !!(arg = va_arg( args, char const* )) ) {
printf( "!! %s\n", arg );
if( !(*argv_it++ = copy_arg( work_buff, arg )) )
return false;
}
va_end( args );
*argv_it = 0;
return ::execvp( file, argv_buff ) != -1;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** start_debugger_in_emacs ************** //
// ************************************************************************** //
static void
start_debugger_in_emacs( dbg_startup_info const& dsi, char const* emacs_name, char const* dbg_command )
{
char const* title = prepare_window_title( dsi );
if( !title )
return;
dsi.display.is_empty()
? safe_execlp( emacs_name, "-title", title, "--eval", dbg_command, 0 )
: safe_execlp( emacs_name, "-title", title, "-display", dsi.display.begin(), "--eval", dbg_command, 0 );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** gdb starters ************** //
// ************************************************************************** //
static char const*
prepare_gdb_cmnd_file( dbg_startup_info const& dsi )
{
// prepare pid value
char pid_buff[16];
::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid );
unit_test::const_string pid_str( pid_buff );
static char cmd_file_name[] = "/tmp/btl_gdb_cmd_XXXXXX"; // !! ??
// prepare commands
fd_holder cmd_fd( ::mkstemp( cmd_file_name ) );
if( cmd_fd == -1 )
return 0;
#define WRITE_STR( str ) if( ::write( cmd_fd, str.begin(), str.size() ) == -1 ) return 0;
#define WRITE_CSTR( str ) if( ::write( cmd_fd, str, sizeof( str )-1 ) == -1 ) return 0;
WRITE_CSTR( "file " );
WRITE_STR( dsi.binary_path );
WRITE_CSTR( "\nattach " );
WRITE_STR( pid_str );
WRITE_CSTR( "\nshell unlink " );
WRITE_STR( dsi.init_done_lock );
WRITE_CSTR( "\ncont" );
if( dsi.break_or_continue )
WRITE_CSTR( "\nup 4" );
WRITE_CSTR( "\necho \\n" ); // !! ??
WRITE_CSTR( "\nlist -" );
WRITE_CSTR( "\nlist" );
WRITE_CSTR( "\nshell unlink " );
WRITE_CSTR( cmd_file_name );
return cmd_file_name;
}
//____________________________________________________________________________//
static void
start_gdb_in_console( dbg_startup_info const& dsi )
{
char const* cmnd_file_name = prepare_gdb_cmnd_file( dsi );
if( !cmnd_file_name )
return;
safe_execlp( "gdb", "-q", "-x", cmnd_file_name, 0 );
}
//____________________________________________________________________________//
static void
start_gdb_in_xterm( dbg_startup_info const& dsi )
{
char const* title = prepare_window_title( dsi );
char const* cmnd_file_name = prepare_gdb_cmnd_file( dsi );
if( !title || !cmnd_file_name )
return;
safe_execlp( "xterm", "-T", title, "-display", dsi.display.begin(),
"-bg", "black", "-fg", "white", "-geometry", "88x30+10+10", "-fn", "9x15", "-e",
"gdb", "-q", "-x", cmnd_file_name, 0 );
}
//____________________________________________________________________________//
static void
start_gdb_in_emacs( dbg_startup_info const& dsi )
{
char const* cmnd_file_name = prepare_gdb_cmnd_file( dsi );
if( !cmnd_file_name )
return;
char dbg_cmd_buff[500]; // !! ??
::snprintf( dbg_cmd_buff, sizeof(dbg_cmd_buff), "(progn (gdb \"gdb -q -x %s\"))", cmnd_file_name );
start_debugger_in_emacs( dsi, "emacs", dbg_cmd_buff );
}
//____________________________________________________________________________//
static void
start_gdb_in_xemacs( dbg_startup_info const& )
{
// !! ??
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** dbx starters ************** //
// ************************************************************************** //
static char const*
prepare_dbx_cmd_line( dbg_startup_info const& dsi, bool list_source = true )
{
static char cmd_line_buff[500]; // !! ??
::snprintf( cmd_line_buff, sizeof(cmd_line_buff), "unlink %s;cont;%s%s",
dsi.init_done_lock.begin(),
dsi.break_or_continue ? "up 2;": "",
list_source ? "echo \" \";list -w3;" : "" );
return cmd_line_buff;
}
//____________________________________________________________________________//
static void
start_dbx_in_console( dbg_startup_info const& dsi )
{
char pid_buff[16];
::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid );
safe_execlp( "dbx", "-q", "-c", prepare_dbx_cmd_line( dsi ), dsi.binary_path.begin(), pid_buff, 0 );
}
//____________________________________________________________________________//
static void
start_dbx_in_xterm( dbg_startup_info const& dsi )
{
char const* title = prepare_window_title( dsi );
if( !title )
return;
char pid_buff[16]; // !! ??
::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid );
safe_execlp( "xterm", "-T", title, "-display", dsi.display.begin(),
"-bg", "black", "-fg", "white", "-geometry", "88x30+10+10", "-fn", "9x15", "-e",
"dbx", "-q", "-c", prepare_dbx_cmd_line( dsi ), dsi.binary_path.begin(), pid_buff, 0 );
}
//____________________________________________________________________________//
static void
start_dbx_in_emacs( dbg_startup_info const& /*dsi*/ )
{
// char dbg_cmd_buff[500]; // !! ??
//
// ::snprintf( dbg_cmd_buff, sizeof(dbg_cmd_buff), "(progn (dbx \"dbx -q -c cont %s %ld\"))", dsi.binary_path.begin(), dsi.pid );
// start_debugger_in_emacs( dsi, "emacs", dbg_cmd_buff );
}
//____________________________________________________________________________//
static void
start_dbx_in_xemacs( dbg_startup_info const& )
{
// !! ??
}
//____________________________________________________________________________//
static void
start_dbx_in_ddd( dbg_startup_info const& dsi )
{
char const* title = prepare_window_title( dsi );
if( !title )
return;
char pid_buff[16]; // !! ??
::snprintf( pid_buff, sizeof(pid_buff), "%ld", dsi.pid );
safe_execlp( "ddd", "-display", dsi.display.begin(),
"--dbx", "-q", "-c", prepare_dbx_cmd_line( dsi, false ), dsi.binary_path.begin(), pid_buff, 0 );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** debug::info_t ************** //
// ************************************************************************** //
static struct info_t {
// Constructor
info_t();
// Public properties
unit_test::readwrite_property<std::string> p_dbg;
// Data members
std::map<std::string,dbg_starter> m_dbg_starter_reg;
} s_info;
//____________________________________________________________________________//
info_t::info_t()
{
p_dbg.value = ::getenv( "DISPLAY" )
? std::string( BOOST_STRINGIZE( BOOST_TEST_GUI_DBG ) )
: std::string( BOOST_STRINGIZE( BOOST_TEST_CNL_DBG ) );
m_dbg_starter_reg[std::string("gdb")] = &start_gdb_in_console;
m_dbg_starter_reg[std::string("gdb-emacs")] = &start_gdb_in_emacs;
m_dbg_starter_reg[std::string("gdb-xterm")] = &start_gdb_in_xterm;
m_dbg_starter_reg[std::string("gdb-xemacs")] = &start_gdb_in_xemacs;
m_dbg_starter_reg[std::string("dbx")] = &start_dbx_in_console;
m_dbg_starter_reg[std::string("dbx-emacs")] = &start_dbx_in_emacs;
m_dbg_starter_reg[std::string("dbx-xterm")] = &start_dbx_in_xterm;
m_dbg_starter_reg[std::string("dbx-xemacs")] = &start_dbx_in_xemacs;
m_dbg_starter_reg[std::string("dbx-ddd")] = &start_dbx_in_ddd;
}
//____________________________________________________________________________//
#endif
} // local namespace
// ************************************************************************** //
// ************** check if program is running under debugger ************** //
// ************************************************************************** //
bool
under_debugger()
{
#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32
return !!s_info.m_is_debugger_present && s_info.m_is_debugger_present();
#elif defined(BOOST_UNIX_BASED_DEBUG) // ********************** UNIX
// !! ?? could/should we cache the result somehow?
const_string dbg_list = BOOST_TEST_STRINGIZE( BOOST_TEST_DBG_LIST );
pid_t pid = ::getpid();
while( pid != 0 ) {
process_info pi( pid );
// !! ?? should we use tokenizer here instead?
if( dbg_list.find( pi.binary_name() ) != const_string::npos )
return true;
pid = pi.parent_pid();
}
return false;
#else // ****************************************************** default
return false;
#endif
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** cause program to break execution ************** //
// ************** in debugger at call point ************** //
// ************************************************************************** //
void
debugger_break()
{
// !! ?? auto-start debugger?
#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32
#if BOOST_WORKAROUND(BOOST_MSVC, >= 1300) || \
BOOST_WORKAROUND(__GNUC__, >= 3) && !defined(__MINGW32__) || \
defined(__INTEL_COMPILER)
# define BOOST_DEBUG_BREAK __debugbreak
#else
# define BOOST_DEBUG_BREAK DebugBreak
#endif
#ifndef __MINGW32__
if( !under_debugger() ) {
__try {
__try {
BOOST_DEBUG_BREAK();
}
__except( UnhandledExceptionFilter(GetExceptionInformation()) )
{
// User opted to ignore the breakpoint
return;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
// If we got here, the user has pushed Debug. Debugger is already attached to our process and we
// continue to let the another BOOST_DEBUG_BREAK to be called.
}
}
#endif
BOOST_DEBUG_BREAK();
#elif defined(BOOST_UNIX_BASED_DEBUG) // ********************** UNIX
::kill( ::getpid(), SIGTRAP );
#else // ****************************************************** default
#endif
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** console debugger setup ************** //
// ************************************************************************** //
#if defined(BOOST_UNIX_BASED_DEBUG) // ************************ UNIX
std::string
set_debugger( unit_test::const_string dbg_id, dbg_starter s )
{
std::string old = s_info.p_dbg;
assign_op( s_info.p_dbg.value, dbg_id, 0 );
if( !!s )
s_info.m_dbg_starter_reg[s_info.p_dbg] = s;
return old;
}
#else // ***************************************************** default
std::string
set_debugger( unit_test::const_string, dbg_starter )
{
return std::string();
}
#endif
//____________________________________________________________________________//
// ************************************************************************** //
// ************** attach debugger to the current process ************** //
// ************************************************************************** //
bool
attach_debugger( bool break_or_continue )
{
if( under_debugger() )
return false;
#if defined(BOOST_WIN32_BASED_DEBUG) // *********************** WIN32
const int MAX_CMD_LINE = 200;
// *************************************************** //
// Debugger "ready" event
SECURITY_ATTRIBUTES attr;
attr.nLength = sizeof(attr);
attr.lpSecurityDescriptor = NULL;
attr.bInheritHandle = true;
// manual resettable, initially non signaled, unnamed event,
// that will signal me that debugger initialization is done
HANDLE dbg_init_done_ev = ::CreateEvent(
&attr, // pointer to security attributes
true, // flag for manual-reset event
false, // flag for initial state
NULL // pointer to event-object name
);
if( !dbg_init_done_ev )
return false;
// *************************************************** //
// Debugger command line format
HKEY reg_key;
if( !s_info.m_reg_open_key || (*s_info.m_reg_open_key)(
HKEY_LOCAL_MACHINE, // handle of open key
"Software\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug", // name of subkey to open
&reg_key ) != ERROR_SUCCESS ) // address of handle of open key
return false;
char format[MAX_CMD_LINE];
DWORD format_size = MAX_CMD_LINE;
DWORD type = REG_SZ;
if( !s_info.m_reg_query_value || (*s_info.m_reg_query_value)(
reg_key, // handle of open key
"Debugger", // name of subkey to query
0, // reserved
&type, // value type
(LPBYTE)format, // buffer for returned string
&format_size ) != ERROR_SUCCESS ) // in: buffer size; out: actual size of returned string
return false;
if( !s_info.m_reg_close_key || (*s_info.m_reg_close_key)( reg_key ) != ERROR_SUCCESS )
return false;
// *************************************************** //
// Debugger command line
char cmd_line[MAX_CMD_LINE];
std::sprintf( cmd_line, format, ::GetCurrentProcessId(), dbg_init_done_ev );
// *************************************************** //
// Debugger window parameters
STARTUPINFOA startup_info;
std::memset( &startup_info, 0, sizeof(startup_info) );
startup_info.cb = sizeof(startup_info);
startup_info.dwFlags = STARTF_USESHOWWINDOW;
startup_info.wShowWindow = SW_SHOWNORMAL;
// debugger process s_info
PROCESS_INFORMATION debugger_info;
bool created = !!::CreateProcessA(
NULL, // pointer to name of executable module; NULL - use the one in command line
cmd_line, // pointer to command line string
NULL, // pointer to process security attributes; NULL - debugger's handle couldn't be inherited
NULL, // pointer to thread security attributes; NULL - debugger's handle couldn't be inherited
true, // debugger inherit opened handles
0, // priority flags; 0 - normal priority
NULL, // pointer to new environment block; NULL - use this process environment
NULL, // pointer to current directory name; NULL - use this process correct directory
&startup_info, // pointer to STARTUPINFO that specifies main window appearance
&debugger_info // pointer to PROCESS_INFORMATION that will contain the new process identification
);
if( created )
::WaitForSingleObject( dbg_init_done_ev, INFINITE );
::CloseHandle( dbg_init_done_ev );
if( !created )
return false;
if( break_or_continue )
debugger_break();
return true;
#elif defined(BOOST_UNIX_BASED_DEBUG) // ********************** UNIX
char init_done_lock_fn[] = "/tmp/btl_dbg_init_done_XXXXXX";
fd_holder init_done_lock_fd( ::mkstemp( init_done_lock_fn ) );
if( init_done_lock_fd == -1 )
return false;
pid_t child_pid = fork();
if( child_pid == -1 )
return false;
if( child_pid != 0 ) { // parent process - here we will start the debugger
dbg_startup_info dsi;
process_info pi( child_pid );
if( pi.binary_path().is_empty() )
::exit( -1 );
dsi.pid = child_pid;
dsi.break_or_continue = break_or_continue;
dsi.binary_path = pi.binary_path();
dsi.display = ::getenv( "DISPLAY" );
dsi.init_done_lock = init_done_lock_fn;
dbg_starter starter = s_info.m_dbg_starter_reg[s_info.p_dbg];
if( !!starter )
starter( dsi );
::perror( "Boost.Test execution monitor failed to start a debugger:" );
::exit( -1 );
}
// child process - here we will continue our test module execution ; // !! ?? should it be vice versa
while( ::access( init_done_lock_fn, F_OK ) == 0 ) {
struct timeval to = { 0, 100 };
::select( 0, 0, 0, 0, &to );
}
// char dummy;
// while( ::read( init_done_lock_fd, &dummy, sizeof(char) ) == 0 );
if( break_or_continue )
debugger_break();
return true;
#else // ****************************************************** default
return false;
#endif
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** switch on/off detect memory leaks feature ************** //
// ************************************************************************** //
void
detect_memory_leaks( bool on_off )
{
unit_test::ut_detail::ignore_unused_variable_warning( on_off );
#ifdef BOOST_MS_CRT_BASED_DEBUG
int flags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
if( !on_off )
flags &= ~_CRTDBG_LEAK_CHECK_DF;
else {
flags |= _CRTDBG_LEAK_CHECK_DF;
_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
}
_CrtSetDbgFlag ( flags );
#endif // BOOST_MS_CRT_BASED_DEBUG
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** cause program to break execution in ************** //
// ************** debugger at specific allocation point ************** //
// ************************************************************************** //
void
break_memory_alloc( long mem_alloc_order_num )
{
unit_test::ut_detail::ignore_unused_variable_warning( mem_alloc_order_num );
#ifdef BOOST_MS_CRT_BASED_DEBUG
_CrtSetBreakAlloc( mem_alloc_order_num );
#endif // BOOST_MS_CRT_BASED_DEBUG
}
} // namespace debug
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_DEBUG_API_IPP_112006GER

View File

@@ -0,0 +1,537 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 49312 $
//
// Description : Facilities to perform exception safety tests
// ***************************************************************************
#ifndef BOOST_TEST_EXECUTION_SAFETY_IPP_112005GER
#define BOOST_TEST_EXECUTION_SAFETY_IPP_112005GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#if BOOST_TEST_SUPPORT_INTERACTION_TESTING
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/utils/iterator/token_iterator.hpp>
#include <boost/test/interaction_based.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/test_observer.hpp>
#include <boost/test/debug.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// Boost
#include <boost/lexical_cast.hpp>
// STL
#include <vector>
#include <cstdlib>
#include <map>
#include <iomanip>
#include <cctype>
#include <boost/limits.hpp>
//____________________________________________________________________________//
namespace boost {
using namespace ::boost::unit_test;
namespace itest {
// ************************************************************************** //
// ************** execution_path_point ************** //
// ************************************************************************** //
enum exec_path_point_type { EPP_SCOPE, EPP_EXCEPT, EPP_DECISION, EPP_ALLOC };
struct execution_path_point {
execution_path_point( exec_path_point_type t, const_string file, std::size_t line_num )
: m_type( t )
, m_file_name( file )
, m_line_num( line_num )
{}
exec_path_point_type m_type;
const_string m_file_name;
std::size_t m_line_num;
// Execution path point specific
struct decision_data {
bool value;
unsigned forced_exception_point;
};
struct scope_data {
unsigned size;
char const* name;
};
struct except_data {
char const* description;
};
struct alloc_data {
void* ptr;
std::size_t size;
};
union {
struct decision_data m_decision;
struct scope_data m_scope;
struct except_data m_except;
struct alloc_data m_alloc;
};
};
// ************************************************************************** //
// ************** exception safety test implementation ************** //
// ************************************************************************** //
struct exception_safety_tester : itest::manager, test_observer {
// helpers types
struct unique_exception {};
// Constructor
explicit exception_safety_tester( const_string test_name );
~exception_safety_tester();
// check last run and prepare for next
bool next_execution_path();
// memory tracking
// manager interface implementation
virtual void exception_point( const_string file, std::size_t line_num, const_string description );
virtual bool decision_point( const_string file, std::size_t line_num );
virtual unsigned enter_scope( const_string file, std::size_t line_num, const_string scope_name );
virtual void leave_scope( unsigned enter_scope_point );
virtual void allocated( const_string file, std::size_t line_num, void* p, std::size_t s );
virtual void freed( void* p );
// test observer interface
virtual void assertion_result( bool passed );
virtual int priority() { return (std::numeric_limits<int>::max)(); } // we want this observer to run the last
private:
void failure_point();
void report_error();
typedef std::vector<execution_path_point> exec_path;
typedef std::map<void*,unsigned> registry;
// Data members
bool m_internal_activity;
unsigned m_exception_point_counter;
unsigned m_forced_exception_point;
unsigned m_exec_path_point;
exec_path m_execution_path;
unsigned m_exec_path_counter;
unsigned m_break_exec_path;
bool m_invairant_failed;
registry m_memory_in_use;
};
//____________________________________________________________________________//
struct activity_guard {
bool& m_v;
activity_guard( bool& v ) : m_v( v ) { m_v = true; }
~activity_guard() { m_v = false; }
};
//____________________________________________________________________________//
exception_safety_tester::exception_safety_tester( const_string test_name )
: m_internal_activity( true )
, m_exception_point_counter( 0 )
, m_forced_exception_point( 1 )
, m_exec_path_point( 0 )
, m_exec_path_counter( 1 )
, m_break_exec_path( (unsigned)-1 )
, m_invairant_failed( false )
{
framework::register_observer( *this );
if( !runtime_config::break_exec_path().is_empty() ) {
using namespace unit_test;
string_token_iterator tit( runtime_config::break_exec_path(),
(dropped_delimeters = ":",kept_delimeters = " ") );
const_string test_to_break = *tit;
if( test_to_break == test_name ) {
++tit;
m_break_exec_path = lexical_cast<unsigned>( *tit );
}
}
m_internal_activity = false;
}
//____________________________________________________________________________//
exception_safety_tester::~exception_safety_tester()
{
m_internal_activity = true;
framework::deregister_observer( *this );
}
//____________________________________________________________________________//
bool
exception_safety_tester::next_execution_path()
{
activity_guard ag( m_internal_activity );
// check memory usage
if( m_execution_path.size() > 0 ) {
bool errors_detected = m_invairant_failed || (m_memory_in_use.size() != 0);
framework::assertion_result( !errors_detected );
if( errors_detected )
report_error();
m_memory_in_use.clear();
}
m_exec_path_point = 0;
m_exception_point_counter = 0;
m_invairant_failed = false;
++m_exec_path_counter;
while( m_execution_path.size() > 0 ) {
switch( m_execution_path.back().m_type ) {
case EPP_SCOPE:
case EPP_ALLOC:
m_execution_path.pop_back();
break;
case EPP_DECISION:
if( !m_execution_path.back().m_decision.value ) {
m_execution_path.pop_back();
break;
}
m_execution_path.back().m_decision.value = false;
m_forced_exception_point = m_execution_path.back().m_decision.forced_exception_point;
return true;
case EPP_EXCEPT:
m_execution_path.pop_back();
++m_forced_exception_point;
return true;
}
}
BOOST_TEST_MESSAGE( "Total tested " << --m_exec_path_counter << " execution path" );
return false;
}
//____________________________________________________________________________//
void
exception_safety_tester::exception_point( const_string file, std::size_t line_num, const_string description )
{
activity_guard ag( m_internal_activity );
if( ++m_exception_point_counter == m_forced_exception_point ) {
m_execution_path.push_back(
execution_path_point( EPP_EXCEPT, file, line_num ) );
m_execution_path.back().m_except.description = description.begin();
++m_exec_path_point;
failure_point();
}
}
//____________________________________________________________________________//
bool
exception_safety_tester::decision_point( const_string file, std::size_t line_num )
{
activity_guard ag( m_internal_activity );
if( m_exec_path_point < m_execution_path.size() ) {
BOOST_REQUIRE_MESSAGE( m_execution_path[m_exec_path_point].m_type == EPP_DECISION &&
m_execution_path[m_exec_path_point].m_file_name == file &&
m_execution_path[m_exec_path_point].m_line_num == line_num,
"Function under test exibit non-deterministic behavior" );
}
else {
m_execution_path.push_back(
execution_path_point( EPP_DECISION, file, line_num ) );
m_execution_path.back().m_decision.value = true;
m_execution_path.back().m_decision.forced_exception_point = m_forced_exception_point;
}
return m_execution_path[m_exec_path_point++].m_decision.value;
}
//____________________________________________________________________________//
unsigned
exception_safety_tester::enter_scope( const_string file, std::size_t line_num, const_string scope_name )
{
activity_guard ag( m_internal_activity );
if( m_exec_path_point < m_execution_path.size() ) {
BOOST_REQUIRE_MESSAGE( m_execution_path[m_exec_path_point].m_type == EPP_SCOPE &&
m_execution_path[m_exec_path_point].m_file_name == file &&
m_execution_path[m_exec_path_point].m_line_num == line_num,
"Function under test exibit non-deterministic behavior" );
}
else {
m_execution_path.push_back(
execution_path_point( EPP_SCOPE, file, line_num ) );
}
m_execution_path[m_exec_path_point].m_scope.size = 0;
m_execution_path[m_exec_path_point].m_scope.name = scope_name.begin();
return m_exec_path_point++;
}
//____________________________________________________________________________//
void
exception_safety_tester::leave_scope( unsigned enter_scope_point )
{
activity_guard ag( m_internal_activity );
BOOST_REQUIRE_MESSAGE( m_execution_path[enter_scope_point].m_type == EPP_SCOPE,
"Function under test exibit non-deterministic behavior" );
m_execution_path[enter_scope_point].m_scope.size = m_exec_path_point - enter_scope_point;
}
//____________________________________________________________________________//
void
exception_safety_tester::allocated( const_string file, std::size_t line_num, void* p, std::size_t s )
{
if( m_internal_activity )
return;
activity_guard ag( m_internal_activity );
if( m_exec_path_point < m_execution_path.size() )
BOOST_REQUIRE_MESSAGE( m_execution_path[m_exec_path_point].m_type == EPP_ALLOC,
"Function under test exibit non-deterministic behavior" );
else
m_execution_path.push_back(
execution_path_point( EPP_ALLOC, file, line_num ) );
m_execution_path[m_exec_path_point].m_alloc.ptr = p;
m_execution_path[m_exec_path_point].m_alloc.size = s;
m_memory_in_use.insert( std::make_pair( p, m_exec_path_point++ ) );
}
//____________________________________________________________________________//
void
exception_safety_tester::freed( void* p )
{
if( m_internal_activity )
return;
activity_guard ag( m_internal_activity );
registry::iterator it = m_memory_in_use.find( p );
if( it != m_memory_in_use.end() ) {
m_execution_path[it->second].m_alloc.ptr = 0;
m_memory_in_use.erase( it );
}
}
//____________________________________________________________________________//
void
exception_safety_tester::assertion_result( bool passed )
{
if( !m_internal_activity && !passed ) {
m_invairant_failed = true;
failure_point();
}
}
//____________________________________________________________________________//
void
exception_safety_tester::failure_point()
{
if( m_exec_path_counter == m_break_exec_path )
debug::debugger_break();
throw unique_exception();
}
//____________________________________________________________________________//
namespace {
inline void
format_location( wrap_stringstream& formatter, execution_path_point const& /*p*/, unsigned indent )
{
if( indent )
formatter << std::left << std::setw( indent ) << "";
// !! ?? optional if( p.m_file_name )
// formatter << p.m_file_name << '(' << p.m_line_num << "): ";
}
//____________________________________________________________________________//
template<typename ExecPathIt>
inline void
format_execution_path( wrap_stringstream& formatter, ExecPathIt it, ExecPathIt end, unsigned indent = 0 )
{
while( it != end ) {
switch( it->m_type ) {
case EPP_SCOPE:
format_location( formatter, *it, indent );
formatter << "> \"" << it->m_scope.name << "\"\n";
format_execution_path( formatter, it+1, it + it->m_scope.size, indent + 2 );
format_location( formatter, *it, indent );
formatter << "< \"" << it->m_scope.name << "\"\n";
it += it->m_scope.size;
break;
case EPP_DECISION:
format_location( formatter, *it, indent );
formatter << "Decision made as " << std::boolalpha << it->m_decision.value << '\n';
++it;
break;
case EPP_EXCEPT:
format_location( formatter, *it, indent );
formatter << "Forced failure";
if( it->m_except.description )
formatter << ": " << it->m_except.description;
formatter << "\n";
++it;
break;
case EPP_ALLOC:
if( it->m_alloc.ptr ) {
format_location( formatter, *it, indent );
formatter << "Allocated memory block 0x" << std::uppercase << it->m_alloc.ptr
<< ", " << it->m_alloc.size << " bytes long: <";
unsigned i;
for( i = 0; i < std::min<std::size_t>( it->m_alloc.size, 8 ); i++ ) {
unsigned char c = ((unsigned char*)it->m_alloc.ptr)[i];
if( (std::isprint)( c ) )
formatter << c;
else
formatter << '.';
}
formatter << "> ";
for( i = 0; i < std::min<std::size_t>( it->m_alloc.size, 8 ); i++ ) {
unsigned c = ((unsigned char*)it->m_alloc.ptr)[i];
formatter << std::hex << std::uppercase << c << ' ';
}
formatter << "\n";
}
++it;
break;
}
}
}
//____________________________________________________________________________//
} // local namespace
void
exception_safety_tester::report_error()
{
activity_guard ag( m_internal_activity );
unit_test_log << unit_test::log::begin( m_execution_path.back().m_file_name,
m_execution_path.back().m_line_num )
<< log_all_errors;
wrap_stringstream formatter;
if( m_invairant_failed )
formatter << "Failed invariant";
if( m_memory_in_use.size() != 0 ) {
if( m_invairant_failed )
formatter << " and ";
formatter << (unsigned int)m_memory_in_use.size() << " memory leak";
if( m_memory_in_use.size() > 1 )
formatter << 's';
}
formatter << " detected in the execution path " << m_exec_path_counter << ":\n";
format_execution_path( formatter, m_execution_path.begin(), m_execution_path.end() );
unit_test_log << const_string( formatter.str() ) << unit_test::log::end();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** exception safety test ************** //
// ************************************************************************** //
void BOOST_TEST_DECL
exception_safety( callback0<> const& F, const_string test_name )
{
exception_safety_tester est( test_name );
do {
try {
F();
}
catch( exception_safety_tester::unique_exception const& ) {}
} while( est.next_execution_path() );
}
//____________________________________________________________________________//
} // namespace itest
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // non-ancient compiler
#endif // BOOST_TEST_EXECUTION_SAFETY_IPP_112005GER

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,503 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : implements framework API - main driver for the test
// ***************************************************************************
#ifndef BOOST_TEST_FRAMEWORK_IPP_021005GER
#define BOOST_TEST_FRAMEWORK_IPP_021005GER
// Boost.Test
#include <boost/test/framework.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/debug.hpp>
#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/unit_test_monitor.hpp>
#include <boost/test/test_observer.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/progress_monitor.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/foreach.hpp>
// Boost
#include <boost/timer.hpp>
// STL
#include <map>
#include <set>
#include <cstdlib>
#include <ctime>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::time; using ::srand; }
#endif
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_start calls wrapper ************** //
// ************************************************************************** //
namespace ut_detail {
struct test_start_caller {
test_start_caller( test_observer* to, counter_t tc_amount )
: m_to( to )
, m_tc_amount( tc_amount )
{}
int operator()()
{
m_to->test_start( m_tc_amount );
return 0;
}
private:
// Data members
test_observer* m_to;
counter_t m_tc_amount;
};
//____________________________________________________________________________//
struct test_init_caller {
explicit test_init_caller( init_unit_test_func init_func )
: m_init_func( init_func )
{}
int operator()()
{
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
if( !(*m_init_func)() )
throw std::runtime_error( "test module initialization failed" );
#else
test_suite* manual_test_units = (*m_init_func)( framework::master_test_suite().argc, framework::master_test_suite().argv );
if( manual_test_units )
framework::master_test_suite().add( manual_test_units );
#endif
return 0;
}
// Data members
init_unit_test_func m_init_func;
};
}
// ************************************************************************** //
// ************** framework ************** //
// ************************************************************************** //
class framework_impl : public test_tree_visitor {
public:
framework_impl()
: m_master_test_suite( 0 )
, m_curr_test_case( INV_TEST_UNIT_ID )
, m_next_test_case_id( MIN_TEST_CASE_ID )
, m_next_test_suite_id( MIN_TEST_SUITE_ID )
, m_is_initialized( false )
, m_test_in_progress( false )
{}
~framework_impl() { clear(); }
void clear()
{
while( !m_test_units.empty() ) {
test_unit_store::value_type const& tu = *m_test_units.begin();
// the delete will erase this element from map
if( test_id_2_unit_type( tu.second->p_id ) == tut_suite )
delete (test_suite const*)tu.second;
else
delete (test_case const*)tu.second;
}
}
void set_tu_id( test_unit& tu, test_unit_id id ) { tu.p_id.value = id; }
// test_tree_visitor interface implementation
void visit( test_case const& tc )
{
if( !tc.check_dependencies() ) {
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_unit_skipped( tc );
return;
}
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_unit_start( tc );
boost::timer tc_timer;
test_unit_id bkup = m_curr_test_case;
m_curr_test_case = tc.p_id;
unit_test_monitor_t::error_level run_result = unit_test_monitor.execute_and_translate( tc );
unsigned long elapsed = static_cast<unsigned long>( tc_timer.elapsed() * 1e6 );
if( unit_test_monitor.is_critical_error( run_result ) ) {
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_aborted();
}
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_unit_finish( tc, elapsed );
m_curr_test_case = bkup;
if( unit_test_monitor.is_critical_error( run_result ) )
throw test_being_aborted();
}
bool test_suite_start( test_suite const& ts )
{
if( !ts.check_dependencies() ) {
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_unit_skipped( ts );
return false;
}
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_unit_start( ts );
return true;
}
void test_suite_finish( test_suite const& ts )
{
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
to->test_unit_finish( ts, 0 );
}
//////////////////////////////////////////////////////////////////
struct priority_order {
bool operator()( test_observer* lhs, test_observer* rhs ) const
{
return (lhs->priority() < rhs->priority()) || ((lhs->priority() == rhs->priority()) && (lhs < rhs));
}
};
typedef std::map<test_unit_id,test_unit*> test_unit_store;
typedef std::set<test_observer*,priority_order> observer_store;
master_test_suite_t* m_master_test_suite;
test_unit_id m_curr_test_case;
test_unit_store m_test_units;
test_unit_id m_next_test_case_id;
test_unit_id m_next_test_suite_id;
bool m_is_initialized;
bool m_test_in_progress;
observer_store m_observers;
};
//____________________________________________________________________________//
namespace {
framework_impl& s_frk_impl() { static framework_impl the_inst; return the_inst; }
} // local namespace
//____________________________________________________________________________//
namespace framework {
void
init( init_unit_test_func init_func, int argc, char* argv[] )
{
runtime_config::init( &argc, argv );
// set the log level and format
unit_test_log.set_threshold_level( runtime_config::log_level() );
unit_test_log.set_format( runtime_config::log_format() );
// set the report level and format
results_reporter::set_level( runtime_config::report_level() );
results_reporter::set_format( runtime_config::report_format() );
register_observer( results_collector );
register_observer( unit_test_log );
if( runtime_config::show_progress() )
register_observer( progress_monitor );
if( runtime_config::detect_memory_leaks() > 0 ) {
debug::detect_memory_leaks( true );
debug::break_memory_alloc( runtime_config::detect_memory_leaks() );
}
// init master unit test suite
master_test_suite().argc = argc;
master_test_suite().argv = argv;
try {
boost::execution_monitor em;
ut_detail::test_init_caller tic( init_func );
em.execute( tic );
}
catch( execution_exception const& ex ) {
throw setup_error( ex.what() );
}
s_frk_impl().m_is_initialized = true;
}
//____________________________________________________________________________//
bool
is_initialized()
{
return s_frk_impl().m_is_initialized;
}
//____________________________________________________________________________//
void
register_test_unit( test_case* tc )
{
if( tc->p_id != INV_TEST_UNIT_ID )
throw setup_error( BOOST_TEST_L( "test case already registered" ) );
test_unit_id new_id = s_frk_impl().m_next_test_case_id;
if( new_id == MAX_TEST_CASE_ID )
throw setup_error( BOOST_TEST_L( "too many test cases" ) );
typedef framework_impl::test_unit_store::value_type map_value_type;
s_frk_impl().m_test_units.insert( map_value_type( new_id, tc ) );
s_frk_impl().m_next_test_case_id++;
s_frk_impl().set_tu_id( *tc, new_id );
}
//____________________________________________________________________________//
void
register_test_unit( test_suite* ts )
{
if( ts->p_id != INV_TEST_UNIT_ID )
throw setup_error( BOOST_TEST_L( "test suite already registered" ) );
test_unit_id new_id = s_frk_impl().m_next_test_suite_id;
if( new_id == MAX_TEST_SUITE_ID )
throw setup_error( BOOST_TEST_L( "too many test suites" ) );
typedef framework_impl::test_unit_store::value_type map_value_type;
s_frk_impl().m_test_units.insert( map_value_type( new_id, ts ) );
s_frk_impl().m_next_test_suite_id++;
s_frk_impl().set_tu_id( *ts, new_id );
}
//____________________________________________________________________________//
void
deregister_test_unit( test_unit* tu )
{
s_frk_impl().m_test_units.erase( tu->p_id );
}
//____________________________________________________________________________//
void
clear()
{
s_frk_impl().clear();
}
//____________________________________________________________________________//
void
register_observer( test_observer& to )
{
s_frk_impl().m_observers.insert( &to );
}
//____________________________________________________________________________//
void
deregister_observer( test_observer& to )
{
s_frk_impl().m_observers.erase( &to );
}
//____________________________________________________________________________//
void
reset_observers()
{
s_frk_impl().m_observers.clear();
}
//____________________________________________________________________________//
master_test_suite_t&
master_test_suite()
{
if( !s_frk_impl().m_master_test_suite )
s_frk_impl().m_master_test_suite = new master_test_suite_t;
return *s_frk_impl().m_master_test_suite;
}
//____________________________________________________________________________//
test_case const&
current_test_case()
{
return get<test_case>( s_frk_impl().m_curr_test_case );
}
//____________________________________________________________________________//
test_unit&
get( test_unit_id id, test_unit_type t )
{
test_unit* res = s_frk_impl().m_test_units[id];
if( (res->p_type & t) == 0 )
throw internal_error( "Invalid test unit type" );
return *res;
}
//____________________________________________________________________________//
void
run( test_unit_id id, bool continue_test )
{
if( id == INV_TEST_UNIT_ID )
id = master_test_suite().p_id;
test_case_counter tcc;
traverse_test_tree( id, tcc );
if( tcc.p_count == 0 )
throw setup_error( runtime_config::test_to_run().is_empty()
? BOOST_TEST_L( "test tree is empty" )
: BOOST_TEST_L( "no test cases matching filter" ) );
bool call_start_finish = !continue_test || !s_frk_impl().m_test_in_progress;
bool was_in_progress = s_frk_impl().m_test_in_progress;
s_frk_impl().m_test_in_progress = true;
if( call_start_finish ) {
BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers ) {
boost::execution_monitor em;
try {
em.execute( ut_detail::test_start_caller( to, tcc.p_count ) );
}
catch( execution_exception const& ex ) {
throw setup_error( ex.what() );
}
}
}
switch( runtime_config::random_seed() ) {
case 0:
break;
case 1: {
unsigned int seed = (unsigned int)std::time( 0 );
BOOST_TEST_MESSAGE( "Test cases order is shuffled using seed: " << seed );
std::srand( seed );
break;
}
default:
BOOST_TEST_MESSAGE( "Test cases order is shuffled using seed: " << runtime_config::random_seed() );
std::srand( runtime_config::random_seed() );
}
try {
traverse_test_tree( id, s_frk_impl() );
}
catch( test_being_aborted const& ) {
// abort already reported
}
if( call_start_finish ) {
BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
to->test_finish();
}
s_frk_impl().m_test_in_progress = was_in_progress;
}
//____________________________________________________________________________//
void
run( test_unit const* tu, bool continue_test )
{
run( tu->p_id, continue_test );
}
//____________________________________________________________________________//
void
assertion_result( bool passed )
{
BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
to->assertion_result( passed );
}
//____________________________________________________________________________//
void
exception_caught( execution_exception const& ex )
{
BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
to->exception_caught( ex );
}
//____________________________________________________________________________//
void
test_unit_aborted( test_unit const& tu )
{
BOOST_TEST_FOREACH( test_observer*, to, s_frk_impl().m_observers )
to->test_unit_aborted( tu );
}
//____________________________________________________________________________//
} // namespace framework
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_FRAMEWORK_IPP_021005GER

View File

@@ -0,0 +1,91 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to the
// Boost Software License, Version 1.0. (See accompanying file
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 49312 $
//
// Description : Facilities to perform interaction-based testing
// ***************************************************************************
#ifndef BOOST_TEST_INTERACTION_BASED_IPP_112105GER
#define BOOST_TEST_INTERACTION_BASED_IPP_112105GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#if BOOST_TEST_SUPPORT_INTERACTION_TESTING
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/interaction_based.hpp>
#include <boost/test/mock_object.hpp>
#include <boost/test/framework.hpp> // for setup_error
#include <boost/test/detail/suppress_warnings.hpp>
// STL
#include <stdexcept>
#include <string>
//____________________________________________________________________________//
namespace boost {
namespace itest { // interaction-based testing
// ************************************************************************** //
// ************** manager ************** //
// ************************************************************************** //
manager::manager()
{
instance_ptr( true, this );
}
//____________________________________________________________________________//
manager::~manager()
{
instance_ptr( true );
}
//____________________________________________________________________________//
manager*
manager::instance_ptr( bool reset, manager* new_ptr )
{
static manager dummy( 0 );
static manager* ptr = &dummy;
if( reset ) {
if( new_ptr ) {
if( ptr != &dummy )
throw unit_test::framework::setup_error( BOOST_TEST_L( "Couldn't run two interation based test the same time" ) );
ptr = new_ptr;
}
else
ptr = &dummy;
}
return ptr;
}
} // namespace itest
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // not ancient compiler
#endif // BOOST_TEST_INTERACTION_BASED_IPP_112105GER

View File

@@ -0,0 +1,246 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to the
// Boost Software License, ELOG_VER 1.0. (See accompanying file
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 49312 $
//
// Description : Facilities to perform interaction based testng of logged expectations
// ***************************************************************************
#ifndef BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
#define BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#if BOOST_TEST_SUPPORT_INTERACTION_TESTING
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/utils/iterator/token_iterator.hpp>
#include <boost/test/interaction_based.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// Boost
#include <boost/lexical_cast.hpp>
// STL
#include <fstream>
//____________________________________________________________________________//
namespace boost {
using namespace ::boost::unit_test;
namespace itest {
// ************************************************************************** //
// ************** logged expectation test implementation ************** //
// ************************************************************************** //
struct expectations_logger : itest::manager {
// Constructor
expectations_logger( const_string log_file_name, bool test_or_log );
virtual bool decision_point( const_string, std::size_t );
virtual unsigned enter_scope( const_string, std::size_t, const_string scope_name );
virtual void allocated( const_string, std::size_t, void*, std::size_t s );
virtual void data_flow( const_string d );
virtual std::string return_value( const_string default_value );
private:
// Data members
bool m_test_or_log;
std::fstream m_log_file;
};
literal_string ELOG_VER = "1.0";
literal_string CLMN_SEP = "|";
static const char LINE_SEP = '\n';
literal_string FILE_SIG = "ELOG";
literal_string SCOPE_SIG = "SCOPE";
literal_string ALLOC_SIG = "ALLOC";
literal_string DP_SIG = "SWITCH";
literal_string DATA_SIG = "DATA";
literal_string RETURN_SIG = "RETURN";
//____________________________________________________________________________//
expectations_logger::expectations_logger( const_string log_file_name, bool test_or_log )
: m_test_or_log( test_or_log )
{
BOOST_REQUIRE_MESSAGE( !log_file_name.is_empty(), "Empty expectations log file name" );
m_log_file.open( log_file_name.begin(), test_or_log ? std::ios::in : std::ios::out );
BOOST_REQUIRE_MESSAGE( m_log_file.is_open(),
"Couldn't open expectations log file " << log_file_name
<< " for " << ( m_test_or_log ? "reading" : "writing") );
if( m_test_or_log ) {
std::string line;
std::getline( m_log_file, line, LINE_SEP );
const_string cline( line );
string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
BOOST_CHECK_EQUAL( *tit, FILE_SIG );
++tit;
BOOST_CHECK_EQUAL( *tit, ELOG_VER );
}
else {
m_log_file << FILE_SIG << CLMN_SEP << ELOG_VER << LINE_SEP;
}
}
//____________________________________________________________________________//
bool
expectations_logger::decision_point( const_string, std::size_t )
{
if( m_test_or_log ) {
std::string line;
std::getline( m_log_file, line, LINE_SEP );
const_string cline( line );
string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
BOOST_CHECK_EQUAL( *tit, DP_SIG ); ++tit;
return lexical_cast<bool>( *tit );
}
else {
m_log_file << DP_SIG << CLMN_SEP << std::boolalpha << true << LINE_SEP;
return true;
}
}
//____________________________________________________________________________//
unsigned
expectations_logger::enter_scope( const_string, std::size_t, const_string scope_name )
{
if( m_test_or_log ) {
std::string line;
std::getline( m_log_file, line, LINE_SEP );
const_string cline( line );
string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
BOOST_CHECK_EQUAL( *tit, SCOPE_SIG ); ++tit;
BOOST_CHECK_EQUAL( *tit, scope_name );
}
else {
m_log_file << SCOPE_SIG << CLMN_SEP << scope_name << LINE_SEP;
}
return 0;
}
//____________________________________________________________________________//
void
expectations_logger::allocated( const_string, std::size_t, void*, std::size_t s )
{
if( m_test_or_log ) {
std::string line;
std::getline( m_log_file, line, LINE_SEP );
const_string cline( line );
string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
BOOST_CHECK_EQUAL( *tit, ALLOC_SIG ); ++tit;
BOOST_CHECK_EQUAL( lexical_cast<std::size_t>( *tit ), s );
}
else {
m_log_file << ALLOC_SIG << CLMN_SEP << s << LINE_SEP;
}
}
//____________________________________________________________________________//
void
expectations_logger::data_flow( const_string d )
{
if( m_test_or_log ) {
std::string line;
std::getline( m_log_file, line, LINE_SEP );
const_string cline( line );
string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
BOOST_CHECK_EQUAL( *tit, DATA_SIG ); ++tit;
BOOST_CHECK_EQUAL( *tit, d );
}
else {
m_log_file << DATA_SIG << CLMN_SEP << d << LINE_SEP;
}
}
//____________________________________________________________________________//
std::string
expectations_logger::return_value( const_string default_value )
{
if( m_test_or_log ) {
std::string line;
std::getline( m_log_file, line, LINE_SEP );
const_string cline( line );
string_token_iterator tit( cline, (dropped_delimeters = CLMN_SEP, kept_delimeters = dt_none));
BOOST_CHECK_EQUAL( *tit, RETURN_SIG ); ++tit;
return std::string( tit->begin(), tit->size() );
}
else {
m_log_file << RETURN_SIG << CLMN_SEP << default_value << LINE_SEP;
return std::string();
}
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** logged expectations test ************** //
// ************************************************************************** //
void BOOST_TEST_DECL
logged_expectations( callback0<> const& F, const_string log_file_name, bool test_or_log )
{
expectations_logger el( log_file_name, test_or_log );
F();
}
//____________________________________________________________________________//
} // namespace itest
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // not ancient compiler
#endif // BOOST_TEST_LOGGED_EXPECTATIONS_IPP_120905GER

View File

@@ -0,0 +1,198 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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_suite_impl.hpp>
#include <boost/test/utils/basic_cstring/io.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 custom_manip<struct quote_t> quote;
template<typename T>
inline std::ostream&
operator<<( 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 ) {
ostr << std::setw( indent ) << ""
<< v << ' ' << name << ( v != 1 ? "s" : "" );
if( total > 0 )
ostr << " out of " << total;
ostr << ' ' << res << '\n';
}
}
//____________________________________________________________________________//
} // local namespace
// ************************************************************************** //
// ************** plain_report_formatter ************** //
// ************************************************************************** //
void
plain_report_formatter::results_report_start( std::ostream& ostr )
{
m_indent = 0;
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 = "passed";
else if( tr.p_skipped )
descr = "skipped";
else if( tr.p_aborted )
descr = "aborted";
else
descr = "failed";
ostr << std::setw( m_indent ) << ""
<< "Test " << (tu.p_type == tut_case ? "case " : "suite " ) << quote() << tu.p_name << ' ' << descr;
if( tr.p_skipped ) {
ostr << " due to " << (tu.check_dependencies() ? "test aborting\n" : "failed dependancy\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_failed + tr.p_test_cases_skipped;
if( total_assertions > 0 || total_tc > 0 )
ostr << " with:";
ostr << '\n';
m_indent += 2;
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_expected_failures, m_indent, 0 , "failure" , "expected" );
print_stat_value( ostr, tr.p_test_cases_passed, m_indent, total_tc , "test case", "passed" );
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" );
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() ) {
ostr << "*** No errors detected\n";
return;
}
if( tr.p_skipped ) {
ostr << "*** Test " << tu.p_type_name << " skipped due to "
<< (tu.check_dependencies() ? "test aborting\n" : "failed dependancy\n" );
return;
}
if( tr.p_assertions_failed == 0 ) {
ostr << "*** errors detected in test " << tu.p_type_name << " " << quote() << tu.p_name
<< "; see standard output for details\n";
return;
}
counter_t num_failures = tr.p_assertions_failed;
ostr << "*** " << num_failures << " failure" << ( num_failures != 1 ? "s" : "" ) << " detected";
if( tr.p_expected_failures > 0 )
ostr << " (" << tr.p_expected_failures << " failure" << ( tr.p_expected_failures != 1 ? "s" : "" ) << " expected)";
ostr << " in test " << tu.p_type_name << " " << quote() << tu.p_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,108 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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_suite_impl.hpp>
// Boost
#include <boost/progress.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** progress_monitor ************** //
// ************************************************************************** //
namespace {
struct progress_monitor_impl {
// Constructor
progress_monitor_impl()
: m_stream( &std::cout )
{}
std::ostream* m_stream;
scoped_ptr<progress_display> m_progress_display;
};
progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; return the_inst; }
} // local namespace
//____________________________________________________________________________//
void
progress_monitor_t::test_start( counter_t test_cases_amount )
{
s_pm_impl().m_progress_display.reset( new progress_display( test_cases_amount, *s_pm_impl().m_stream ) );
}
//____________________________________________________________________________//
void
progress_monitor_t::test_aborted()
{
(*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 )
{
if( tu.p_type == tut_case )
++(*s_pm_impl().m_progress_display);
}
//____________________________________________________________________________//
void
progress_monitor_t::test_unit_skipped( test_unit const& tu )
{
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;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER

View File

@@ -0,0 +1,294 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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_suite_impl.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/framework.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_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_test_cases_passed.value += tr.p_test_cases_passed;
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_expected_failures.value = 0;
p_test_cases_passed.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 = true;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** results_collector ************** //
// ************************************************************************** //
#if !BOOST_WORKAROUND(BOOST_MSVC, <1300)
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
#else
struct results_collector_impl {
std::map<test_unit_id,test_results> m_results_store;
};
static results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
#endif
//____________________________________________________________________________//
void
results_collector_t::test_start( counter_t )
{
s_rc_impl().m_results_store.clear();
}
//____________________________________________________________________________//
void
results_collector_t::test_finish()
{
// do nothing
}
//____________________________________________________________________________//
void
results_collector_t::test_aborted()
{
// do nothing
}
//____________________________________________________________________________//
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;
tr.p_skipped.value = false;
}
//____________________________________________________________________________//
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() )
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;
else {
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.p_name << " has fewer failures than expected" );
bool has_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
if( !has_any_assertions )
BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " doesn't include any assertions" );
}
}
//____________________________________________________________________________//
void
results_collector_t::test_unit_skipped( test_unit const& tu )
{
if( tu.p_type == tut_suite ) {
test_case_counter tcc;
traverse_test_tree( tu, tcc );
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
tr.clear();
tr.p_skipped.value = true;
tr.p_test_cases_skipped.value = tcc.p_count;
}
}
//____________________________________________________________________________//
void
results_collector_t::assertion_result( bool passed )
{
test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
if( passed )
tr.p_assertions_passed.value++;
else
tr.p_assertions_failed.value++;
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().p_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,198 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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/unit_test_suite_impl.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>
// 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_output( &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_output );
m_formatter->test_unit_report_finish( tc, *m_output );
}
bool test_suite_start( test_suite const& ts )
{
m_formatter->test_unit_report_start( ts, *m_output );
if( m_report_level == DETAILED_REPORT && !results_collector.results( ts.p_id ).p_skipped )
return true;
m_formatter->test_unit_report_finish( ts, *m_output );
return false;
}
void test_suite_finish( test_suite const& ts )
{
m_formatter->test_unit_report_finish( ts, *m_output );
}
typedef scoped_ptr<io_saver_type> saver_ptr;
// Data members
std::ostream* m_output;
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_output = &ostr;
s_rr_impl().m_stream_state_saver.reset( new io_saver_type( ostr ) );
}
//____________________________________________________________________________//
std::ostream&
get_stream()
{
return *s_rr_impl().m_output;
}
//____________________________________________________________________________//
void
set_format( output_format rf )
{
switch( rf ) {
case CLF:
set_format( new output::plain_report_formatter );
break;
case 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_output );
switch( l ) {
case CONFIRMATION_REPORT:
s_rr_impl().m_formatter->do_confirmation_report( framework::get<test_unit>( id ), *s_rr_impl().m_output );
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_output );
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,68 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// (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: 49312 $
//
// Description : 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,630 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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/test_tools.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/output_test_stream.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/execution_monitor.hpp> // execution_aborted
#include <boost/test/unit_test_suite_impl.hpp>
// Boost
#include <boost/config.hpp>
// STL
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
#include <cwchar>
#include <stdexcept>
#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 {
// ************************************************************************** //
// ************** print_log_value ************** //
// ************************************************************************** //
void
print_log_value<char>::operator()( std::ostream& ostr, char t )
{
if( (std::isprint)( (unsigned char)t ) )
ostr << '\'' << t << '\'';
else
ostr << std::hex
#if BOOST_TEST_USE_STD_LOCALE
<< std::showbase
#else
<< "0x"
#endif
<< (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
<< (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" );
}
//____________________________________________________________________________//
namespace tt_detail {
// ************************************************************************** //
// ************** TOOL BOX Implementation ************** //
// ************************************************************************** //
using ::boost::unit_test::lazy_ostream;
bool
check_impl( predicate_result const& pr, lazy_ostream const& check_descr,
const_string file_name, std::size_t line_num,
tool_level tl, check_type ct,
std::size_t num_of_args, ... )
{
using namespace unit_test;
if( !framework::is_initialized() )
throw std::runtime_error( "can't use testing tools before framework is initialized" );
if( !!pr )
tl = PASS;
log_level ll;
char const* prefix;
char const* suffix;
switch( tl ) {
case PASS:
ll = log_successful_tests;
prefix = "check ";
suffix = " passed";
break;
case WARN:
ll = log_warnings;
prefix = "condition ";
suffix = " is not satisfied";
break;
case CHECK:
ll = log_all_errors;
prefix = "check ";
suffix = " failed";
break;
case REQUIRE:
ll = log_fatal_errors;
prefix = "critical check ";
suffix = " failed";
break;
default:
return true;
}
switch( ct ) {
case CHECK_PRED:
unit_test_log << unit_test::log::begin( file_name, line_num )
<< ll << prefix << check_descr << suffix;
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
case CHECK_MSG:
unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
if( tl == PASS )
unit_test_log << prefix << "'" << check_descr << "'" << suffix;
else
unit_test_log << check_descr;
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
case CHECK_EQUAL:
case CHECK_NE:
case CHECK_LT:
case CHECK_LE:
case CHECK_GT:
case CHECK_GE: {
static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
va_list args;
va_start( args, num_of_args );
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
char const* arg2_descr = va_arg( args, char const* );
lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
unit_test_log << unit_test::log::begin( file_name, line_num )
<< ll << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
if( tl != PASS )
unit_test_log << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
va_end( args );
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
}
case CHECK_CLOSE:
case CHECK_CLOSE_FRACTION: {
va_list args;
va_start( args, num_of_args );
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
char const* arg2_descr = va_arg( args, char const* );
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* );
unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
unit_test_log << "difference between " << arg1_descr << "{" << *arg1_val << "}"
<< " and " << arg2_descr << "{" << *arg2_val << "}"
<< ( tl == PASS ? " doesn't exceed " : " exceeds " )
<< *toler_val;
if( ct == CHECK_CLOSE )
unit_test_log << "%";
va_end( args );
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
}
case CHECK_SMALL: {
va_list args;
va_start( args, num_of_args );
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
/* toler_descr = */ va_arg( args, char const* );
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
unit_test_log << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
<< ( tl == PASS ? " doesn't exceed " : " exceeds " )
<< *toler_val;
va_end( args );
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
}
case CHECK_PRED_WITH_ARGS: {
unit_test_log << unit_test::log::begin( file_name, line_num )
<< ll << prefix << check_descr;
// print predicate call description
{
va_list args;
va_start( args, num_of_args );
unit_test_log << "( ";
for( std::size_t i = 0; i < num_of_args; ++i ) {
unit_test_log << va_arg( args, char const* );
va_arg( args, lazy_ostream const* ); // skip argument value;
if( i != num_of_args-1 )
unit_test_log << ", ";
}
unit_test_log << " )" << suffix;
va_end( args );
}
if( tl != PASS ) {
va_list args;
va_start( args, num_of_args );
unit_test_log << " for ( ";
for( std::size_t i = 0; i < num_of_args; ++i ) {
va_arg( args, char const* ); // skip argument description;
unit_test_log << *va_arg( args, lazy_ostream const* );
if( i != num_of_args-1 )
unit_test_log << ", ";
}
unit_test_log << " )";
va_end( args );
}
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
}
case CHECK_EQUAL_COLL: {
va_list args;
va_start( args, num_of_args );
char const* left_begin_descr = va_arg( args, char const* );
char const* left_end_descr = va_arg( args, char const* );
char const* right_begin_descr = va_arg( args, char const* );
char const* right_end_descr = va_arg( args, char const* );
unit_test_log << unit_test::log::begin( file_name, line_num )
<< ll << prefix
<< "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
<< right_begin_descr << ", " << right_end_descr << " }"
<< suffix;
va_end( args );
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
}
case CHECK_BITWISE_EQUAL: {
va_list args;
va_start( args, num_of_args );
char const* left_descr = va_arg( args, char const* );
char const* right_descr = va_arg( args, char const* );
unit_test_log << unit_test::log::begin( file_name, line_num )
<< ll << prefix << left_descr << " =.= " << right_descr << suffix;
va_end( args );
if( !pr.has_empty_message() )
unit_test_log << ". " << pr.message();
unit_test_log << unit_test::log::end();
break;
}
}
switch( tl ) {
case PASS:
framework::assertion_result( true );
return true;
case WARN:
return false;
case CHECK:
framework::assertion_result( false );
return false;
case REQUIRE:
framework::assertion_result( false );
framework::test_unit_aborted( framework::current_test_case() );
throw execution_aborted();
}
return true;
}
//____________________________________________________________________________//
predicate_result
equal_impl( char const* left, char const* right )
{
return (left && right) ? std::strcmp( left, right ) == 0 : (left == right);
}
//____________________________________________________________________________//
#if !defined( BOOST_NO_CWCHAR )
predicate_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;
}
//____________________________________________________________________________//
} // 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( predicate_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 );
BOOST_WARN_MESSAGE( m_pimpl->m_pattern.is_open(),
"Couldn'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;
}
//____________________________________________________________________________//
predicate_result
output_test_stream::is_empty( bool flush_stream )
{
sync();
result_type res( m_pimpl->m_synced_string.empty() );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
predicate_result
output_test_stream::check_length( std::size_t length_, bool flush_stream )
{
sync();
result_type res( m_pimpl->m_synced_string.length() == length_ );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
predicate_result
output_test_stream::is_equal( const_string arg, bool flush_stream )
{
sync();
result_type res( const_string( m_pimpl->m_synced_string ) == arg );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
predicate_result
output_test_stream::match_pattern( bool flush_stream )
{
sync();
result_type result( true );
if( !m_pimpl->m_pattern.is_open() ) {
result = false;
result.message() << "Pattern file could not 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 c = m_pimpl->get_char();
if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
break;
result.message() << c;
}
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,447 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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/unit_test_suite_impl.hpp>
#include <boost/test/execution_monitor.hpp>
#include <boost/test/detail/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;
// STL
#include <iostream>
#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::show_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 )
{
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 );
}
//____________________________________________________________________________//
void
unit_test_log_t::test_unit_aborted( test_unit const& )
{
// do nothing
}
//____________________________________________________________________________//
void
unit_test_log_t::assertion_result( bool )
{
// do nothing
}
//____________________________________________________________________________//
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( s_log_impl().stream(), s_log_impl().m_checkpoint_data, ex.what() );
}
}
//____________________________________________________________________________//
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 )
s_log_impl().m_log_formatter->log_entry_finish( s_log_impl().stream() );
s_log_impl().m_entry_in_progress = false;
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::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;
if( log_format == CLF )
set_formatter( new output::compiler_log_formatter );
else
set_formatter( new output::xml_log_formatter );
}
//____________________________________________________________________________//
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,242 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// 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/unit_test_suite_impl.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
#if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
#include <boost/test/utils/iterator/token_iterator.hpp>
#endif
// Boost
#include <boost/cstdlib.hpp>
#include <boost/bind.hpp>
// STL
#include <stdexcept>
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_case_filter ************** //
// ************************************************************************** //
class test_case_filter : public test_tree_visitor {
public:
struct single_filter {
single_filter( const_string in )
{
if( in == "*" )
m_kind = SFK_ALL;
else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
m_kind = SFK_SUBSTR;
m_value = in.substr( 1, in.size()-1 );
}
else if( first_char( in ) == '*' ) {
m_kind = SFK_TRAILING;
m_value = in.substr( 1 );
}
else if( last_char( in ) == '*' ) {
m_kind = SFK_LEADING;
m_value = in.substr( 0, in.size()-1 );
}
else {
m_kind = SFK_MATCH;
m_value = in;
}
};
bool pass( test_unit const& tu ) const
{
const_string name( tu.p_name );
switch( m_kind ) {
default:
case SFK_ALL:
return true;
case SFK_LEADING:
return name.substr( 0, m_value.size() ) == m_value;
case SFK_TRAILING:
return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
case SFK_SUBSTR:
return name.find( m_value ) != const_string::npos;
case SFK_MATCH:
return m_value == tu.p_name.get();
}
}
enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
kind m_kind;
const_string m_value;
};
// Constructor
#if defined(__BORLANDC__) || BOOST_WORKAROUND( BOOST_MSVC, < 1300 )
explicit test_case_filter( const_string ) : m_depth( 0 ) {}
#else
explicit test_case_filter( const_string tc_to_tun )
: m_depth( 0 )
{
string_token_iterator tit( tc_to_tun, (dropped_delimeters = "/", kept_delimeters = dt_none) );
while( tit != string_token_iterator() ) {
m_filters.push_back(
std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
string_token_iterator() ) );
++tit;
}
}
#endif
void filter_unit( test_unit const& tu )
{
if( (++m_depth - 1) > m_filters.size() ) {
tu.p_enabled.value = true;
return;
}
if( m_depth == 1 )
return;
std::vector<single_filter> const& filters = m_filters[m_depth-2];
tu.p_enabled.value =
std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end();
}
// test tree visitor interface
virtual void visit( test_case const& tc )
{
if( m_depth < m_filters.size() ) {
tc.p_enabled.value = false;
return;
}
filter_unit( tc );
--m_depth;
}
virtual bool test_suite_start( test_suite const& ts )
{
filter_unit( ts );
if( !ts.p_enabled )
--m_depth;
return ts.p_enabled;
}
virtual void test_suite_finish( test_suite const& ) { --m_depth; }
private:
// Data members
std::vector<std::vector<single_filter> > m_filters;
unsigned m_depth;
};
// ************************************************************************** //
// ************** unit_test_main ************** //
// ************************************************************************** //
int BOOST_TEST_DECL
unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
{
try {
framework::init( init_func, argc, argv );
if( !runtime_config::test_to_run().is_empty() ) {
test_case_filter filter( runtime_config::test_to_run() );
traverse_test_tree( framework::master_test_suite().p_id, filter );
}
framework::run();
results_reporter::make_report();
return runtime_config::no_result_code()
? boost::exit_success
: results_collector.results( framework::master_test_suite().p_id ).result_code();
}
catch( framework::internal_error const& ex ) {
results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
return boost::exit_exception_failure;
}
catch( framework::setup_error const& ex ) {
results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
return boost::exit_exception_failure;
}
catch( ... ) {
results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
return boost::exit_exception_failure;
}
}
} // 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,101 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// 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/unit_test_suite_impl.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace {
template<typename F>
struct zero_return_wrapper_t {
explicit zero_return_wrapper_t( F const& f ) : m_f( f ) {}
int operator()() { m_f(); return 0; }
F const& m_f;
};
template<typename F>
zero_return_wrapper_t<F>
zero_return_wrapper( F const& f )
{
return zero_return_wrapper_t<F>( f );
}
}
// ************************************************************************** //
// ************** unit_test_monitor ************** //
// ************************************************************************** //
unit_test_monitor_t::error_level
unit_test_monitor_t::execute_and_translate( test_case const& tc )
{
try {
p_catch_system_errors.value = runtime_config::catch_sys_errors();
p_timeout.value = tc.p_timeout.get();
p_auto_start_dbg.value = runtime_config::auto_start_dbg();
p_use_alt_stack.value = runtime_config::use_alt_stack();
p_detect_fp_exceptions.value = runtime_config::detect_fp_exceptions();
execute( callback0<int>( zero_return_wrapper( tc.test_func() ) ) );
}
catch( execution_exception const& 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,391 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// 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/detail/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/utils/fixed_mapping.hpp>
#include <boost/test/debug.hpp>
// Boost
#include <boost/config.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/test/detail/enable_warnings.hpp>
// STL
#include <map>
#include <cstdlib>
#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 {
// framework parameters and there corresponding command-line arguments
literal_string LOG_LEVEL = "BOOST_TEST_LOG_LEVEL";
literal_string NO_RESULT_CODE = "BOOST_TEST_RESULT_CODE";
literal_string REPORT_LEVEL = "BOOST_TEST_REPORT_LEVEL";
literal_string TESTS_TO_RUN = "BOOST_TESTS_TO_RUN";
literal_string SAVE_TEST_PATTERN = "BOOST_TEST_SAVE_PATTERN";
literal_string BUILD_INFO = "BOOST_TEST_BUILD_INFO";
literal_string SHOW_PROGRESS = "BOOST_TEST_SHOW_PROGRESS";
literal_string CATCH_SYS_ERRORS = "BOOST_TEST_CATCH_SYSTEM_ERRORS";
literal_string AUTO_START_DBG = "BOOST_TEST_AUTO_START_DBG";
literal_string USE_ALT_STACK = "BOOST_TEST_USE_ALT_STACK";
literal_string DETECT_FP_EXCEPT = "BOOST_TEST_DETECT_FP_EXCEPTIONS";
literal_string REPORT_FORMAT = "BOOST_TEST_REPORT_FORMAT";
literal_string LOG_FORMAT = "BOOST_TEST_LOG_FORMAT";
literal_string OUTPUT_FORMAT = "BOOST_TEST_OUTPUT_FORMAT";
literal_string DETECT_MEM_LEAK = "BOOST_TEST_DETECT_MEMORY_LEAK";
literal_string RANDOM_SEED = "BOOST_TEST_RANDOM";
literal_string BREAK_EXEC_PATH = "BOOST_TEST_BREAK_EXEC_PATH";
unit_test::log_level s_log_level;
bool s_no_result_code;
unit_test::report_level s_report_level;
const_string s_tests_to_run;
const_string s_exec_path_to_break;
bool s_save_pattern;
bool s_show_build_info;
bool s_show_progress;
bool s_catch_sys_errors;
bool s_auto_start_dbg;
bool s_use_alt_stack;
bool s_detect_fp_except;
output_format s_report_format;
output_format s_log_format;
long s_detect_mem_leaks;
unsigned int s_random_seed;
// ************************************************************************** //
// ************** runtime_config ************** //
// ************************************************************************** //
const_string
retrieve_framework_parameter( const_string parameter_name, int* argc, char** argv )
{
static fixed_mapping<const_string,const_string> parameter_2_cla_name_map(
LOG_LEVEL , "--log_level",
NO_RESULT_CODE , "--result_code",
REPORT_LEVEL , "--report_level",
TESTS_TO_RUN , "--run_test",
SAVE_TEST_PATTERN , "--save_pattern",
BUILD_INFO , "--build_info",
SHOW_PROGRESS , "--show_progress",
CATCH_SYS_ERRORS , "--catch_system_errors",
AUTO_START_DBG , "--auto_start_dbg",
USE_ALT_STACK , "--use_alt_stack",
DETECT_FP_EXCEPT , "--detect_fp_exceptions",
REPORT_FORMAT , "--report_format",
LOG_FORMAT , "--log_format",
OUTPUT_FORMAT , "--output_format",
DETECT_MEM_LEAK , "--detect_memory_leaks",
RANDOM_SEED , "--random",
BREAK_EXEC_PATH , "--break_exec_path",
""
);
// first try to find parameter among command line arguments if present
if( argc ) {
// locate corresponding cla name
const_string cla_name = parameter_2_cla_name_map[parameter_name];
if( !cla_name.is_empty() ) {
for( int i = 1; i < *argc; ++i ) {
if( cla_name == const_string( argv[i], cla_name.size() ) && argv[i][cla_name.size()] == '=' ) {
const_string result = argv[i] + cla_name.size() + 1;
for( int j = i; j < *argc; ++j ) {
argv[j] = argv[j+1];
}
--(*argc);
return result;
}
}
}
}
return std::getenv( parameter_name.begin() );
}
long interpret_long( const_string from )
{
bool negative = false;
long res = 0;
if( first_char( from ) == '-' ) {
negative = true;
from.trim_left( 1 );
}
const_string::iterator it = from.begin();
for( ;it != from.end(); ++it ) {
int d = *it - '0';
res = 10 * res + d;
}
if( negative )
res = -res;
return res;
}
} // local namespace
//____________________________________________________________________________//
namespace runtime_config {
void
init( int* argc, char** argv )
{
fixed_mapping<const_string,unit_test::log_level,case_ins_less<char const> > log_level_name(
"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,
invalid_log_level
);
fixed_mapping<const_string,unit_test::report_level,case_ins_less<char const> > report_level_name (
"confirm", CONFIRMATION_REPORT,
"short", SHORT_REPORT,
"detailed", DETAILED_REPORT,
"no", NO_REPORT,
INV_REPORT_LEVEL
);
fixed_mapping<const_string,output_format,case_ins_less<char const> > output_format_name (
"HRF", CLF,
"CLF", CLF,
"XML", XML,
CLF
);
s_no_result_code = retrieve_framework_parameter( NO_RESULT_CODE, argc, argv ) == "no";
s_save_pattern = retrieve_framework_parameter( SAVE_TEST_PATTERN, argc, argv ) == "yes";
s_show_build_info = retrieve_framework_parameter( BUILD_INFO, argc, argv ) == "yes";
s_show_progress = retrieve_framework_parameter( SHOW_PROGRESS, argc, argv ) == "yes";
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
s_catch_sys_errors = retrieve_framework_parameter( CATCH_SYS_ERRORS, argc, argv ) == "yes";
#else
s_catch_sys_errors = retrieve_framework_parameter( CATCH_SYS_ERRORS, argc, argv ) != "no";
#endif
s_use_alt_stack = retrieve_framework_parameter( USE_ALT_STACK, argc, argv ) != "no";
s_detect_fp_except = retrieve_framework_parameter( DETECT_FP_EXCEPT, argc, argv ) == "yes";
s_tests_to_run = retrieve_framework_parameter( TESTS_TO_RUN, argc, argv );
s_exec_path_to_break= retrieve_framework_parameter( BREAK_EXEC_PATH, argc, argv );
const_string rs_str = retrieve_framework_parameter( RANDOM_SEED, argc, argv );
s_random_seed = rs_str.is_empty() ? 0 : lexical_cast<unsigned int>( rs_str );
s_log_level = log_level_name[retrieve_framework_parameter( LOG_LEVEL, argc, argv )];
s_report_level = report_level_name[retrieve_framework_parameter( REPORT_LEVEL, argc, argv )];
s_report_format = output_format_name[retrieve_framework_parameter( REPORT_FORMAT, argc, argv )];
s_log_format = output_format_name[retrieve_framework_parameter( LOG_FORMAT, argc, argv )];
const_string output_format = retrieve_framework_parameter( OUTPUT_FORMAT, argc, argv );
if( !output_format.is_empty() ) {
s_report_format = output_format_name[output_format];
s_log_format = output_format_name[output_format];
}
const_string ml_str = retrieve_framework_parameter( DETECT_MEM_LEAK, argc, argv );
s_detect_mem_leaks = ml_str.is_empty() ? 1 : interpret_long( ml_str );
const_string dbg = retrieve_framework_parameter( AUTO_START_DBG, argc, argv );
if( dbg.is_empty() || dbg == "no" )
s_auto_start_dbg = false;
else {
s_auto_start_dbg = true;
if( dbg != "yes" )
debug::set_debugger( dbg );
}
}
//____________________________________________________________________________//
unit_test::log_level
log_level()
{
return s_log_level;
}
//____________________________________________________________________________//
bool
no_result_code()
{
return s_no_result_code;
}
//____________________________________________________________________________//
unit_test::report_level
report_level()
{
return s_report_level;
}
//____________________________________________________________________________//
const_string
test_to_run()
{
return s_tests_to_run;
}
//____________________________________________________________________________//
const_string
break_exec_path()
{
return s_exec_path_to_break;
}
//____________________________________________________________________________//
bool
save_pattern()
{
return s_save_pattern;
}
//____________________________________________________________________________//
bool
show_progress()
{
return s_show_progress;
}
//____________________________________________________________________________//
bool
show_build_info()
{
return s_show_build_info;
}
//____________________________________________________________________________//
bool
catch_sys_errors()
{
return s_catch_sys_errors;
}
//____________________________________________________________________________//
bool
auto_start_dbg()
{
return s_auto_start_dbg;
}
//____________________________________________________________________________//
bool
use_alt_stack()
{
return s_use_alt_stack;
}
//____________________________________________________________________________//
bool
detect_fp_exceptions()
{
return s_detect_fp_except;
}
//____________________________________________________________________________//
output_format
report_format()
{
return s_report_format;
}
//____________________________________________________________________________//
output_format
log_format()
{
return s_log_format;
}
//____________________________________________________________________________//
long
detect_memory_leaks()
{
return s_detect_mem_leaks;
}
//____________________________________________________________________________//
int
random_seed()
{
return s_random_seed;
}
//____________________________________________________________________________//
} // 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,346 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : privide core implementation for Unit Test Framework.
// Extensions could 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/unit_test_suite_impl.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/utils/foreach.hpp>
#include <boost/test/results_collector.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
// Boost
#include <boost/timer.hpp>
// STL
#include <algorithm>
#include <vector>
#include <boost/test/detail/suppress_warnings.hpp>
#if BOOST_WORKAROUND(__BORLANDC__, < 0x600) && \
BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) \
/**/
using std::rand; // rand is in std and random_shuffle is in _STL
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_unit ************** //
// ************************************************************************** //
test_unit::test_unit( const_string name, test_unit_type t )
: p_type( t )
, p_type_name( t == tut_case ? "case" : "suite" )
, p_id( INV_TEST_UNIT_ID )
, p_name( std::string( name.begin(), name.size() ) )
, p_enabled( true )
{
}
//____________________________________________________________________________//
test_unit::~test_unit()
{
framework::deregister_test_unit( this );
}
//____________________________________________________________________________//
void
test_unit::depends_on( test_unit* tu )
{
m_dependencies.push_back( tu->p_id );
}
//____________________________________________________________________________//
bool
test_unit::check_dependencies() const
{
BOOST_TEST_FOREACH( test_unit_id, tu_id, m_dependencies ) {
if( !unit_test::results_collector.results( tu_id ).passed() )
return false;
}
return true;
}
//____________________________________________________________________________//
void
test_unit::increase_exp_fail( unsigned num )
{
p_expected_failures.value += num;
if( p_parent_id != 0 )
framework::get<test_suite>( p_parent_id ).increase_exp_fail( num );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** test_case ************** //
// ************************************************************************** //
test_case::test_case( const_string name, callback0<> const& test_func )
: test_unit( name, (test_unit_type)type )
, m_test_func( test_func )
{
// !! weirdest MSVC BUG; try to remove this statement; looks like it eats first token of next statement
#if BOOST_WORKAROUND(BOOST_MSVC,<1300)
0;
#endif
framework::register_test_unit( this );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** test_suite ************** //
// ************************************************************************** //
//____________________________________________________________________________//
test_suite::test_suite( const_string name )
: test_unit( name, (test_unit_type)type )
{
framework::register_test_unit( this );
}
//____________________________________________________________________________//
void
test_suite::add( test_unit* tu, counter_t expected_failures, unsigned timeout )
{
if( timeout != 0 )
tu->p_timeout.value = timeout;
m_members.push_back( tu->p_id );
tu->p_parent_id.value = p_id;
if( tu->p_expected_failures )
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(), tu))
add( tu, 0, timeout );
}
//____________________________________________________________________________//
void
test_suite::remove( test_unit_id id )
{
std::vector<test_unit_id>::iterator it = std::find( m_members.begin(), m_members.begin(), id );
if( it != m_members.end() )
m_members.erase( it );
}
//____________________________________________________________________________//
test_unit_id
test_suite::get( const_string tu_name ) const
{
BOOST_TEST_FOREACH( test_unit_id, id, m_members ) {
if( tu_name == framework::get( id, test_id_2_unit_type( id ) ).p_name.get() )
return id;
}
return INV_TEST_UNIT_ID;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** traverse_test_tree ************** //
// ************************************************************************** //
void
traverse_test_tree( test_case const& tc, test_tree_visitor& V )
{
if( tc.p_enabled )
V.visit( tc );
}
//____________________________________________________________________________//
void
traverse_test_tree( test_suite const& suite, test_tree_visitor& V )
{
if( !suite.p_enabled || !V.test_suite_start( suite ) )
return;
try {
if( runtime_config::random_seed() == 0 ) {
BOOST_TEST_FOREACH( test_unit_id, id, suite.m_members )
traverse_test_tree( id, V );
}
else {
std::vector<test_unit_id> members( suite.m_members );
std::random_shuffle( members.begin(), members.end() );
BOOST_TEST_FOREACH( test_unit_id, id, members )
traverse_test_tree( id, V );
}
} catch( test_being_aborted const& ) {
V.test_suite_finish( suite );
framework::test_unit_aborted( suite );
throw;
}
V.test_suite_finish( suite );
}
//____________________________________________________________________________//
void
traverse_test_tree( test_unit_id id, test_tree_visitor& V )
{
if( test_id_2_unit_type( id ) == tut_case )
traverse_test_tree( framework::get<test_case>( id ), V );
else
traverse_test_tree( framework::get<test_suite>( id ), V );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** test_case_counter ************** //
// ************************************************************************** //
void
test_case_counter::visit( test_case const& tc )
{
if( tc.p_enabled )
++p_count.value;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** object generators ************** //
// ************************************************************************** //
namespace ut_detail {
std::string
normalize_test_case_name( const_string name )
{
return ( name[0] == '&'
? std::string( name.begin()+1, name.size()-1 )
: std::string( name.begin(), name.size() ) );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** auto_test_unit_registrar ************** //
// ************************************************************************** //
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, counter_t exp_fail )
{
curr_ts_store().back()->add( tc, exp_fail );
}
//____________________________________________________________________________//
auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name )
{
test_unit_id id = curr_ts_store().back()->get( ts_name );
test_suite* ts;
if( id != INV_TEST_UNIT_ID ) {
ts = &framework::get<test_suite>( id ); // !! test for invalid tu type
BOOST_ASSERT( ts->p_parent_id == curr_ts_store().back()->p_id );
}
else {
ts = new test_suite( ts_name );
curr_ts_store().back()->add( ts );
}
curr_ts_store().push_back( ts );
}
//____________________________________________________________________________//
auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen )
{
curr_ts_store().back()->add( tc_gen );
}
//____________________________________________________________________________//
auto_test_unit_registrar::auto_test_unit_registrar( int )
{
if( curr_ts_store().size() == 0 )
return; // report error?
curr_ts_store().pop_back();
}
//____________________________________________________________________________//
std::list<test_suite*>&
auto_test_unit_registrar::curr_ts_store()
{
static std::list<test_suite*> inst( 1, &framework::master_test_suite() );
return inst;
}
//____________________________________________________________________________//
} // 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,172 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : implements 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/unit_test_suite_impl.hpp>
#include <boost/test/framework.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" << attr_value() << BOOST_PLATFORM
<< " compiler" << attr_value() << BOOST_COMPILER
<< " stl" << 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" << attr_value() << tu.p_name.get() << ">";
}
//____________________________________________________________________________//
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 )
{
ostr << "<" << tu_type_name( tu )
<< " name" << attr_value() << tu.p_name.get()
<< " skipped" << attr_value() << "yes"
<< "/>";
}
//____________________________________________________________________________//
void
xml_log_formatter::log_exception( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, const_string explanation )
{
ostr << "<Exception>" << pcdata() << explanation;
if( !checkpoint_data.m_file_name.is_empty() ) {
ostr << "<LastCheckpoint file" << attr_value() << checkpoint_data.m_file_name
<< " line" << attr_value() << checkpoint_data.m_line_num
<< ">"
<< pcdata() << checkpoint_data.m_message
<< "</LastCheckpoint>";
}
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
<< " file" << attr_value() << entry_data.m_file_name
<< " line" << attr_value() << entry_data.m_line_num
<< ">";
}
//____________________________________________________________________________//
void
xml_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
{
ostr << pcdata() << value;
}
//____________________________________________________________________________//
void
xml_log_formatter::log_entry_finish( std::ostream& ostr )
{
ostr << "</" << m_curr_tag << ">";
m_curr_tag.clear();
}
//____________________________________________________________________________//
} // 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,115 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : 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/unit_test_suite_impl.hpp>
#include <boost/test/output/xml_report_formatter.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" << attr_value() << tu.p_name.get()
<< " result" << attr_value() << descr
<< " assertions_passed" << attr_value() << tr.p_assertions_passed
<< " assertions_failed" << attr_value() << tr.p_assertions_failed
<< " expected_failures" << attr_value() << tr.p_expected_failures;
if( tu.p_type == tut_suite )
ostr << " test_cases_passed" << attr_value() << tr.p_test_cases_passed
<< " test_cases_failed" << attr_value() << tr.p_test_cases_failed
<< " test_cases_skipped" << attr_value() << tr.p_test_cases_skipped
<< " test_cases_aborted" << 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

View File

@@ -0,0 +1,25 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : included (vs. linked ) version of Program Execution Monitor
// ***************************************************************************
#ifndef BOOST_INCLUDED_PRG_EXEC_MONITOR_HPP_071894GER
#define BOOST_INCLUDED_PRG_EXEC_MONITOR_HPP_071894GER
#include <boost/test/impl/execution_monitor.ipp>
#include <boost/test/impl/debug.ipp>
#include <boost/test/impl/cpp_main.ipp>
#define BOOST_TEST_INCLUDED
#include <boost/test/prg_exec_monitor.hpp>
#endif // BOOST_INCLUDED_PRG_EXEC_MONITOR_HPP_071894GER

View File

@@ -0,0 +1,39 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : included (vs. linked) version of Test Execution Monitor
// ***************************************************************************
#ifndef BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER
#define BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER
#include <boost/test/impl/compiler_log_formatter.ipp>
#include <boost/test/impl/debug.ipp>
#include <boost/test/impl/execution_monitor.ipp>
#include <boost/test/impl/framework.ipp>
#include <boost/test/impl/plain_report_formatter.ipp>
#include <boost/test/impl/progress_monitor.ipp>
#include <boost/test/impl/results_collector.ipp>
#include <boost/test/impl/results_reporter.ipp>
#include <boost/test/impl/test_main.ipp>
#include <boost/test/impl/test_tools.ipp>
#include <boost/test/impl/unit_test_log.ipp>
#include <boost/test/impl/unit_test_main.ipp>
#include <boost/test/impl/unit_test_monitor.ipp>
#include <boost/test/impl/unit_test_parameters.ipp>
#include <boost/test/impl/unit_test_suite.ipp>
#include <boost/test/impl/xml_log_formatter.ipp>
#include <boost/test/impl/xml_report_formatter.ipp>
#define BOOST_TEST_INCLUDED
#include <boost/test/test_exec_monitor.hpp>
#endif // BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER

View File

@@ -0,0 +1,41 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : included (vs. linked) version of Unit Test Framework
// ***************************************************************************
#ifndef BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
#define BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
#include <boost/test/impl/compiler_log_formatter.ipp>
#include <boost/test/impl/debug.ipp>
#include <boost/test/impl/framework.ipp>
#include <boost/test/impl/exception_safety.ipp>
#include <boost/test/impl/execution_monitor.ipp>
#include <boost/test/impl/interaction_based.ipp>
#include <boost/test/impl/logged_expectations.ipp>
#include <boost/test/impl/plain_report_formatter.ipp>
#include <boost/test/impl/progress_monitor.ipp>
#include <boost/test/impl/results_collector.ipp>
#include <boost/test/impl/results_reporter.ipp>
#include <boost/test/impl/test_tools.ipp>
#include <boost/test/impl/unit_test_log.ipp>
#include <boost/test/impl/unit_test_main.ipp>
#include <boost/test/impl/unit_test_monitor.ipp>
#include <boost/test/impl/unit_test_parameters.ipp>
#include <boost/test/impl/unit_test_suite.ipp>
#include <boost/test/impl/xml_log_formatter.ipp>
#include <boost/test/impl/xml_report_formatter.ipp>
#define BOOST_TEST_INCLUDED
#include <boost/test/unit_test.hpp>
#endif // BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER

View File

@@ -0,0 +1,2 @@
// deprecated
#include <boost/test/included/unit_test.hpp>

View File

@@ -0,0 +1,262 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : Facilities to perform interaction-based testing
// ***************************************************************************
#ifndef BOOST_TEST_INTERACTION_BASED_HPP_112105GER
#define BOOST_TEST_INTERACTION_BASED_HPP_112105GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// Boost
#include <boost/lexical_cast.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** BOOST_ITEST_EPOINT ************** //
// ************************************************************************** //
#define BOOST_ITEST_EPOINT( description ) \
::boost::itest::manager::instance().exception_point( BOOST_TEST_L(__FILE__), __LINE__, description )
/**/
// ************************************************************************** //
// ************** BOOST_ITEST_DPOINT ************** //
// ************************************************************************** //
#define BOOST_ITEST_DPOINT() \
::boost::itest::manager::instance().decision_point( BOOST_TEST_L(__FILE__), __LINE__ )
/**/
// ************************************************************************** //
// ************** BOOST_ITEST_SCOPE ************** //
// ************************************************************************** //
#define BOOST_ITEST_SCOPE( scope_name ) \
::boost::itest::scope_guard itest_scope_guard ## __LINE__( BOOST_TEST_L(__FILE__), __LINE__, BOOST_STRINGIZE(scope_name) )
/**/
// ************************************************************************** //
// ************** BOOST_ITEST_NEW ************** //
// ************************************************************************** //
#define BOOST_ITEST_NEW( type_name ) \
new ( ::boost::itest::location( BOOST_TEST_L(__FILE__), __LINE__ ) ) type_name
/**/
// ************************************************************************** //
// ************** BOOST_ITEST_DATA_FLOW ************** //
// ************************************************************************** //
#define BOOST_ITEST_DATA_FLOW( v ) \
::boost::itest::manager::instance().generic_data_flow( v )
/**/
// ************************************************************************** //
// ************** BOOST_ITEST_RETURN ************** //
// ************************************************************************** //
#define BOOST_ITEST_RETURN( type, default_value ) \
::boost::itest::manager::instance().generic_return<type>( default_value )
/**/
// ************************************************************************** //
// ************** BOOST_ITEST_MOCK_FUNC ************** //
// ************************************************************************** //
#define BOOST_ITEST_MOCK_FUNC( function_name ) \
BOOST_ITEST_SCOPE( function_name ); \
BOOST_ITEST_EPOINT( 0 ); \
return ::boost::itest::mock_object<>::prototype(); \
/**/
namespace boost {
namespace itest { // interaction-based testing
using unit_test::const_string;
// ************************************************************************** //
// ************** manager ************** //
// ************************************************************************** //
class BOOST_TEST_DECL manager {
public:
// instance access
static manager& instance() { return *instance_ptr(); }
// Mock objects interface hooks
virtual void exception_point( const_string /*file*/,
std::size_t /*line_num*/,
const_string /*descr*/ ){}
virtual bool decision_point( const_string /*file*/,
std::size_t /*line_num*/ ) { return true; }
virtual unsigned enter_scope( const_string /*file*/,
std::size_t /*line_num*/,
const_string /*scope_name*/){ return 0; }
virtual void leave_scope( unsigned ) {}
virtual void allocated( const_string /*file*/,
std::size_t /*line_num*/,
void* /*p*/, std::size_t /*s*/ ) {}
virtual void freed( void* /*p*/ ) {}
virtual void data_flow( const_string /*d*/ ) {}
virtual std::string return_value( const_string /*default_value */ ) { return ""; }
template<typename T>
void generic_data_flow( T const& t )
{
wrap_stringstream ws;
data_flow( (ws << t).str() );
}
template<typename T, typename DefaultValueType>
T generic_return( DefaultValueType const& dv )
{
wrap_stringstream ws;
std::string const& res = return_value( (ws << dv).str() );
if( res.empty() )
return dv;
return lexical_cast<T>( res );
}
protected:
manager();
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
public:
#endif
BOOST_TEST_PROTECTED_VIRTUAL ~manager();
private:
struct dummy_constr{};
explicit manager( dummy_constr* ) {}
static manager* instance_ptr( bool reset = false, manager* ptr = 0 );
}; // manager
// ************************************************************************** //
// ************** scope_guard ************** //
// ************************************************************************** //
class scope_guard {
public:
// Constructor
scope_guard( const_string file, std::size_t line_num, const_string scope_name )
{
m_scope_index = manager::instance().enter_scope( file, line_num, scope_name );
}
~scope_guard()
{
manager::instance().leave_scope( m_scope_index );
}
unsigned m_scope_index;
};
// ************************************************************************** //
// ************** location ************** //
// ************************************************************************** //
struct location {
location( const_string file, std::size_t line )
: m_file_name( file )
, m_line_num( line )
{}
const_string m_file_name;
std::size_t m_line_num;
};
} // namespace itest
} // namespace boost
// ************************************************************************** //
// ************** operator new overload ************** //
// ************************************************************************** //
#if !defined(BOOST_ITEST_NO_NEW_OVERLOADS)
// STL
#include <cstdlib>
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::malloc; using ::free; }
# endif
# ifdef _CRTDBG_MAP_ALLOC
namespace std { using ::_malloc_dbg; using ::_free_dbg; }
# endif
inline void*
operator new( std::size_t s, ::boost::itest::location const& l )
{
void* res = std::malloc(s ? s : 1);
if( res )
::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s );
else
throw std::bad_alloc();
return res;
}
//____________________________________________________________________________//
inline void*
operator new[]( std::size_t s, ::boost::itest::location const& l )
{
void* res = std::malloc(s ? s : 1);
if( res )
::boost::itest::manager::instance().allocated( l.m_file_name, l.m_line_num, res, s );
else
throw std::bad_alloc();
return res;
}
//____________________________________________________________________________//
inline void
operator delete( void* p, ::boost::itest::location const& )
{
::boost::itest::manager::instance().freed( p );
std::free( p );
}
//____________________________________________________________________________//
inline void
operator delete[]( void* p, ::boost::itest::location const& )
{
::boost::itest::manager::instance().freed( p );
std::free( p );
}
//____________________________________________________________________________//
#endif
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_INTERACTION_BASED_HPP_112105GER

View File

@@ -0,0 +1,74 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : Facilities to perform interaction based testng of logged expectations
// ***************************************************************************
#ifndef BOOST_TEST_LOGGED_EXPECTATIONS_HPP_120905GER
#define BOOST_TEST_LOGGED_EXPECTATIONS_HPP_120905GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/unit_test_parameters.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** BOOST_TEST_LOGGED_EXPECTATIONS ************** //
// ************************************************************************** //
#define BOOST_TEST_LOGGED_EXPECTATIONS( test_name ) \
struct test_name : public BOOST_AUTO_TEST_CASE_FIXTURE \
{ void test_method(); }; \
\
static void BOOST_AUTO_TC_INVOKER( test_name )() \
{ \
test_name t; \
::boost::itest::logged_expectations( \
boost::bind( &test_name::test_method, t ), \
BOOST_STRINGIZE(test_name) ".elog", \
!::boost::unit_test::runtime_config::save_pattern() ); \
} \
\
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
\
BOOST_AUTO_TU_REGISTRAR( test_name )( \
boost::unit_test::make_test_case( \
&BOOST_AUTO_TC_INVOKER( test_name ), #test_name ), \
boost::unit_test::ut_detail::auto_tc_exp_fail< \
BOOST_AUTO_TC_UNIQUE_ID( test_name )>::instance()->value() ); \
\
void test_name::test_method() \
/**/
namespace boost {
namespace itest {
// ************************************************************************** //
// ************** logged expectations test ************** //
// ************************************************************************** //
void BOOST_TEST_DECL
logged_expectations( unit_test::callback0<> const& F,
unit_test::const_string log_file_name,
bool test_or_log = true );
} // namespace itest
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_LOGGED_EXPECTATIONS_HPP_120905GER

View File

@@ -0,0 +1,143 @@
// (C) Copyright Gennadiy Rozental 2002-2008.
// 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: 49312 $
//
// Description : simple minimal testing definitions and implementation
// ***************************************************************************
#ifndef BOOST_TEST_MINIMAL_HPP_071894GER
#define BOOST_TEST_MINIMAL_HPP_071894GER
#define BOOST_CHECK(exp) \
( (exp) \
? static_cast<void>(0) \
: boost::minimal_test::report_error(#exp,__FILE__,__LINE__, BOOST_CURRENT_FUNCTION) )
#define BOOST_REQUIRE(exp) \
( (exp) \
? static_cast<void>(0) \
: boost::minimal_test::report_critical_error(#exp,__FILE__,__LINE__,BOOST_CURRENT_FUNCTION))
#define BOOST_ERROR( msg_ ) \
boost::minimal_test::report_error( (msg_),__FILE__,__LINE__, BOOST_CURRENT_FUNCTION, true )
#define BOOST_FAIL( msg_ ) \
boost::minimal_test::report_critical_error( (msg_),__FILE__,__LINE__, BOOST_CURRENT_FUNCTION, true )
//____________________________________________________________________________//
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/impl/execution_monitor.ipp>
#include <boost/test/impl/debug.ipp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
// Boost
#include <boost/cstdlib.hpp> // for exit codes#include <boost/cstdlib.hpp> // for exit codes
#include <boost/current_function.hpp> // for BOOST_CURRENT_FUNCTION
// STL
#include <iostream> // std::cerr, std::endl
#include <string> // std::string
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
int test_main( int argc, char* argv[] ); // prototype for users test_main()
namespace boost {
namespace minimal_test {
typedef boost::unit_test::const_string const_string;
inline unit_test::counter_t& errors_counter() { static unit_test::counter_t ec = 0; return ec; }
inline void
report_error( const char* msg, const char* file, int line, const_string func_name, bool is_msg = false )
{
++errors_counter();
std::cerr << file << "(" << line << "): ";
if( is_msg )
std::cerr << msg;
else
std::cerr << "test " << msg << " failed";
if( func_name != "(unknown)" )
std::cerr << " in function: '" << func_name << "'";
std::cerr << std::endl;
}
inline void
report_critical_error( const char* msg, const char* file, int line, const_string func_name, bool is_msg = false )
{
report_error( msg, file, line, func_name, is_msg );
throw boost::execution_aborted();
}
class caller {
public:
// constructor
caller( int argc, char** argv )
: m_argc( argc ), m_argv( argv ) {}
// execution monitor hook implementation
int operator()() { return test_main( m_argc, m_argv ); }
private:
// Data members
int m_argc;
char** m_argv;
}; // monitor
} // namespace minimal_test
} // namespace boost
//____________________________________________________________________________//
int BOOST_TEST_CALL_DECL main( int argc, char* argv[] )
{
using namespace boost::minimal_test;
try {
::boost::execution_monitor ex_mon;
int run_result = ex_mon.execute( caller( argc, argv ) );
BOOST_CHECK( run_result == 0 || run_result == boost::exit_success );
}
catch( boost::execution_exception const& exex ) {
if( exex.code() != boost::execution_exception::no_error )
BOOST_ERROR( (std::string( "exception \"" ).
append( exex.what().begin(), exex.what().end() ).
append( "\" caught" ) ).c_str() );
std::cerr << "\n**** Testing aborted.";
}
if( boost::minimal_test::errors_counter() != 0 ) {
std::cerr << "\n**** " << errors_counter()
<< " error" << (errors_counter() > 1 ? "s" : "" ) << " detected\n";
return boost::exit_test_failure;
}
std::cout << "\n**** no errors detected\n";
return boost::exit_success;
}
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_MINIMAL_HPP_071894GER

View File

@@ -0,0 +1,328 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : Facilities to perform exception safety_tests
// ***************************************************************************
#ifndef BOOST_TEST_MOCK_OBJECT_HPP_112205GER
#define BOOST_TEST_MOCK_OBJECT_HPP_112205GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/interaction_based.hpp>
// Boost
#include <boost/preprocessor/punctuation/comma.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace itest {
// ************************************************************************** //
// ************** mock_object_base ************** //
// ************************************************************************** //
class mock_object_base {
public:
mock_object_base() {}
template<typename T1>
mock_object_base( T1 const& ) {}
template<typename T1, typename T2>
mock_object_base( T1 const&, T2 const& ) {}
template<typename T1, typename T2, typename T3>
mock_object_base( T1 const&, T2 const&, T3 const& ) {}
template<typename T1, typename T2, typename T3, typename T4>
mock_object_base( T1 const&, T2 const&, T3 const&, T4 const& ) {}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
mock_object_base( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) {}
};
// ************************************************************************** //
// ************** mock_object implementation helpers ************** //
// ************************************************************************** //
#define MO_OP_IMPL( op, descr, ret ) \
BOOST_ITEST_SCOPE( mock_object::operator op ); \
BOOST_ITEST_EPOINT( descr ); \
return ret \
/**/
#define MO_UNARY_OP( op, descr ) \
self_type const& operator op() const \
{ \
MO_OP_IMPL( op, descr, prototype() ); \
} \
/**/
#define MO_UNARY_BOOL_OP( op, descr ) \
bool operator op() const \
{ \
MO_OP_IMPL( op, descr, (!!BOOST_ITEST_DPOINT()) ); \
} \
/**/
#define MO_BINARY_OP( op, descr ) \
template<int i1, typename Base1,int i2, typename Base2> \
inline mock_object<i1,Base1> const& \
operator op( mock_object<i1,Base1> const& mo, \
mock_object<i2,Base2> const& ) \
{ \
MO_OP_IMPL( op, descr, mo ); \
} \
\
template<int i, typename Base, typename T> \
inline mock_object<i,Base> const& \
operator op( mock_object<i,Base> const& mo, T const& ) \
{ \
MO_OP_IMPL( op, descr, mo ); \
} \
\
template<int i, typename Base, typename T> \
inline mock_object<i,Base> const& \
operator op( T const&, mock_object<i,Base> const& mo ) \
{ \
MO_OP_IMPL( op, descr, mo ); \
} \
/**/
#define MO_BINARY_BOOL_OP( op, descr ) \
template<int i1, typename Base1,int i2, typename Base2> \
inline bool \
operator op( mock_object<i1,Base1> const&, \
mock_object<i2,Base2> const& ) \
{ \
MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \
} \
\
template<int i, typename Base, typename T> \
inline bool \
operator op( mock_object<i,Base> const&, T const& ) \
{ \
MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \
} \
\
template<int i, typename Base, typename T> \
inline bool \
operator op( T const&, mock_object<i,Base> const& ) \
{ \
MO_OP_IMPL( op, descr, BOOST_ITEST_DPOINT() ); \
} \
/**/
// ************************************************************************** //
// ************** mock_object ************** //
// ************************************************************************** //
template<int i = 0, typename Base=mock_object_base>
class mock_object;
template<int i, typename Base>
class mock_object : public Base {
// Private typeefs
typedef mock_object<i,Base> self_type;
struct dummy { void nonnull() {}; };
typedef void (dummy::*safe_bool)();
// prototype constructor
mock_object( dummy* ) {}
public:
static mock_object& prototype()
{
static mock_object p( (dummy*)0 );
return p;
}
// Constructors
mock_object()
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object default constructor" );
}
template<typename T1>
mock_object( T1 const& arg1 )
: mock_object_base( arg1 )
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object constructor" );
}
template<typename T1, typename T2>
mock_object( T1 const& arg1, T2 const& arg2 )
: mock_object_base( arg1, arg2 )
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object constructor" );
}
template<typename T1, typename T2, typename T3>
mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3 )
: mock_object_base( arg1, arg2, arg3 )
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object constructor" );
}
template<typename T1, typename T2, typename T3, typename T4>
mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4 )
: mock_object_base( arg1, arg2, arg3, arg4 )
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object constructor" );
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
mock_object( T1 const& arg1, T2 const& arg2, T3 const& arg3, T4 const& arg4, T5 const& arg5 )
: mock_object_base( arg1, arg2, arg3, arg4, arg5 )
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object constructor" );
}
mock_object( mock_object const& )
{
BOOST_ITEST_SCOPE( mock_object::mock_object );
BOOST_ITEST_EPOINT( "Mock object copy constructor" );
}
// assignment
self_type const& operator =( mock_object const& ) const
{
MO_OP_IMPL( =, "Copy assignment", prototype() );
}
template <typename T>
self_type const& operator =( T const& ) const
{
MO_OP_IMPL( =, "Copy assignment", prototype() );
}
// Unary operators
MO_UNARY_BOOL_OP( !, "Logical NOT operator" )
MO_UNARY_OP( &, "Address-of operator" )
MO_UNARY_OP( ~, "One's complement operator" )
MO_UNARY_OP( *, "Pointer dereference" )
MO_UNARY_OP( +, "Unary plus" )
// Increment and Decrement
MO_UNARY_OP( ++, "Prefix increment" )
MO_UNARY_OP( --, "Prefix decrement" )
self_type const& operator ++(int) const
{
MO_OP_IMPL( ++, "Postfix increment", prototype() );
}
self_type const& operator --(int) const
{
MO_OP_IMPL( --, "Postfix decrement", prototype() );
}
// Bool context convertion
operator safe_bool() const
{
MO_OP_IMPL( safe_bool, "Bool context conversion",
(BOOST_ITEST_DPOINT() ? 0 : &dummy::nonnull) );
}
// Function-call operators
self_type const& operator ()() const
{
MO_OP_IMPL( (), "0-arity function-call", prototype() );
}
template<typename T1>
self_type const& operator ()( T1 const& arg1 ) const
{
MO_OP_IMPL( (), "1-arity function-call", prototype() );
}
template<typename T1, typename T2>
self_type const& operator ()( T1 const&, T2 const& ) const
{
MO_OP_IMPL( (), "2-arity function-call", prototype() );
}
template<typename T1, typename T2, typename T3>
self_type const& operator ()( T1 const&, T2 const&, T3 const& ) const
{
MO_OP_IMPL( (), "3-arity function-call", prototype() );
}
template<typename T1, typename T2, typename T3, typename T4>
self_type const& operator ()( T1 const&, T2 const&, T3 const&, T4 const& ) const
{
MO_OP_IMPL( (), "4-arity function-call", prototype() );
}
template<typename T1, typename T2, typename T3, typename T4, typename T5>
self_type const& operator ()( T1 const&, T2 const&, T3 const&, T4 const&, T5 const& ) const
{
MO_OP_IMPL( (), "5-arity function-call", prototype() );
}
// Substripting
template<typename T>
self_type const& operator []( T const& ) const
{
MO_OP_IMPL( [], "Substripting", prototype() );
}
// Class member access
self_type const* operator->() const
{
MO_OP_IMPL( ->, "Class member access", this );
}
};
// !! MO_BINARY_OP( BOOST_PP_COMMA(), "Comma operator" )
MO_BINARY_BOOL_OP( !=, "Inequality" )
MO_BINARY_OP( %, "Modulus" )
MO_BINARY_OP( %=, "Modulus/assignment" )
MO_BINARY_OP( &, "Bitwise AND" )
MO_BINARY_BOOL_OP( &&, "Logical AND" )
MO_BINARY_OP( &=, "Bitwise AND/assignment" )
MO_BINARY_OP( *, "Multiplication" )
MO_BINARY_OP( *=, "Multiplication/assignment" )
MO_BINARY_OP( +, "Addition" )
MO_BINARY_OP( +=, "Addition/assignment" )
//MO_BINARY_OP( -, "Subtraction" )
MO_BINARY_OP( -=, "Subtraction/assignment" )
MO_BINARY_OP( ->*, "Pointer-to-member selection" )
MO_BINARY_OP( /, "Division" )
MO_BINARY_OP( /=, "Division/assignment" )
MO_BINARY_BOOL_OP( <, "Less than" )
MO_BINARY_OP( <<=, "Left shift/assignment" )
MO_BINARY_BOOL_OP( <=, "Less than or equal to" )
MO_BINARY_BOOL_OP( ==, "Equality" )
MO_BINARY_BOOL_OP( >, "Greater than" )
MO_BINARY_BOOL_OP( >=, "Greater than or equal to" )
MO_BINARY_OP( >>=, "Right shift/assignment" )
MO_BINARY_OP( ^, "Exclusive OR" )
MO_BINARY_OP( ^=, "Exclusive OR/assignment" )
MO_BINARY_OP( |, "Bitwise inclusive OR" )
MO_BINARY_OP( |=, "Bitwise inclusive OR/assignment" )
MO_BINARY_BOOL_OP( ||, "Logical OR" )
MO_BINARY_OP( <<, "Left shift" )
MO_BINARY_OP( >>, "Right shift" )
} // namespace itest
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_MOCK_OBJECT_HPP_112205GER

View File

@@ -0,0 +1,68 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : contains compiler like Log formatter definition
// ***************************************************************************
#ifndef BOOST_TEST_COMPILER_LOG_FORMATTER_HPP_020105GER
#define BOOST_TEST_COMPILER_LOG_FORMATTER_HPP_020105GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/unit_test_log_formatter.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
// ************************************************************************** //
// ************** compiler_log_formatter ************** //
// ************************************************************************** //
class BOOST_TEST_DECL compiler_log_formatter : public unit_test_log_formatter {
public:
// Formatter interface
void log_start( std::ostream&, counter_t test_cases_amount );
void log_finish( std::ostream& );
void log_build_info( std::ostream& );
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
void test_unit_skipped( std::ostream&, test_unit const& tu );
void log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation );
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
void log_entry_value( std::ostream&, const_string value );
void log_entry_value( std::ostream&, lazy_ostream const& value );
void log_entry_finish( std::ostream& );
protected:
virtual void print_prefix( std::ostream&, const_string file, std::size_t line );
};
} // namespace output
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_COMPILER_LOG_FORMATTER_HPP_020105GER

View File

@@ -0,0 +1,62 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : plain report formatter implementation
// ***************************************************************************
#ifndef BOOST_TEST_PLAIN_REPORT_FORMATTER_HPP_020105GER
#define BOOST_TEST_PLAIN_REPORT_FORMATTER_HPP_020105GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
// ************************************************************************** //
// ************** plain_report_formatter ************** //
// ************************************************************************** //
class plain_report_formatter : public results_reporter::format {
public:
// Formatter interface
void results_report_start( std::ostream& ostr );
void results_report_finish( std::ostream& ostr );
void test_unit_report_start( test_unit const&, std::ostream& ostr );
void test_unit_report_finish( test_unit const&, std::ostream& ostr );
void do_confirmation_report( test_unit const&, std::ostream& ostr );
private:
// Data members
counter_t m_indent;
};
} // namespace output
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PLAIN_REPORT_FORMATTER_HPP_020105GER

View File

@@ -0,0 +1,72 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : contains XML Log formatter definition
// ***************************************************************************
#ifndef BOOST_TEST_XML_LOG_FORMATTER_020105GER
#define BOOST_TEST_XML_LOG_FORMATTER_020105GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/unit_test_log_formatter.hpp>
// STL
#include <cstddef> // std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
// ************************************************************************** //
// ************** xml_log_formatter ************** //
// ************************************************************************** //
class xml_log_formatter : public unit_test_log_formatter {
public:
// Formatter interface
void log_start( std::ostream&, counter_t test_cases_amount );
void log_finish( std::ostream& );
void log_build_info( std::ostream& );
void test_unit_start( std::ostream&, test_unit const& tu );
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
void test_unit_skipped( std::ostream&, test_unit const& tu );
void log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation );
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let );
using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
void log_entry_value( std::ostream&, const_string value );
void log_entry_finish( std::ostream& );
private:
// Data members
const_string m_curr_tag;
};
} // namespace output
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_LOG_FORMATTER_020105GER

View File

@@ -0,0 +1,58 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : XML report formatter implementation
// ***************************************************************************
#ifndef BOOST_TEST_XML_REPORT_FORMATTER_HPP_020105GER
#define BOOST_TEST_XML_REPORT_FORMATTER_HPP_020105GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/results_reporter.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace output {
// ************************************************************************** //
// ************** xml_report_formatter ************** //
// ************************************************************************** //
class xml_report_formatter : public results_reporter::format {
public:
// Formatter interface
void results_report_start( std::ostream& ostr );
void results_report_finish( std::ostream& ostr );
void test_unit_report_start( test_unit const&, std::ostream& ostr );
void test_unit_report_finish( test_unit const&, std::ostream& ostr );
void do_confirmation_report( test_unit const&, std::ostream& ostr );
};
} // namespace output
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_XML_REPORT_FORMATTER_HPP_020105GER

View File

@@ -0,0 +1,78 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : output_test_stream class definition
// ***************************************************************************
#ifndef BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
#define BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/predicate_result.hpp>
// STL
#include <cstddef> // for std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** output_test_stream ************** //
// ************************************************************************** //
// class to be used to simplify testing of ostream-based output operations
namespace boost {
namespace test_tools {
class BOOST_TEST_DECL output_test_stream : public wrap_stringstream::wrapped_stream {
typedef unit_test::const_string const_string;
typedef predicate_result result_type;
public:
// Constructor
explicit output_test_stream( const_string pattern_file_name = const_string(),
bool match_or_save = true,
bool text_or_binary = true );
// Destructor
~output_test_stream();
// checking function
result_type is_empty( bool flush_stream = true );
result_type check_length( std::size_t length, bool flush_stream = true );
result_type is_equal( const_string arg_, bool flush_stream = true );
result_type match_pattern( bool flush_stream = true );
// explicit flush
void flush();
private:
// helper functions
std::size_t length();
void sync();
struct Impl;
Impl* m_pimpl;
};
} // namespace test_tools
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_OUTPUT_TEST_STREAM_HPP_012705GER

View File

@@ -0,0 +1,181 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : generators and helper macros for parameterized tests
// ***************************************************************************
#ifndef BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
#define BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
// Boost.Test
#include <boost/test/unit_test_suite.hpp>
#include <boost/test/utils/callback.hpp>
// Boost
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
#define BOOST_PARAM_TEST_CASE( function, begin, end ) \
boost::unit_test::make_test_case( function, \
BOOST_TEST_STRINGIZE( function ), \
(begin), (end) ) \
/**/
#define BOOST_PARAM_CLASS_TEST_CASE( function, tc_instance, begin, end ) \
boost::unit_test::make_test_case( function, \
BOOST_TEST_STRINGIZE( function ), \
(tc_instance), \
(begin), (end) ) \
/**/
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_func_with_bound_param ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename ParamType>
struct test_func_with_bound_param {
template<typename T>
test_func_with_bound_param( callback1<ParamType> test_func, T const& param )
: m_test_func( test_func )
, m_param( param )
{}
void operator()() { m_test_func( m_param ); }
private:
callback1<ParamType> m_test_func;
ParamType m_param;
};
// ************************************************************************** //
// ************** param_test_case_generator ************** //
// ************************************************************************** //
template<typename ParamType, typename ParamIter>
class param_test_case_generator : public test_unit_generator {
public:
param_test_case_generator( callback1<ParamType> const& test_func,
const_string tc_name,
ParamIter par_begin,
ParamIter par_end )
: m_test_func( test_func )
, m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
, m_par_begin( par_begin )
, m_par_end( par_end )
{}
test_unit* next() const
{
if( m_par_begin == m_par_end )
return (test_unit*)0;
test_func_with_bound_param<ParamType> bound_test_func( m_test_func, *m_par_begin );
test_unit* res = new test_case( m_tc_name, bound_test_func );
++m_par_begin;
return res;
}
private:
// Data members
callback1<ParamType> m_test_func;
std::string m_tc_name;
mutable ParamIter m_par_begin;
ParamIter m_par_end;
};
//____________________________________________________________________________//
template<typename UserTestCase,typename ParamType>
struct user_param_tc_method_invoker {
typedef void (UserTestCase::*test_method)( ParamType );
// Constructor
user_param_tc_method_invoker( shared_ptr<UserTestCase> inst, test_method test_method )
: m_inst( inst ), m_test_method( test_method ) {}
void operator()( ParamType p ) { ((*m_inst).*m_test_method)( p ); }
// Data members
shared_ptr<UserTestCase> m_inst;
test_method m_test_method;
};
//____________________________________________________________________________//
} // namespace ut_detail
template<typename ParamType, typename ParamIter>
inline ut_detail::param_test_case_generator<ParamType,ParamIter>
make_test_case( callback1<ParamType> const& test_func,
const_string tc_name,
ParamIter par_begin,
ParamIter par_end )
{
return ut_detail::param_test_case_generator<ParamType,ParamIter>( test_func, tc_name, par_begin, par_end );
}
//____________________________________________________________________________//
template<typename ParamType, typename ParamIter>
inline ut_detail::param_test_case_generator<
BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type,ParamIter>
make_test_case( void (*test_func)( ParamType ),
const_string tc_name,
ParamIter par_begin,
ParamIter par_end )
{
typedef BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type param_value_type;
return ut_detail::param_test_case_generator<param_value_type,ParamIter>( test_func, tc_name, par_begin, par_end );
}
//____________________________________________________________________________//
template<typename UserTestCase,typename ParamType, typename ParamIter>
inline ut_detail::param_test_case_generator<
BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type,ParamIter>
make_test_case( void (UserTestCase::*test_method )( ParamType ),
const_string tc_name,
boost::shared_ptr<UserTestCase> const& user_test_case,
ParamIter par_begin,
ParamIter par_end )
{
typedef BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type param_value_type;
return ut_detail::param_test_case_generator<param_value_type,ParamIter>(
ut_detail::user_param_tc_method_invoker<UserTestCase,ParamType>( user_test_case, test_method ),
tc_name,
par_begin,
par_end );
}
//____________________________________________________________________________//
} // unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER

View File

@@ -0,0 +1,83 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : enhanced result for test predicate that include message explaining failure
// ***************************************************************************
#ifndef BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
#define BOOST_TEST_PREDICATE_RESULT_HPP_012705GER
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// Boost
#include <boost/shared_ptr.hpp>
#include <boost/detail/workaround.hpp>
// STL
#include <cstddef> // for std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
// ************************************************************************** //
// ************** predicate_result ************** //
// ************************************************************************** //
class BOOST_TEST_DECL predicate_result {
typedef unit_test::const_string const_string;
public:
// Constructor
predicate_result( bool pv_ )
: p_predicate_value( pv_ )
{}
template<typename BoolConvertable>
predicate_result( BoolConvertable const& pv_ ) : p_predicate_value( !!pv_ ) {}
bool operator!() const { return !p_predicate_value; }
void operator=( bool pv_ ) { p_predicate_value.value = pv_; }
// Public properties
BOOST_READONLY_PROPERTY( bool, (predicate_result) ) p_predicate_value;
// Access methods
bool has_empty_message() const { return !m_message; }
wrap_stringstream& message()
{
if( !m_message )
m_message.reset( new wrap_stringstream );
return *m_message;
}
const_string message() const { return !m_message ? const_string() : const_string( m_message->str() ); }
private:
// Data members
shared_ptr<wrap_stringstream> m_message;
};
} // namespace test_tools
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PREDICATE_RESULT_HPP_012705GER

View File

@@ -0,0 +1,68 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : Entry point for the end user into the Program Execution Monitor.
// ***************************************************************************
#ifndef BOOST_PRG_EXEC_MONITOR_HPP_071894GER
#define BOOST_PRG_EXEC_MONITOR_HPP_071894GER
#include <boost/test/detail/config.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** Auto Linking ************** //
// ************************************************************************** //
// Automatically link to the correct build variant where possible.
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
# define BOOST_LIB_NAME boost_prg_exec_monitor
// If we're importing code from a dll, then tell auto_link.hpp about it:
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TEST_DYN_LINK)
# define BOOST_DYN_LINK
# endif
# include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
// ************************************************************************** //
// ************** 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[] );
}
#if defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
// ************************************************************************** //
// ************** main function for tests using dll ************** //
// ************************************************************************** //
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
#endif // BOOST_PRG_EXEC_MONITOR_HPP_071894GER

View File

@@ -0,0 +1,70 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : defines simple text based progress monitor
// ***************************************************************************
#ifndef BOOST_TEST_PROGRESS_MONITOR_HPP_020105GER
#define BOOST_TEST_PROGRESS_MONITOR_HPP_020105GER
// Boost.Test
#include <boost/test/test_observer.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
// STL
#include <iosfwd> // for std::ostream&
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** progress_monitor ************** //
// ************************************************************************** //
class BOOST_TEST_DECL progress_monitor_t : public test_observer, public singleton<progress_monitor_t> {
public:
// test observer interface
void test_start( counter_t test_cases_amount );
void test_finish() {}
void test_aborted();
void test_unit_start( test_unit const& ) {}
void test_unit_finish( test_unit const&, unsigned long );
void test_unit_skipped( test_unit const& );
void test_unit_aborted( test_unit const& ) {}
void assertion_result( bool ) {}
void exception_caught( execution_exception const& ) {}
// configuration
void set_stream( std::ostream& );
private:
BOOST_TEST_SINGLETON_CONS( progress_monitor_t );
}; // progress_monitor_t
BOOST_TEST_SINGLETON_INST( progress_monitor )
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PROGRESS_MONITOR_HPP_020105GER

View File

@@ -0,0 +1,112 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines class unit_test_result that is responsible for
// gathering test results and presenting this information to end-user
// ***************************************************************************
#ifndef BOOST_TEST_RESULTS_COLLECTOR_HPP_071894GER
#define BOOST_TEST_RESULTS_COLLECTOR_HPP_071894GER
// Boost.Test
#include <boost/test/test_observer.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** first failed assertion debugger hook ************** //
// ************************************************************************** //
namespace {
inline void first_failed_assertion() {}
}
// ************************************************************************** //
// ************** test_results ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_results {
public:
test_results();
typedef BOOST_READONLY_PROPERTY( counter_t, (results_collector_t)(test_results)(results_collect_helper) ) counter_prop;
typedef BOOST_READONLY_PROPERTY( bool, (results_collector_t)(test_results)(results_collect_helper) ) bool_prop;
counter_prop p_assertions_passed;
counter_prop p_assertions_failed;
counter_prop p_expected_failures;
counter_prop p_test_cases_passed;
counter_prop p_test_cases_failed;
counter_prop p_test_cases_skipped;
counter_prop p_test_cases_aborted;
bool_prop p_aborted;
bool_prop p_skipped;
// "conclusion" methods
bool passed() const;
int result_code() const;
// collection helper
void operator+=( test_results const& );
void clear();
};
// ************************************************************************** //
// ************** results_collector ************** //
// ************************************************************************** //
class BOOST_TEST_DECL results_collector_t : public test_observer, public singleton<results_collector_t> {
public:
// test_observer interface implementation
void test_start( counter_t test_cases_amount );
void test_finish();
void test_aborted();
void test_unit_start( test_unit const& );
void test_unit_finish( test_unit const&, unsigned long elapsed );
void test_unit_skipped( test_unit const& );
void test_unit_aborted( test_unit const& );
void assertion_result( bool passed );
void exception_caught( execution_exception const& );
// results access
test_results const& results( test_unit_id ) const;
private:
BOOST_TEST_SINGLETON_CONS( results_collector_t );
};
BOOST_TEST_SINGLETON_INST( results_collector )
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_COLLECTOR_HPP_071894GER

View File

@@ -0,0 +1,88 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines class unit_test_result that is responsible for
// gathering test results and presenting this information to end-user
// ***************************************************************************
#ifndef BOOST_TEST_RESULTS_REPORTER_HPP_021205GER
#define BOOST_TEST_RESULTS_REPORTER_HPP_021205GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
// STL
#include <iosfwd> // for std::ostream&
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace results_reporter {
// ************************************************************************** //
// ************** formatter interface ************** //
// ************************************************************************** //
class BOOST_TEST_DECL format {
public:
// Destructor
virtual ~format() {}
virtual void results_report_start( std::ostream& ostr ) = 0;
virtual void results_report_finish( std::ostream& ostr ) = 0;
virtual void test_unit_report_start( test_unit const&, std::ostream& ostr ) = 0;
virtual void test_unit_report_finish( test_unit const&, std::ostream& ostr ) = 0;
virtual void do_confirmation_report( test_unit const&, std::ostream& ostr ) = 0;
};
// ************************************************************************** //
// ************** report configuration ************** //
// ************************************************************************** //
BOOST_TEST_DECL void set_level( report_level );
BOOST_TEST_DECL void set_stream( std::ostream& );
BOOST_TEST_DECL void set_format( output_format );
BOOST_TEST_DECL void set_format( results_reporter::format* );
BOOST_TEST_DECL std::ostream& get_stream();
// ************************************************************************** //
// ************** report initiation ************** //
// ************************************************************************** //
BOOST_TEST_DECL void make_report( report_level l = INV_REPORT_LEVEL, test_unit_id = INV_TEST_UNIT_ID );
inline void confirmation_report( test_unit_id id = INV_TEST_UNIT_ID )
{ make_report( CONFIRMATION_REPORT, id ); }
inline void short_report( test_unit_id id = INV_TEST_UNIT_ID )
{ make_report( SHORT_REPORT, id ); }
inline void detailed_report( test_unit_id id = INV_TEST_UNIT_ID )
{ make_report( DETAILED_REPORT, id ); }
} // namespace results_reporter
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_RESULTS_REPORTER_HPP_021205GER

View File

@@ -0,0 +1,151 @@
// (C) Copyright Gennadiy Rozental 2003-2008.
// 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: 49312 $
//
// Description : implements support for test cases templates instantiated with
// sequence of test types
// ***************************************************************************
#ifndef BOOST_TEST_TEST_CASE_TEMPLATE_HPP_071894GER
#define BOOST_TEST_TEST_CASE_TEMPLATE_HPP_071894GER
// Boost
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type.hpp>
#include <boost/type_traits/is_const.hpp>
// STL
#include <typeinfo>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
#define BOOST_TEST_CASE_TEMPLATE( name, typelist ) \
boost::unit_test::ut_detail::template_test_case_gen<name,typelist >( \
BOOST_TEST_STRINGIZE( name ) ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_CASE_TEMPLATE_FUNCTION( name, type_name ) \
template<typename type_name> \
void BOOST_JOIN( name, _impl )( boost::type<type_name>* ); \
\
struct name { \
template<typename TestType> \
static void run( boost::type<TestType>* frwrd = 0 ) \
{ \
BOOST_JOIN( name, _impl )( frwrd ); \
} \
}; \
\
template<typename type_name> \
void BOOST_JOIN( name, _impl )( boost::type<type_name>* ) \
/**/
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
// ************************************************************************** //
// ************** test_case_template_invoker ************** //
// ************************************************************************** //
template<typename TestCaseTemplate,typename TestType>
class test_case_template_invoker {
public:
void operator()() { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** generate_test_case_4_type ************** //
// ************************************************************************** //
template<typename Generator,typename TestCaseTemplate>
struct generate_test_case_4_type {
explicit generate_test_case_4_type( const_string tc_name, Generator& G )
: m_test_case_name( tc_name )
, m_holder( G )
{}
template<typename TestType>
void operator()( mpl::identity<TestType> )
{
std::string full_name;
assign_op( full_name, m_test_case_name, 0 );
full_name += '<';
full_name += typeid(TestType).name();
if( boost::is_const<TestType>::value )
full_name += " const";
full_name += '>';
m_holder.m_test_cases.push_back(
new test_case( full_name, test_case_template_invoker<TestCaseTemplate,TestType>() ) );
}
private:
// Data members
const_string m_test_case_name;
Generator& m_holder;
};
// ************************************************************************** //
// ************** test_case_template ************** //
// ************************************************************************** //
template<typename TestCaseTemplate,typename TestTypesList>
class template_test_case_gen : public test_unit_generator {
public:
// Constructor
template_test_case_gen( const_string tc_name )
{
typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,
TestCaseTemplate
> single_test_gen;
mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, *this ) );
}
test_unit* next() const
{
if( m_test_cases.empty() )
return 0;
test_unit* res = m_test_cases.front();
m_test_cases.pop_front();
return res;
}
// Data members
mutable std::list<test_unit*> m_test_cases;
};
//____________________________________________________________________________//
} // namespace ut_detail
} // unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_CASE_TEMPLATE_HPP_071894GER

View File

@@ -0,0 +1,36 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : Entry point for the end user into the Test Execution Monitor.
// ***************************************************************************
#ifndef BOOST_TEST_EXEC_MONITOR_HPP_071894GER
#define BOOST_TEST_EXEC_MONITOR_HPP_071894GER
// Boost.Test
#include <boost/test/test_tools.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** Auto Linking ************** //
// ************************************************************************** //
// Automatically link to the correct build variant where possible.
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
# define BOOST_LIB_NAME boost_test_exec_monitor
# include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif // BOOST_TEST_EXEC_MONITOR_HPP_071894GER

View File

@@ -0,0 +1,65 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : defines abstract interface for test observer
// ***************************************************************************
#ifndef BOOST_TEST_TEST_OBSERVER_HPP_021005GER
#define BOOST_TEST_TEST_OBSERVER_HPP_021005GER
// Boost.Test
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_observer ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_observer {
public:
// test observer interface
virtual void test_start( counter_t /* test_cases_amount */ ) {}
virtual void test_finish() {}
virtual void test_aborted() {}
virtual void test_unit_start( test_unit const& ) {}
virtual void test_unit_finish( test_unit const&, unsigned long /* elapsed */ ) {}
virtual void test_unit_skipped( test_unit const& ) {}
virtual void test_unit_aborted( test_unit const& ) {}
virtual void assertion_result( bool /* passed */ ) {}
virtual void exception_caught( execution_exception const& ) {}
virtual int priority() { return 0; }
protected:
BOOST_TEST_PROTECTED_VIRTUAL ~test_observer() {}
};
} // unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_OBSERVER_HPP_021005GER

View File

@@ -0,0 +1,719 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : contains definition for all test tools in test toolbox
// ***************************************************************************
#ifndef BOOST_TEST_TEST_TOOLS_HPP_012705GER
#define BOOST_TEST_TEST_TOOLS_HPP_012705GER
// Boost.Test
#include <boost/test/predicate_result.hpp>
#include <boost/test/unit_test_log.hpp>
#include <boost/test/floating_point_comparison.hpp>
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/lazy_ostream.hpp>
// Boost
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/enum.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/punctuation/comma_if.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/limits.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_abstract.hpp>
#include <boost/mpl/or.hpp>
// STL
#include <cstddef> // for std::size_t
#include <iosfwd>
#include <ios> // for std::boolalpha
#include <climits> // for CHAR_BIT
#ifdef BOOST_MSVC
# pragma warning(disable: 4127) // conditional expression is constant
#endif
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** TOOL BOX ************** //
// ************************************************************************** //
// In macros below following argument abbreviations are used:
// P - predicate
// M - message
// S - statement
// E - exception
// L - left argument
// R - right argument
// TL - tool level
// CT - check type
// ARGS - arguments list
#define BOOST_TEST_TOOL_IMPL( func, P, check_descr, TL, CT ) \
::boost::test_tools::tt_detail::func( \
P, \
::boost::unit_test::lazy_ostream::instance() << check_descr, \
BOOST_TEST_L(__FILE__), \
(std::size_t)__LINE__, \
::boost::test_tools::tt_detail::TL, \
::boost::test_tools::tt_detail::CT \
/**/
//____________________________________________________________________________//
#define BOOST_CHECK_IMPL( P, check_descr, TL, CT ) \
do { \
BOOST_TEST_PASSPOINT(); \
BOOST_TEST_TOOL_IMPL( check_impl, P, check_descr, TL, CT ), 0 );\
} while( ::boost::test_tools::dummy_cond ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_PASS_ARG_INFO( r, data, arg ) , arg, BOOST_STRINGIZE( arg )
#define BOOST_CHECK_WITH_ARGS_IMPL( P, check_descr, TL, CT, ARGS ) \
do { \
BOOST_TEST_PASSPOINT(); \
BOOST_TEST_TOOL_IMPL( check_frwd, P, check_descr, TL, CT ) \
BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_PASS_ARG_INFO, '_', ARGS ) ); \
} while( ::boost::test_tools::dummy_cond ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED )
#define BOOST_CHECK( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED )
#define BOOST_REQUIRE( P ) BOOST_CHECK_IMPL( (P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED )
//____________________________________________________________________________//
#define BOOST_WARN_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, WARN, CHECK_MSG )
#define BOOST_CHECK_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, CHECK, CHECK_MSG )
#define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_CHECK_IMPL( (P), M, REQUIRE, CHECK_MSG )
//____________________________________________________________________________//
#define BOOST_ERROR( M ) BOOST_CHECK_MESSAGE( false, M )
#define BOOST_FAIL( M ) BOOST_REQUIRE_MESSAGE( false, M )
//____________________________________________________________________________//
#define BOOST_CHECK_THROW_IMPL( S, E, P, prefix, TL ) \
try { \
BOOST_TEST_PASSPOINT(); \
S; \
BOOST_CHECK_IMPL( false, "exception " BOOST_STRINGIZE( E ) " is expected", TL, CHECK_MSG ); } \
catch( E const& ex ) { \
::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \
BOOST_CHECK_IMPL( P, prefix BOOST_STRINGIZE( E ) " is caught", TL, CHECK_MSG ); \
} \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", WARN )
#define BOOST_CHECK_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", CHECK )
#define BOOST_REQUIRE_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "exception ", REQUIRE )
//____________________________________________________________________________//
#define BOOST_WARN_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", WARN )
#define BOOST_CHECK_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", CHECK )
#define BOOST_REQUIRE_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), "incorrect exception ", REQUIRE )
//____________________________________________________________________________//
#define BOOST_CHECK_NO_THROW_IMPL( S, TL ) \
try { \
S; \
BOOST_CHECK_IMPL( true, "no exceptions thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); } \
catch( ... ) { \
BOOST_CHECK_IMPL( false, "exception thrown by " BOOST_STRINGIZE( S ), TL, CHECK_MSG ); \
} \
/**/
#define BOOST_WARN_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, WARN )
#define BOOST_CHECK_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, CHECK )
#define BOOST_REQUIRE_NO_THROW( S ) BOOST_CHECK_NO_THROW_IMPL( S, REQUIRE )
//____________________________________________________________________________//
#define BOOST_WARN_EQUAL( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) )
#define BOOST_CHECK_EQUAL( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) )
#define BOOST_REQUIRE_EQUAL( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_NE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", WARN, CHECK_NE, (L)(R) )
#define BOOST_CHECK_NE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", CHECK, CHECK_NE, (L)(R) )
#define BOOST_REQUIRE_NE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ne_impl(), "", REQUIRE, CHECK_NE, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_LT( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", WARN, CHECK_LT, (L)(R) )
#define BOOST_CHECK_LT( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", CHECK, CHECK_LT, (L)(R) )
#define BOOST_REQUIRE_LT( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::lt_impl(), "", REQUIRE, CHECK_LT, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_LE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", WARN, CHECK_LE, (L)(R) )
#define BOOST_CHECK_LE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", CHECK, CHECK_LE, (L)(R) )
#define BOOST_REQUIRE_LE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::le_impl(), "", REQUIRE, CHECK_LE, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_GT( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", WARN, CHECK_GT, (L)(R) )
#define BOOST_CHECK_GT( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", CHECK, CHECK_GT, (L)(R) )
#define BOOST_REQUIRE_GT( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::gt_impl(), "", REQUIRE, CHECK_GT, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_GE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", WARN, CHECK_GE, (L)(R) )
#define BOOST_CHECK_GE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", CHECK, CHECK_GE, (L)(R) )
#define BOOST_REQUIRE_GE( L, R ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::tt_detail::ge_impl(), "", REQUIRE, CHECK_GE, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_CLOSE( L, R, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE, \
(L)(R)(::boost::test_tools::percent_tolerance(T)) )
#define BOOST_CHECK_CLOSE( L, R, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE, \
(L)(R)(::boost::test_tools::percent_tolerance(T)) )
#define BOOST_REQUIRE_CLOSE( L, R, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE, \
(L)(R)(::boost::test_tools::percent_tolerance(T)) )
//____________________________________________________________________________//
#define BOOST_WARN_CLOSE_FRACTION( L, R, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", WARN, CHECK_CLOSE_FRACTION, \
(L)(R)(::boost::test_tools::fraction_tolerance(T)) )
#define BOOST_CHECK_CLOSE_FRACTION( L, R, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", CHECK, CHECK_CLOSE_FRACTION, \
(L)(R)(::boost::test_tools::fraction_tolerance(T)) )
#define BOOST_REQUIRE_CLOSE_FRACTION( L, R, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_close, "", REQUIRE, CHECK_CLOSE_FRACTION, \
(L)(R)(::boost::test_tools::fraction_tolerance(T)) )
//____________________________________________________________________________//
#define BOOST_WARN_SMALL( FPV, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", WARN, CHECK_SMALL, (FPV)(T) )
#define BOOST_CHECK_SMALL( FPV, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", CHECK, CHECK_SMALL, (FPV)(T) )
#define BOOST_REQUIRE_SMALL( FPV, T ) \
BOOST_CHECK_WITH_ARGS_IMPL( ::boost::test_tools::check_is_small, "", REQUIRE, CHECK_SMALL, (FPV)(T) )
//____________________________________________________________________________//
#define BOOST_WARN_PREDICATE( P, ARGS ) \
BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS )
#define BOOST_CHECK_PREDICATE( P, ARGS ) \
BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS )
#define BOOST_REQUIRE_PREDICATE( P, ARGS ) \
BOOST_CHECK_WITH_ARGS_IMPL( P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS )
//____________________________________________________________________________//
#define BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, TL ) \
BOOST_TEST_TOOL_IMPL( check_impl, ::boost::test_tools::tt_detail::equal_coll_impl( \
(L_begin), (L_end), (R_begin), (R_end) ), "", TL, CHECK_EQUAL_COLL ), \
4, \
BOOST_STRINGIZE( L_begin ), BOOST_STRINGIZE( L_end ), \
BOOST_STRINGIZE( R_begin ), BOOST_STRINGIZE( R_end ) ) \
/**/
#define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, WARN )
#define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, CHECK )
#define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_EQUAL_COLLECTIONS_IMPL( L_begin, L_end, R_begin, R_end, REQUIRE )
//____________________________________________________________________________//
#define BOOST_BITWISE_EQUAL_IMPL( L, R, TL ) \
BOOST_TEST_TOOL_IMPL( check_impl, \
::boost::test_tools::tt_detail::bitwise_equal_impl( (L), (R) ), \
"", TL, CHECK_BITWISE_EQUAL ), \
2, BOOST_STRINGIZE( L ), BOOST_STRINGIZE( R ) ) \
/**/
#define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, WARN )
#define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, CHECK )
#define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_BITWISE_EQUAL_IMPL( L, R, REQUIRE )
//____________________________________________________________________________//
#define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
//____________________________________________________________________________//
// ***************************** //
// deprecated interface
#define BOOST_BITWISE_EQUAL( L, R ) BOOST_CHECK_BITWISE_EQUAL( L, R )
#define BOOST_MESSAGE( M ) BOOST_TEST_MESSAGE( M )
#define BOOST_CHECKPOINT( M ) BOOST_TEST_CHECKPOINT( M )
namespace boost {
namespace test_tools {
typedef unit_test::const_string const_string;
namespace { bool const dummy_cond = false; }
// ************************************************************************** //
// ************** print_log_value ************** //
// ************************************************************************** //
template<typename T>
struct print_log_value {
void operator()( std::ostream& ostr, T const& t )
{
// avoid warning: 'boost::test_tools::<unnamed>::dummy_cond' defined but not used
if (::boost::test_tools::dummy_cond) {}
typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type couldnt_use_nl;
set_precision( ostr, couldnt_use_nl() );
ostr << t; // by default print the value
}
void set_precision( std::ostream& ostr, mpl::false_ )
{
if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 )
ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 );
}
void set_precision( std::ostream&, mpl::true_ ) {}
};
//____________________________________________________________________________//
#define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \
namespace boost { namespace test_tools { \
template<> \
struct print_log_value<the_type > { \
void operator()( std::ostream&, the_type const& ) {} \
}; \
}} \
/**/
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
template<typename T, std::size_t N >
struct print_log_value< T[N] > {
void operator()( std::ostream& ostr, T const* t )
{
ostr << t;
}
};
#endif
//____________________________________________________________________________//
template<>
struct BOOST_TEST_DECL print_log_value<bool> {
void operator()( std::ostream& ostr, bool t )
{
ostr << std::boolalpha << t;
}
};
//____________________________________________________________________________//
template<>
struct BOOST_TEST_DECL print_log_value<char> {
void operator()( std::ostream& ostr, char t );
};
//____________________________________________________________________________//
template<>
struct BOOST_TEST_DECL print_log_value<unsigned char> {
void operator()( std::ostream& ostr, unsigned char t );
};
//____________________________________________________________________________//
template<>
struct BOOST_TEST_DECL print_log_value<char const*> {
void operator()( std::ostream& ostr, char const* t );
};
//____________________________________________________________________________//
template<>
struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
void operator()( std::ostream& ostr, wchar_t const* t );
};
//____________________________________________________________________________//
namespace tt_detail {
// ************************************************************************** //
// ************** tools classification ************** //
// ************************************************************************** //
enum check_type {
CHECK_PRED,
CHECK_MSG,
CHECK_EQUAL,
CHECK_NE,
CHECK_LT,
CHECK_LE,
CHECK_GT,
CHECK_GE,
CHECK_CLOSE,
CHECK_CLOSE_FRACTION,
CHECK_SMALL,
CHECK_BITWISE_EQUAL,
CHECK_PRED_WITH_ARGS,
CHECK_EQUAL_COLL
};
enum tool_level {
WARN, CHECK, REQUIRE, PASS
};
// ************************************************************************** //
// ************** print_helper ************** //
// ************************************************************************** //
// Adds level of indirection to the output operation, allowing us to customize
// it for types that do not support operator << directly or for any other reason
template<typename T>
struct print_helper_t {
explicit print_helper_t( T const& t ) : m_t( t ) {}
T const& m_t;
};
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
// Borland suffers premature pointer decay passing arrays by reference
template<typename T, std::size_t N >
struct print_helper_t< T[N] > {
explicit print_helper_t( T const * t ) : m_t( t ) {}
T const * m_t;
};
#endif
//____________________________________________________________________________//
template<typename T>
inline print_helper_t<T> print_helper( T const& t )
{
return print_helper_t<T>( t );
}
//____________________________________________________________________________//
template<typename T>
inline std::ostream&
operator<<( std::ostream& ostr, print_helper_t<T> const& ph )
{
print_log_value<T>()( ostr, ph.m_t );
return ostr;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** TOOL BOX Implementation ************** //
// ************************************************************************** //
BOOST_TEST_DECL
bool check_impl( predicate_result const& pr, ::boost::unit_test::lazy_ostream const& check_descr,
const_string file_name, std::size_t line_num,
tool_level tl, check_type ct,
std::size_t num_args, ... );
//____________________________________________________________________________//
#define TEMPL_PARAMS( z, m, dummy ) , typename BOOST_JOIN( Arg, m )
#define FUNC_PARAMS( z, m, dummy ) \
, BOOST_JOIN( Arg, m ) const& BOOST_JOIN( arg, m ) \
, char const* BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \
/**/
#define PRED_PARAMS( z, m, dummy ) BOOST_PP_COMMA_IF( m ) BOOST_JOIN( arg, m )
#define ARG_INFO( z, m, dummy ) \
, BOOST_JOIN( BOOST_JOIN( arg, m ), _descr ) \
, &(const unit_test::lazy_ostream&)(unit_test::lazy_ostream::instance() \
<< ::boost::test_tools::tt_detail::print_helper( BOOST_JOIN( arg, m ) )) \
/**/
#define IMPL_FRWD( z, n, dummy ) \
template<typename Pred \
BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), TEMPL_PARAMS, _ )> \
inline bool \
check_frwd( Pred P, unit_test::lazy_ostream const& check_descr, \
const_string file_name, std::size_t line_num, \
tool_level tl, check_type ct \
BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), FUNC_PARAMS, _ ) \
) \
{ \
return \
check_impl( P( BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), PRED_PARAMS, _ ) ), \
check_descr, file_name, line_num, tl, ct, \
BOOST_PP_ADD( n, 1 ) \
BOOST_PP_REPEAT_ ## z( BOOST_PP_ADD( n, 1 ), ARG_INFO, _ ) \
); \
} \
/**/
#ifndef BOOST_TEST_MAX_PREDICATE_ARITY
#define BOOST_TEST_MAX_PREDICATE_ARITY 5
#endif
BOOST_PP_REPEAT( BOOST_TEST_MAX_PREDICATE_ARITY, IMPL_FRWD, _ )
#undef TEMPL_PARAMS
#undef FUNC_PARAMS
#undef PRED_INFO
#undef ARG_INFO
#undef IMPL_FRWD
//____________________________________________________________________________//
template <class Left, class Right>
predicate_result equal_impl( Left const& left, Right const& right )
{
return left == right;
}
//____________________________________________________________________________//
predicate_result BOOST_TEST_DECL equal_impl( char const* left, char const* right );
inline predicate_result equal_impl( char* left, char const* right ) { return equal_impl( (char const*)left, (char const*)right ); }
inline predicate_result equal_impl( char const* left, char* right ) { return equal_impl( (char const*)left, (char const*)right ); }
inline predicate_result equal_impl( char* left, char* right ) { return equal_impl( (char const*)left, (char const*)right ); }
#if !defined( BOOST_NO_CWCHAR )
predicate_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
inline predicate_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( (wchar_t const*)left, (wchar_t const*)right ); }
inline predicate_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( (wchar_t const*)left, (wchar_t const*)right ); }
inline predicate_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( (wchar_t const*)left, (wchar_t const*)right ); }
#endif
//____________________________________________________________________________//
struct equal_impl_frwd {
template <typename Left, typename Right>
inline predicate_result
call_impl( Left const& left, Right const& right, mpl::false_ ) const
{
return equal_impl( left, right );
}
template <typename Left, typename Right>
inline predicate_result
call_impl( Left const& left, Right const& right, mpl::true_ ) const
{
return (*this)( right, &left[0] );
}
template <typename Left, typename Right>
inline predicate_result
operator()( Left const& left, Right const& right ) const
{
typedef typename is_array<Left>::type left_is_array;
return call_impl( left, right, left_is_array() );
}
};
//____________________________________________________________________________//
struct ne_impl {
template <class Left, class Right>
predicate_result operator()( Left const& left, Right const& right )
{
return !equal_impl_frwd()( left, right );
}
};
//____________________________________________________________________________//
struct lt_impl {
template <class Left, class Right>
predicate_result operator()( Left const& left, Right const& right )
{
return left < right;
}
};
//____________________________________________________________________________//
struct le_impl {
template <class Left, class Right>
predicate_result operator()( Left const& left, Right const& right )
{
return left <= right;
}
};
//____________________________________________________________________________//
struct gt_impl {
template <class Left, class Right>
predicate_result operator()( Left const& left, Right const& right )
{
return left > right;
}
};
//____________________________________________________________________________//
struct ge_impl {
template <class Left, class Right>
predicate_result operator()( Left const& left, Right const& right )
{
return left >= right;
}
};
//____________________________________________________________________________//
template <typename Left, typename Right>
inline predicate_result
equal_coll_impl( Left left_begin, Left left_end, Right right_begin, Right right_end )
{
predicate_result res( true );
std::size_t pos = 0;
for( ; left_begin != left_end && right_begin != right_end; ++left_begin, ++right_begin, ++pos ) {
if( *left_begin != *right_begin ) {
res = false;
res.message() << "\nMismatch in a position " << pos << ": " << *left_begin << " != " << *right_begin;
}
}
if( left_begin != left_end ) {
std::size_t r_size = pos;
while( left_begin != left_end ) {
++pos;
++left_begin;
}
res = false;
res.message() << "\nCollections size mismatch: " << pos << " != " << r_size;
}
if( right_begin != right_end ) {
std::size_t l_size = pos;
while( right_begin != right_end ) {
++pos;
++right_begin;
}
res = false;
res.message() << "\nCollections size mismatch: " << l_size << " != " << pos;
}
return res;
}
//____________________________________________________________________________//
template <class Left, class Right>
inline predicate_result
bitwise_equal_impl( Left const& left, Right const& right )
{
predicate_result res( true );
std::size_t left_bit_size = sizeof(Left)*CHAR_BIT;
std::size_t right_bit_size = sizeof(Right)*CHAR_BIT;
static Left const leftOne( 1 );
static Right const rightOne( 1 );
std::size_t total_bits = left_bit_size < right_bit_size ? left_bit_size : right_bit_size;
for( std::size_t counter = 0; counter < total_bits; ++counter ) {
if( ( left & ( leftOne << counter ) ) != ( right & ( rightOne << counter ) ) ) {
res = false;
res.message() << "\nMismatch in a position " << counter;
}
}
if( left_bit_size != right_bit_size ) {
res = false;
res.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
}
return res;
}
//____________________________________________________________________________//
bool BOOST_TEST_DECL is_defined_impl( const_string symbol_name, const_string symbol_value );
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
namespace test_toolbox = test_tools;
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_TOOLS_HPP_012705GER

View File

@@ -0,0 +1,66 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : Entry point for the end user into the Unit Test Framework.
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_HPP_071894GER
// Boost.Test
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test_suite.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** Auto Linking ************** //
// ************************************************************************** //
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
# define BOOST_LIB_NAME boost_unit_test_framework
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TEST_DYN_LINK)
# define BOOST_DYN_LINK
# endif
# include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
// ************************************************************************** //
// ************** unit_test_main ************** //
// ************************************************************************** //
namespace boost { namespace unit_test {
int BOOST_TEST_DECL unit_test_main( init_unit_test_func init_func, int argc, char* argv[] );
}}
#if defined(BOOST_TEST_DYN_LINK) && defined(BOOST_TEST_MAIN) && !defined(BOOST_TEST_NO_MAIN)
// ************************************************************************** //
// ************** main function for tests using dll ************** //
// ************************************************************************** //
int BOOST_TEST_CALL_DECL
main( int argc, char* argv[] )
{
return ::boost::unit_test::unit_test_main( &init_unit_test, argc, argv );
}
//____________________________________________________________________________//
#endif // BOOST_TEST_DYN_LINK && BOOST_TEST_MAIN && !BOOST_TEST_NO_MAIN
#endif // BOOST_TEST_UNIT_TEST_HPP_071894GER

View File

@@ -0,0 +1,177 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines singleton class unit_test_log and all manipulators.
// unit_test_log has output stream like interface. It's implementation is
// completely hidden with pimple idiom
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER
// Boost.Test
#include <boost/test/test_observer.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/wrap_stringstream.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/utils/lazy_ostream.hpp>
// Boost
#include <boost/utility.hpp>
// STL
#include <iosfwd> // for std::ostream&
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** log manipulators ************** //
// ************************************************************************** //
namespace log {
struct BOOST_TEST_DECL begin {
begin( const_string fn, std::size_t ln )
: m_file_name( fn )
, m_line_num( ln )
{}
const_string m_file_name;
std::size_t m_line_num;
};
struct end {};
} // namespace log
// ************************************************************************** //
// ************** entry_value_collector ************** //
// ************************************************************************** //
namespace ut_detail {
class BOOST_TEST_DECL entry_value_collector {
public:
// Constructors
entry_value_collector() : m_last( true ) {}
entry_value_collector( entry_value_collector const& rhs ) : m_last( true ) { rhs.m_last = false; }
~entry_value_collector();
// collection interface
entry_value_collector const& operator<<( lazy_ostream const& ) const;
entry_value_collector const& operator<<( const_string ) const;
private:
// Data members
mutable bool m_last;
};
} // namespace ut_detail
// ************************************************************************** //
// ************** unit_test_log ************** //
// ************************************************************************** //
class BOOST_TEST_DECL unit_test_log_t : public test_observer, public singleton<unit_test_log_t> {
public:
// test_observer interface implementation
void test_start( counter_t test_cases_amount );
void test_finish();
void test_aborted();
void test_unit_start( test_unit const& );
void test_unit_finish( test_unit const&, unsigned long elapsed );
void test_unit_skipped( test_unit const& );
void test_unit_aborted( test_unit const& );
void assertion_result( bool passed );
void exception_caught( execution_exception const& );
virtual int priority() { return 1; }
// log configuration methods
void set_stream( std::ostream& );
void set_threshold_level( log_level );
void set_format( output_format );
void set_formatter( unit_test_log_formatter* );
// test progress logging
void set_checkpoint( const_string file, std::size_t line_num, const_string msg = const_string() );
// entry logging
unit_test_log_t& operator<<( log::begin const& ); // begin entry
unit_test_log_t& operator<<( log::end const& ); // end entry
unit_test_log_t& operator<<( log_level ); // set entry level
unit_test_log_t& operator<<( const_string ); // log entry value
unit_test_log_t& operator<<( lazy_ostream const& ); // log entry value
ut_detail::entry_value_collector operator()( log_level ); // initiate entry collection
private:
bool log_entry_start();
BOOST_TEST_SINGLETON_CONS( unit_test_log_t );
}; // unit_test_log_t
BOOST_TEST_SINGLETON_INST( unit_test_log )
// helper macros
#define BOOST_TEST_LOG_ENTRY( ll ) \
(::boost::unit_test::unit_test_log \
<< ::boost::unit_test::log::begin( BOOST_TEST_L(__FILE__), __LINE__ ))(ll) \
/**/
} // namespace unit_test
} // namespace boost
// ************************************************************************** //
// ************** Unit test log interface helpers ************** //
// ************************************************************************** //
#define BOOST_TEST_MESSAGE( M ) \
BOOST_TEST_LOG_ENTRY( ::boost::unit_test::log_messages ) \
<< (::boost::unit_test::lazy_ostream::instance() << M) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_PASSPOINT() \
::boost::unit_test::unit_test_log.set_checkpoint( \
BOOST_TEST_L(__FILE__), \
(std::size_t)__LINE__ ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_CHECKPOINT( M ) \
::boost::unit_test::unit_test_log.set_checkpoint( \
BOOST_TEST_L(__FILE__), \
(std::size_t)__LINE__, \
(::boost::wrap_stringstream().ref() << M).str() ) \
/**/
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_LOG_HPP_071894GER

View File

@@ -0,0 +1,116 @@
// (C) Copyright Gennadiy Rozental 2003-2008.
// 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: 49312 $
//
// Description :
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/log_level.hpp>
#include <boost/test/detail/fwd_decl.hpp>
// STL
#include <iosfwd>
#include <string> // for std::string
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** log_entry_data ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL log_entry_data {
log_entry_data()
{
m_file_name.reserve( 200 );
}
std::string m_file_name;
std::size_t m_line_num;
log_level m_level;
void clear()
{
m_file_name.erase();
m_line_num = 0;
m_level = log_nothing;
}
};
// ************************************************************************** //
// ************** checkpoint_data ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL log_checkpoint_data
{
const_string m_file_name;
std::size_t m_line_num;
std::string m_message;
void clear()
{
m_file_name.clear();
m_line_num = 0;
m_message = std::string();
}
};
// ************************************************************************** //
// ************** unit_test_log_formatter ************** //
// ************************************************************************** //
class BOOST_TEST_DECL unit_test_log_formatter {
public:
enum log_entry_types { BOOST_UTL_ET_INFO,
BOOST_UTL_ET_MESSAGE,
BOOST_UTL_ET_WARNING,
BOOST_UTL_ET_ERROR,
BOOST_UTL_ET_FATAL_ERROR };
// Destructor
virtual ~unit_test_log_formatter() {}
// Formatter interface
virtual void log_start( std::ostream&, counter_t test_cases_amount ) = 0;
virtual void log_finish( std::ostream& ) = 0;
virtual void log_build_info( std::ostream& ) = 0;
virtual void test_unit_start( std::ostream&, test_unit const& tu ) = 0;
virtual void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) = 0;
virtual void test_unit_skipped( std::ostream&, test_unit const& ) = 0;
virtual void log_exception( std::ostream&, log_checkpoint_data const&, const_string explanation ) = 0;
virtual void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) = 0;
virtual void log_entry_value( std::ostream&, const_string value ) = 0;
virtual void log_entry_value( std::ostream&, lazy_ostream const& value ); // there is a default impl
virtual void log_entry_finish( std::ostream& ) = 0;
};
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_LOG_FORMATTER_HPP_071894GER

View File

@@ -0,0 +1,69 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines specific version of execution monitor used to managed
// run unit of test cases. Translates execution exception into error level
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER
#define BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER
// Boost.Test
#include <boost/test/execution_monitor.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** unit_test_monitor ************** //
// ************************************************************************** //
class BOOST_TEST_DECL unit_test_monitor_t : public singleton<unit_test_monitor_t>, public execution_monitor {
public:
enum error_level {
test_fail = 1,
test_ok = 0,
constructor_error = -1,
unexpected_exception = -2,
os_exception = -3,
os_timeout = -4,
fatal_error = -5, // includes both system and user
destructor_error = -6
};
static bool is_critical_error( error_level e ) { return e <= fatal_error; }
// monitor method
error_level execute_and_translate( test_case const& );
private:
BOOST_TEST_SINGLETON_CONS( unit_test_monitor_t );
};
BOOST_TEST_SINGLETON_INST( unit_test_monitor )
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_MONITOR_HPP_020905GER

View File

@@ -0,0 +1,210 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines Unit Test Framework public API
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
// Boost.Test
#include <boost/test/unit_test_suite_impl.hpp>
#include <boost/test/test_case_template.hpp>
#include <boost/test/framework.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** Non-auto (explicit) test case interface ************** //
// ************************************************************************** //
#define BOOST_TEST_CASE( test_function ) \
boost::unit_test::make_test_case( boost::unit_test::callback0<>(test_function), BOOST_TEST_STRINGIZE( test_function ) )
#define BOOST_CLASS_TEST_CASE( test_function, tc_instance ) \
boost::unit_test::make_test_case((test_function), BOOST_TEST_STRINGIZE( test_function ), tc_instance )
// ************************************************************************** //
// ************** BOOST_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_TEST_SUITE( testsuite_name ) \
( new boost::unit_test::test_suite( testsuite_name ) )
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_SUITE( suite_name ) \
namespace suite_name { \
BOOST_AUTO_TU_REGISTRAR( suite_name )( BOOST_STRINGIZE( suite_name ) ); \
/**/
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_FIXTURE_TEST_SUITE( suite_name, F ) \
BOOST_AUTO_TEST_SUITE( suite_name ) \
typedef F BOOST_AUTO_TEST_CASE_FIXTURE; \
/**/
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_SUITE_END ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_SUITE_END() \
BOOST_AUTO_TU_REGISTRAR( BOOST_JOIN( end_suite, __LINE__ ) )( 1 ); \
} \
/**/
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( test_name, n ) \
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ); \
\
static struct BOOST_JOIN( test_name, _exp_fail_num_spec ) \
: boost::unit_test::ut_detail:: \
auto_tc_exp_fail<BOOST_AUTO_TC_UNIQUE_ID( test_name ) > \
{ \
BOOST_JOIN( test_name, _exp_fail_num_spec )() \
: boost::unit_test::ut_detail:: \
auto_tc_exp_fail<BOOST_AUTO_TC_UNIQUE_ID( test_name ) >( n ) \
{} \
} BOOST_JOIN( test_name, _exp_fail_num_spec_inst ); \
\
/**/
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_CASE ************** //
// ************************************************************************** //
#define BOOST_FIXTURE_TEST_CASE( test_name, F ) \
struct test_name : public F { void test_method(); }; \
\
static void BOOST_AUTO_TC_INVOKER( test_name )() \
{ \
test_name t; \
t.test_method(); \
} \
\
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
\
BOOST_AUTO_TU_REGISTRAR( test_name )( \
boost::unit_test::make_test_case( \
&BOOST_AUTO_TC_INVOKER( test_name ), #test_name ), \
boost::unit_test::ut_detail::auto_tc_exp_fail< \
BOOST_AUTO_TC_UNIQUE_ID( test_name )>::instance()->value() ); \
\
void test_name::test_method() \
/**/
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_CASE( test_name ) \
BOOST_FIXTURE_TEST_CASE( test_name, BOOST_AUTO_TEST_CASE_FIXTURE )
/**/
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE_TEMPLATE ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_CASE_TEMPLATE( test_name, type_name, TL ) \
template<typename type_name> \
struct test_name : public BOOST_AUTO_TEST_CASE_FIXTURE \
{ void test_method(); }; \
\
struct BOOST_AUTO_TC_INVOKER( test_name ) { \
template<typename TestType> \
static void run( boost::type<TestType>* = 0 ) \
{ \
test_name<TestType> t; \
t.test_method(); \
} \
}; \
\
BOOST_AUTO_TU_REGISTRAR( test_name )( \
boost::unit_test::ut_detail::template_test_case_gen< \
BOOST_AUTO_TC_INVOKER( test_name ),TL >( \
BOOST_STRINGIZE( test_name ) ) ); \
\
template<typename type_name> \
void test_name<type_name>::test_method() \
/**/
// ************************************************************************** //
// ************** BOOST_GLOBAL_FIXURE ************** //
// ************************************************************************** //
#define BOOST_GLOBAL_FIXTURE( F ) \
static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F ) ; \
/**/
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE_FIXTURE ************** //
// ************************************************************************** //
namespace boost { namespace unit_test { namespace ut_detail {
struct nil_t {};
} // namespace ut_detail
} // unit_test
} // namespace boost
// Intentionally is in global namespace, so that FIXURE_TEST_SUITE could reset it in user code.
typedef ::boost::unit_test::ut_detail::nil_t BOOST_AUTO_TEST_CASE_FIXTURE;
// ************************************************************************** //
// ************** Auto registration facility helper macros ************** //
// ************************************************************************** //
#define BOOST_AUTO_TU_REGISTRAR( test_name ) \
static boost::unit_test::ut_detail::auto_test_unit_registrar BOOST_JOIN( BOOST_JOIN( test_name, _registrar ), __LINE__ )
#define BOOST_AUTO_TC_INVOKER( test_name ) BOOST_JOIN( test_name, _invoker )
#define BOOST_AUTO_TC_UNIQUE_ID( test_name ) BOOST_JOIN( test_name, _id )
// ************************************************************************** //
// ************** BOOST_TEST_MAIN ************** //
// ************************************************************************** //
#if defined(BOOST_TEST_MAIN)
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
bool init_unit_test() {
#else
::boost::unit_test::test_suite*
init_unit_test_suite( int, char* [] ) {
#endif
#ifdef BOOST_TEST_MODULE
using namespace ::boost::unit_test;
assign_op( framework::master_test_suite().p_name.value, BOOST_TEST_STRINGIZE( BOOST_TEST_MODULE ).trim( "\"" ), 0 );
#endif
#ifdef BOOST_TEST_ALTERNATIVE_INIT_API
return true;
}
#else
return 0;
}
#endif
#endif
//____________________________________________________________________________//
#endif // BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER

View File

@@ -0,0 +1,354 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/callback.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/test/test_observer.hpp>
// Boost
#include <boost/shared_ptr.hpp>
// STL
#include <string> // for std::string
#include <list> // for std::list
#include <vector> // for std::vector
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_unit ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_unit {
public:
enum { type = tut_any };
// Constructor
test_unit( const_string tu_name, test_unit_type t );
// dependencies management
void depends_on( test_unit* tu );
bool check_dependencies() const;
// Public r/o properties
typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl)) id_t;
typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite)) parent_id_t;
readonly_property<test_unit_type> p_type; // type for this test unit
readonly_property<const_string> p_type_name; // "case"/"suite"
id_t p_id; // unique id for this test unit
parent_id_t p_parent_id; // parent test suite id
// Public r/w properties
readwrite_property<std::string> p_name; // name for this test unit
readwrite_property<unsigned> p_timeout; // timeout for the test unit execution
readwrite_property<counter_t> p_expected_failures; // number of expected failures in this test unit
mutable readwrite_property<bool> p_enabled; // enabled status for this unit
void increase_exp_fail( unsigned num );
protected:
~test_unit();
private:
// Data members
std::list<test_unit_id> m_dependencies;
};
// ************************************************************************** //
// ************** test_case_generator ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_unit_generator {
public:
virtual test_unit* next() const = 0;
protected:
BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
};
// ************************************************************************** //
// ************** test_case ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_case : public test_unit {
public:
enum { type = tut_case };
// Constructor
test_case( const_string tc_name, callback0<> const& test_func );
// Access methods
callback0<> const& test_func() const { return m_test_func; }
private:
friend class framework_impl;
~test_case() {}
// BOOST_MSVC <= 1200 have problems with callback as property
// Data members
callback0<> m_test_func;
};
// ************************************************************************** //
// ************** test_suite ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_suite : public test_unit {
public:
enum { type = tut_suite };
// Constructor
explicit test_suite( const_string ts_name );
// test unit list management
void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
void add( test_unit_generator const& gen, unsigned timeout = 0 );
void remove( test_unit_id id );
// access methods
test_unit_id get( const_string tu_name ) const;
std::size_t size() const { return m_members.size(); }
protected:
friend BOOST_TEST_DECL
void traverse_test_tree( test_suite const&, test_tree_visitor& );
friend class framework_impl;
virtual ~test_suite() {}
// Data members
std::vector<test_unit_id> m_members;
};
// ************************************************************************** //
// ************** master_test_suite ************** //
// ************************************************************************** //
class BOOST_TEST_DECL master_test_suite_t : public test_suite {
public:
master_test_suite_t() : test_suite( "Master Test Suite" )
, argc( 0 )
, argv( 0 )
{}
// Data members
int argc;
char** argv;
};
// ************************************************************************** //
// ************** test_tree_visitor ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_tree_visitor {
public:
// test tree visitor interface
virtual void visit( test_case const& ) {}
virtual bool test_suite_start( test_suite const& ) { return true; }
virtual void test_suite_finish( test_suite const& ) {}
protected:
BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
};
// ************************************************************************** //
// ************** traverse_test_tree ************** //
// ************************************************************************** //
BOOST_TEST_DECL void traverse_test_tree( test_case const&, test_tree_visitor& );
BOOST_TEST_DECL void traverse_test_tree( test_suite const&, test_tree_visitor& );
BOOST_TEST_DECL void traverse_test_tree( test_unit_id , test_tree_visitor& );
//____________________________________________________________________________//
inline void
traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
{
if( tu.p_type == tut_case )
traverse_test_tree( static_cast<test_case const&>( tu ), V );
else
traverse_test_tree( static_cast<test_suite const&>( tu ), V );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** test_case_counter ************** //
// ************************************************************************** //
class test_case_counter : public test_tree_visitor {
public:
// Constructor
test_case_counter() : p_count( 0 ) {}
BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
private:
// test tree visitor interface
virtual void visit( test_case const& );
virtual bool test_suite_start( test_suite const& ts ) { return ts.p_enabled; }
};
// ************************************************************************** //
// ************** test_being_aborted ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL test_being_aborted {};
// ************************************************************************** //
// ************** object generators ************** //
// ************************************************************************** //
namespace ut_detail {
BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );
template<typename InstanceType,typename UserTestCase>
struct user_tc_method_invoker {
typedef void (UserTestCase::*TestMethod )();
user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
: m_inst( inst ), m_test_method( test_method ) {}
void operator()() { ((*m_inst).*m_test_method)(); }
shared_ptr<InstanceType> m_inst;
TestMethod m_test_method;
};
} // namespace ut_detail
//____________________________________________________________________________//
inline test_case*
make_test_case( callback0<> const& test_func, const_string tc_name )
{
return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
}
//____________________________________________________________________________//
template<typename UserTestCase, typename InstanceType>
inline test_case*
make_test_case( void (UserTestCase::* test_method )(),
const_string tc_name,
boost::shared_ptr<InstanceType> user_test_case )
{
return new test_case( ut_detail::normalize_test_case_name( tc_name ),
ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** auto_test_unit_registrar ************** //
// ************************************************************************** //
namespace ut_detail {
struct BOOST_TEST_DECL auto_test_unit_registrar
{
// Constructors
auto_test_unit_registrar( test_case* tc, counter_t exp_fail );
explicit auto_test_unit_registrar( const_string ts_name );
explicit auto_test_unit_registrar( test_unit_generator const& tc_gen );
explicit auto_test_unit_registrar( int );
private:
static std::list<test_suite*>& curr_ts_store();
};
//____________________________________________________________________________//
template<typename T>
struct auto_tc_exp_fail {
auto_tc_exp_fail() : m_value( 0 ) {}
explicit auto_tc_exp_fail( unsigned v )
: m_value( v )
{
instance() = this;
}
static auto_tc_exp_fail*& instance()
{
static auto_tc_exp_fail inst;
static auto_tc_exp_fail* inst_ptr = &inst;
return inst_ptr;
}
unsigned value() const { return m_value; }
private:
// Data members
unsigned m_value;
};
//____________________________________________________________________________//
} // namespace ut_detail
// ************************************************************************** //
// ************** global_fixture ************** //
// ************************************************************************** //
class BOOST_TEST_DECL global_fixture : public test_observer {
public:
// Constructor
global_fixture();
};
//____________________________________________________________________________//
namespace ut_detail {
template<typename F>
struct global_fixture_impl : public global_fixture {
// Constructor
global_fixture_impl(): m_fixure( 0 ) {}
// test observer interface
virtual void test_start( counter_t ) { m_fixure = new F; }
virtual void test_finish() { delete m_fixure; m_fixure = 0; }
virtual void test_aborted() { delete m_fixure; m_fixure = 0; }
private:
// Data members
F* m_fixure;
};
} // namespace ut_detail
} // unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER

View File

@@ -0,0 +1,228 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : addition to STL algorithms
// ***************************************************************************
#ifndef BOOST_ALGORITHM_HPP_062304GER
#define BOOST_ALGORITHM_HPP_062304GER
#include <utility>
#include <algorithm> // std::find
#include <functional> // std::bind1st
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template <class InputIter1, class InputIter2>
inline std::pair<InputIter1, InputIter2>
mismatch( InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2 )
{
while( first1 != last1 && first2 != last2 && *first1 == *first2 ) {
++first1;
++first2;
}
return std::pair<InputIter1, InputIter2>(first1, first2);
}
//____________________________________________________________________________//
/// @brief this algorithm search through two collections for first mismatch position that get returned as a pair
/// of iterators, first pointing to the mismatch position in first collection, second iterator in second one. This algorithms
/// uses supplied predicate for collection elements comparison
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template <class InputIter1, class InputIter2, class Predicate>
inline std::pair<InputIter1, InputIter2>
mismatch( InputIter1 first1, InputIter1 last1,
InputIter2 first2, InputIter2 last2,
Predicate pred )
{
while( first1 != last1 && first2 != last2 && pred( *first1, *first2 ) ) {
++first1;
++first2;
}
return std::pair<InputIter1, InputIter2>(first1, first2);
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for first element that does not belong a second one
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class ForwardIterator1, class ForwardIterator2>
inline ForwardIterator1
find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
while( first1 != last1 ) {
if( std::find( first2, last2, *first1 ) == last2 )
break;
++first1;
}
return first1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for first element that does not satisfy binary
/// predicate in conjunction will any element in second collection
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class ForwardIterator1, class ForwardIterator2, class Predicate>
inline ForwardIterator1
find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
while( first1 != last1 ) {
if( std::find_if( first2, last2, std::bind1st( pred, *first1 ) ) == last2 )
break;
++first1;
}
return first1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that belongs to a second one
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find( first2, last2, *it1 ) == last2 ) {}
return it1 == first1 && std::find( first2, last2, *it1 ) == last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that satisfy binary
/// predicate in conjunction will at least one element in second collection
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ) {}
return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that does not belong to a second one
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
template<class BidirectionalIterator1, class ForwardIterator2>
inline BidirectionalIterator1
find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2 )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find( first2, last2, *it1 ) != last2 ) {}
return it1 == first1 && std::find( first2, last2, *it1 ) != last2 ? last1 : it1;
}
//____________________________________________________________________________//
/// @brief this algorithm search through first collection for last element that does not satisfy binary
/// predicate in conjunction will any element in second collection
/// @param first1 - first collection begin iterator
/// @param last1 - first collection end iterator
/// @param first2 - second collection begin iterator
/// @param last2 - second collection end iterator
/// @param pred - predicate to be used for search
template<class BidirectionalIterator1, class ForwardIterator2, class Predicate>
inline BidirectionalIterator1
find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
ForwardIterator2 first2, ForwardIterator2 last2,
Predicate pred )
{
if( first1 == last1 || first2 == last2 )
return last1;
BidirectionalIterator1 it1 = last1;
while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) != last2 ) {}
return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_ALGORITHM_HPP_062304GER

View File

@@ -0,0 +1,41 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : overloadable assignment
// ***************************************************************************
#ifndef BOOST_TEST_ASSIGN_OP_033005GER
#define BOOST_TEST_ASSIGN_OP_033005GER
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** generic assign operator ************** //
// ************************************************************************** //
// generic
template<typename T,typename S>
inline void
assign_op( T& t, S const& s, long )
{
t = s;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_ASSIGN_OP_033005GER

View File

@@ -0,0 +1,731 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : class basic_cstring wraps C string and provide std_string like
// interface
// ***************************************************************************
#ifndef BOOST_TEST_BASIC_CSTRING_HPP_071894GER
#define BOOST_TEST_BASIC_CSTRING_HPP_071894GER
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
#include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>
// STL
#include <string>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** basic_cstring ************** //
// ************************************************************************** //
template<typename CharT>
class basic_cstring {
typedef basic_cstring<CharT> self_type;
public:
// Subtypes
typedef ut_detail::bcs_char_traits<CharT> traits_type;
typedef typename ut_detail::bcs_char_traits<CharT>::std_string std_string;
typedef CharT value_type;
typedef value_type* pointer;
typedef value_type const* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
typedef value_type const* const_iterator;
typedef value_type* iterator;
// !! should also present reverse_iterator, const_reverse_iterator
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
enum npos_type { npos = (size_type)-1 };
#else
// IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
// But size_type is 8 bytes in 64bit mode.
static const size_type npos = -1 ;
#endif
static pointer null_str();
// Constructors; default copy constructor is generated by compiler
basic_cstring();
basic_cstring( std_string const& s );
basic_cstring( pointer s );
basic_cstring( pointer s, size_type arg_size );
basic_cstring( pointer first, pointer last );
// data access methods
value_type operator[]( size_type index ) const;
value_type at( size_type index ) const;
// size operators
size_type size() const;
bool is_empty() const;
void clear();
void resize( size_type new_len );
// !! only for STL container conformance use is_empty instead
bool empty() const;
// Trimming
self_type& trim_right( size_type trim_size );
self_type& trim_left( size_type trim_size );
self_type& trim_right( iterator it );
self_type& trim_left( iterator it );
#ifndef __IBMCPP__
self_type& trim_left( self_type exclusions = self_type() ) ;
self_type& trim_right( self_type exclusions = self_type() ) ;
self_type& trim( self_type exclusions = self_type() ) ;
#else
// VisualAge version 6 has in this case a problem with the default arguments.
self_type& trim_left( self_type exclusions ) ;
self_type& trim_right( self_type exclusions ) ;
self_type& trim( self_type exclusions ) ;
self_type& trim_left() { trim_left( self_type() ) ; }
self_type& trim_right() { trim_right( self_type() ) ; }
self_type& trim() { trim( self_type() ) ; }
#endif
// Assignment operators
basic_cstring& operator=( self_type const& s );
basic_cstring& operator=( std_string const& s );
basic_cstring& operator=( pointer s );
template<typename CharT2>
basic_cstring& assign( basic_cstring<CharT2> const& s ) { *this = basic_cstring<CharT>( s.begin(), s.end() ); return *this; }
basic_cstring& assign( self_type const& s, size_type pos, size_type len );
basic_cstring& assign( std_string const& s );
basic_cstring& assign( std_string const& s, size_type pos, size_type len );
basic_cstring& assign( pointer s );
basic_cstring& assign( pointer s, size_type len );
basic_cstring& assign( pointer f, pointer l );
// swapping
void swap( self_type& s );
// Iterators
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
// !! should have rbegin, rend
// substring search operation
size_type find( basic_cstring ) const;
size_type rfind( basic_cstring ) const;
self_type substr( size_type beg_index, size_type end_index = npos ) const;
private:
static self_type default_trim_ex();
// Data members
iterator m_begin;
iterator m_end;
};
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::pointer
basic_cstring<CharT>::null_str()
{
static CharT null = 0;
return &null;
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring()
: m_begin( null_str() )
, m_end( m_begin )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( std_string const& s )
: m_begin( s.c_str() )
, m_end( m_begin + s.size() )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer s )
: m_begin( s ? s : null_str() )
, m_end ( m_begin + (s ? traits_type::length( s ) : 0 ) )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer s, size_type arg_size )
: m_begin( s ), m_end( m_begin + arg_size )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline
basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
: m_begin( first )
, m_end( last )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::value_type
basic_cstring<CharT>::operator[]( size_type index ) const
{
return m_begin[index];
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::value_type
basic_cstring<CharT>::at( size_type index ) const
{
if( m_begin + index >= m_end )
return (value_type)0;
return m_begin[index];
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::size() const
{
return m_end - m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
basic_cstring<CharT>::is_empty() const
{
return m_end == m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
basic_cstring<CharT>::empty() const
{
return is_empty();
}
//____________________________________________________________________________//
template<typename CharT>
inline void
basic_cstring<CharT>::clear()
{
m_begin = m_end;
}
//____________________________________________________________________________//
template<typename CharT>
inline void
basic_cstring<CharT>::resize( size_type new_len )
{
if( m_begin + new_len < m_end )
m_end = m_begin + new_len;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( size_type trim_size )
{
m_begin += trim_size;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( iterator it )
{
m_begin = it;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_left( basic_cstring exclusions )
{
if( exclusions.is_empty() )
exclusions = default_trim_ex();
iterator it;
for( it = begin(); it != end(); ++it ) {
if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == (pointer)0 )
break;
}
return trim_left( it );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( size_type trim_size )
{
m_end -= trim_size;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( iterator it )
{
m_end = it;
if( m_end <= m_begin )
clear();
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim_right( basic_cstring exclusions )
{
if( exclusions.is_empty() )
exclusions = default_trim_ex();
iterator it;
for( it = end()-1; it != begin()-1; --it ) {
if( self_type::traits_type::find( exclusions.begin(), exclusions.size(), *it ) == (pointer)0 )
break;
}
return trim_right( it+1 );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::trim( basic_cstring exclusions )
{
trim_left( exclusions );
trim_right( exclusions );
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s )
{
m_begin = s.m_begin;
m_end = s.m_end;
return *this;
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( std_string const& s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::operator=( pointer s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( basic_cstring<CharT> const& s, size_type pos, size_type len )
{
return *this = self_type( s.m_begin + pos, len );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( std_string const& s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( std_string const& s, size_type pos, size_type len )
{
return *this = self_type( s.c_str() + pos, len );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer s, size_type len )
{
return *this = self_type( s, len );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>&
basic_cstring<CharT>::assign( pointer f, pointer l )
{
return *this = self_type( f, l );
}
//____________________________________________________________________________//
template<typename CharT>
inline void
basic_cstring<CharT>::swap( basic_cstring<CharT>& s )
{
// do not want to include alogrithm
pointer tmp1 = m_begin;
pointer tmp2 = m_end;
m_begin = s.m_begin;
m_end = s.m_end;
s.m_begin = tmp1;
s.m_end = tmp2;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::iterator
basic_cstring<CharT>::begin()
{
return m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::const_iterator
basic_cstring<CharT>::begin() const
{
return m_begin;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::iterator
basic_cstring<CharT>::end()
{
return m_end;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::const_iterator
basic_cstring<CharT>::end() const
{
return m_end;
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::find( basic_cstring<CharT> str ) const
{
if( str.is_empty() || str.size() > size() )
return (size_type)npos;
const_iterator it = begin();
const_iterator last = end() - str.size() + 1;
while( it != last ) {
if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
break;
++it;
}
return it == last ? (size_type)npos : it - begin();
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::rfind( basic_cstring<CharT> str ) const
{
if( str.is_empty() || str.size() > size() )
return (size_type)npos;
const_iterator it = end() - str.size();
const_iterator last = begin()-1;
while( it != last ) {
if( traits_type::compare( it, str.begin(), str.size() ) == 0 )
break;
--it;
}
return it == last ? npos : it - begin();
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>
basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const
{
return beg_index > size()
? self_type()
: end_index > size()
? self_type( m_begin + beg_index, m_end )
: self_type( m_begin + beg_index, m_begin + end_index );
}
//____________________________________________________________________________//
template<typename CharT>
inline basic_cstring<CharT>
basic_cstring<CharT>::default_trim_ex()
{
static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; // !! wide case
return self_type( ws, 3 );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** comparison operators ************** //
// ************************************************************************** //
template<typename CharT1,typename CharT2>
inline bool
operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 )
{
typedef typename basic_cstring<CharT1>::traits_type traits_type;
return s1.size() == s2.size() &&
traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0;
}
//____________________________________________________________________________//
template<typename CharT1,typename CharT2>
inline bool
operator==( basic_cstring<CharT1> const& s1, CharT2* s2 )
{
#if !defined(__DMC__)
return s1 == basic_cstring<CharT2>( s2 );
#else
return s1 == basic_cstring<CharT2 const>( s2 );
#endif
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
{
return s1 == basic_cstring<CharT>( s2 );
}
//____________________________________________________________________________//
template<typename CharT1,typename CharT2>
inline bool
operator==( CharT1* s2, basic_cstring<CharT2> const& s1 )
{
return s1 == s2;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
{
return s1 == s2;
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, CharT* s2 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( CharT* s2, basic_cstring<CharT> const& s1 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
template<typename CharT>
inline bool
operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
{
return !(s1 == s2);
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** first_char ************** //
// ************************************************************************** //
template<typename CharT>
inline typename basic_cstring<CharT>::value_type
first_char( basic_cstring<CharT> source )
{
typedef typename basic_cstring<CharT>::value_type string_value_type;
return source.is_empty() ? (string_value_type)0 : *source.begin();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** last_char ************** //
// ************************************************************************** //
template<typename CharT>
inline typename basic_cstring<CharT>::value_type
last_char( basic_cstring<CharT> source )
{
typedef typename basic_cstring<CharT>::value_type string_value_type;
return source.is_empty() ? (string_value_type)0 : *(source.end()-1);
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** assign_op ************** //
// ************************************************************************** //
template<typename CharT1, typename CharT2>
inline void
assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
{
target.assign( src.begin(), src.size() );
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BASIC_CSTRING_HPP_071894GER

View File

@@ -0,0 +1,40 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : basic_cstring class wrap C string and provide std_string like
// interface
// ***************************************************************************
#ifndef BOOST_TEST_BASIC_CSTRING_FWD_HPP_071894GER
#define BOOST_TEST_BASIC_CSTRING_FWD_HPP_071894GER
#include <boost/detail/workaround.hpp>
namespace boost {
namespace unit_test {
template<typename CharT> class basic_cstring;
typedef basic_cstring<char const> const_string;
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041))
typedef const_string literal_string;
#else
typedef const_string const literal_string;
#endif
typedef char const* const c_literal_string;
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_BASIC_CSTRING_FWD_HPP_071894GER

View File

@@ -0,0 +1,150 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : generic char traits class; wraps std::char_traits
// ***************************************************************************
#ifndef BOOST_TEST_BCS_CHAR_TRAITS_HPP_071894GER
#define BOOST_TEST_BCS_CHAR_TRAITS_HPP_071894GER
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/test/detail/config.hpp>
#include <boost/type_traits/add_const.hpp>
// STL
#include <string> // std::char_traits
#include <cstddef> // std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
template<typename CharT> struct bcs_base_char { typedef CharT type; };
template<> struct bcs_base_char<char const> { typedef char type; };
template<> struct bcs_base_char<unsigned char> { typedef char type; };
#if !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
template<> struct bcs_base_char<unsigned char const> { typedef char type; };
#endif
template<> struct bcs_base_char<wchar_t const> { typedef wchar_t type; };
// ************************************************************************** //
// ************** bcs_char_traits ************** //
// ************************************************************************** //
template<typename CharT>
struct bcs_char_traits_impl
{
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
typedef CharT const const_char;
#else
typedef typename boost::add_const<CharT>::type const_char;
#endif
static bool eq( CharT c1, CharT c2 )
{
return c1 == c2;
}
static bool lt( CharT c1, CharT c2 )
{
return c1 < c2;
}
static int compare( const_char* cstr1, const_char* cstr2, std::size_t n )
{
while( n > 0 ) {
if( !eq( *cstr1, *cstr2 ) )
return lt( *cstr1, *cstr2 ) ? -1 : 1;
++cstr1;
++cstr2;
--n;
}
return 0;
}
static std::size_t length( const_char* cstr )
{
const_char null_char = CharT();
const_char* ptr = cstr;
while( !eq( *ptr, null_char ) )
++ptr;
return ptr - cstr;
}
static const_char* find( const_char* s, std::size_t n, CharT c )
{
while( n > 0 ) {
if( eq( *s, c ) )
return s;
++s;
--n;
}
return 0;
}
};
#ifdef BOOST_CLASSIC_IOSTREAMS
template<typename CharT>
struct char_traits_with_find : std::string_char_traits<CharT> {
static CharT const* find( CharT const* s, std::size_t n, CharT c )
{
while( n > 0 ) {
if( eq( *s, c ) )
return s;
++s;
--n;
}
return 0;
}
};
template<> struct bcs_char_traits_impl<char> : char_traits_with_find<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : char_traits_with_find<wchar_t> {};
#else
template<> struct bcs_char_traits_impl<char> : std::char_traits<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : std::char_traits<wchar_t> {};
#endif
template<typename CharT>
class bcs_char_traits : public bcs_char_traits_impl<CharT> {
typedef typename ut_detail::bcs_base_char<CharT>::type the_base_char;
public:
#ifdef BOOST_CLASSIC_IOSTREAMS
typedef std::basic_string<the_base_char, std::string_char_traits<the_base_char> > std_string;
#else
typedef std::basic_string<the_base_char, std::char_traits<the_base_char> > std_string;
#endif
};
} // namespace ut_detail
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BCS_CHAR_TRAITS_HPP_071894GER

View File

@@ -0,0 +1,115 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : class basic_cstring comparisons implementation
// ***************************************************************************
#ifndef BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER
#define BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <functional>
#include <cctype>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
# if defined(BOOST_NO_STDC_NAMESPACE) && !BOOST_WORKAROUND(__BORLANDC__, <= 0x570)
namespace std { using ::toupper; }
# endif
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** case_ins_compare ************** //
// ************************************************************************** //
namespace ut_detail {
template<class CharT>
struct case_ins
{
static bool eq( CharT c1, CharT c2 ) { return (std::toupper)( c1 ) == (std::toupper)( c2 ); }
static bool lt( CharT c1, CharT c2 ) { return (std::toupper)( c1 ) < (std::toupper)( c2 ); }
static int compare( CharT const* s1, CharT const* s2, std::size_t n )
{
for( std::size_t i = 0; i < n; ++i ) {
if( !eq( s1[i], s2[i] ) )
return lt( s1[i], s2[i] ) ? -1 : 1;
}
return 0;
}
};
} // namespace ut_detail
// ************************************************************************** //
// ************** case_ins_eq ************** //
// ************************************************************************** //
template<class CharT>
inline bool
case_ins_eq( basic_cstring<CharT> x, basic_cstring<CharT> y )
{
return x.size() == y.size() && ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) == 0;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** case_ins_less ************** //
// ************************************************************************** //
template<class CharT>
class case_ins_less : public std::binary_function<basic_cstring<CharT>,basic_cstring<CharT>,bool>
{
public:
bool operator()( basic_cstring<CharT> x, basic_cstring<CharT> y ) const
{
return x.size() != y.size()
? x.size() < y.size()
: ut_detail::case_ins<CharT>::compare( x.begin(), y.begin(), x.size() ) < 0;
}
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** operator < ************** //
// ************************************************************************** //
template<class CharT>
inline bool
operator <( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
typedef typename boost::unit_test::basic_cstring<CharT>::traits_type traits_type;
return x.size() != y.size()
? x.size() < y.size()
: traits_type::compare( x.begin(), y.begin(), x.size() ) < 0;
}
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BASIC_CSTRING_COMPARE_HPP_071894GER

View File

@@ -0,0 +1,73 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : basic_cstring i/o implementation
// ***************************************************************************
#ifndef BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER
#define BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
// STL
#include <iosfwd>
#include <string>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
#ifdef BOOST_CLASSIC_IOSTREAMS
template<typename CharT>
inline std::ostream&
operator<<( std::ostream& os, basic_cstring<CharT> const& str )
{
typedef typename ut_detail::bcs_base_char<CharT>::type char_type;
char_type const* const beg = reinterpret_cast<char_type const* const>( str.begin() );
char_type const* const end = reinterpret_cast<char_type const* const>( str.end() );
os << std::basic_string<char_type>( beg, end - beg );
return os;
}
#else
template<typename CharT1, typename Tr,typename CharT2>
inline std::basic_ostream<CharT1,Tr>&
operator<<( std::basic_ostream<CharT1,Tr>& os, basic_cstring<CharT2> const& str )
{
CharT1 const* const beg = reinterpret_cast<CharT1 const*>( str.begin() ); // !!
CharT1 const* const end = reinterpret_cast<CharT1 const*>( str.end() );
os << std::basic_string<CharT1,Tr>( beg, end - beg );
return os;
}
#endif
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_BASIC_CSTRING_IO_HPP_071894GER

View File

@@ -0,0 +1,310 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description :
// ***************************************************************************
#ifndef BOOST_TEST_CALLBACK_020505GER
#define BOOST_TEST_CALLBACK_020505GER
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300) || BOOST_WORKAROUND(BOOST_INTEL, <= 700)
# define BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
struct unused {};
template<typename R>
struct invoker {
template<typename Functor>
R invoke( Functor& f ) { return f(); }
template<typename Functor, typename T1>
R invoke( Functor& f, T1 t1 ) { return f( t1 ); }
template<typename Functor, typename T1, typename T2>
R invoke( Functor& f, T1 t1, T2 t2 ) { return f( t1, t2 ); }
template<typename Functor, typename T1, typename T2, typename T3>
R invoke( Functor& f, T1 t1, T2 t2, T3 t3 ) { return f( t1, t2, t3 ); }
};
//____________________________________________________________________________//
template<>
struct invoker<unused> {
template<typename Functor>
unused invoke( Functor& f ) { f(); return unused(); }
template<typename Functor, typename T1>
unused invoke( Functor& f, T1 t1 ) { f( t1 ); return unused(); }
template<typename Functor, typename T1, typename T2>
unused invoke( Functor& f, T1 t1, T2 t2 ) { f( t1, t2 ); return unused(); }
template<typename Functor, typename T1, typename T2, typename T3>
unused invoke( Functor& f, T1 t1, T2 t2, T3 t3 ) { f( t1, t2, t3 ); return unused(); }
};
//____________________________________________________________________________//
} // namespace ut_detail
// ************************************************************************** //
// ************** unit_test::callback0 ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename R>
struct callback0_impl {
virtual ~callback0_impl() {}
virtual R invoke() = 0;
};
//____________________________________________________________________________//
template<typename R, typename Functor>
struct callback0_impl_t : callback0_impl<R> {
// Constructor
explicit callback0_impl_t( Functor f ) : m_f( f ) {}
virtual R invoke() { return invoker<R>().invoke( m_f ); }
private:
// Data members
Functor m_f;
};
//____________________________________________________________________________//
} // namespace ut_detail
template<typename R = ut_detail::unused>
class callback0 {
public:
// Constructors
callback0() {}
#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
callback0( callback0 const& rhs ) : m_impl( rhs.m_impl ) {}
#endif
template<typename Functor>
callback0( Functor f )
: m_impl( new ut_detail::callback0_impl_t<R,Functor>( f ) ) {}
void operator=( callback0 const& rhs ) { m_impl = rhs.m_impl; }
template<typename Functor>
void operator=( Functor f ) { m_impl.reset( new ut_detail::callback0_impl_t<R,Functor>( f ) ); }
R operator()() const { return m_impl->invoke(); }
bool operator!() const { return !m_impl; }
private:
// Data members
boost::shared_ptr<ut_detail::callback0_impl<R> > m_impl;
};
// ************************************************************************** //
// ************** unit_test::callback1 ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename R, typename T1>
struct callback1_impl {
virtual ~callback1_impl() {}
virtual R invoke( T1 t1 ) = 0;
};
//____________________________________________________________________________//
template<typename R, typename T1,typename Functor>
struct callback1_impl_t : callback1_impl<R,T1> {
// Constructor
explicit callback1_impl_t( Functor f ) : m_f( f ) {}
virtual R invoke( T1 t1 ) { return invoker<R>().invoke( m_f, t1 ); }
private:
// Data members
Functor m_f;
};
//____________________________________________________________________________//
} // namespace ut_detail
template<typename T1,typename R = ut_detail::unused>
class callback1 {
public:
// Constructors
callback1() {}
#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
callback1( callback1 const& rhs ) : m_impl( rhs.m_impl ) {}
#endif
template<typename Functor>
callback1( Functor f )
: m_impl( new ut_detail::callback1_impl_t<R,T1,Functor>( f ) ) {}
void operator=( callback1 const& rhs ) { m_impl = rhs.m_impl; }
template<typename Functor>
void operator=( Functor f ) { m_impl.reset( new ut_detail::callback1_impl_t<R,T1,Functor>( f ) ); }
R operator()( T1 t1 ) const { return m_impl->invoke( t1 ); }
bool operator!() const { return !m_impl; }
private:
// Data members
boost::shared_ptr<ut_detail::callback1_impl<R,T1> > m_impl;
};
// ************************************************************************** //
// ************** unit_test::callback2 ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename R, typename T1,typename T2>
struct callback2_impl {
virtual ~callback2_impl() {}
virtual R invoke( T1 t1, T2 t2 ) = 0;
};
//____________________________________________________________________________//
template<typename R, typename T1, typename T2, typename Functor>
struct callback2_impl_t : callback2_impl<R,T1,T2> {
// Constructor
explicit callback2_impl_t( Functor f ) : m_f( f ) {}
virtual R invoke( T1 t1, T2 t2 ) { return invoker<R>().template invoke<Functor,T1,T2>( m_f, t1, t2 ); }
private:
// Data members
Functor m_f;
};
//____________________________________________________________________________//
} // namespace ut_detail
template<typename T1,typename T2, typename R = ut_detail::unused>
class callback2 {
public:
// Constructors
callback2() {}
#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
callback2( callback2 const& rhs ) : m_impl( rhs.m_impl ) {}
#endif
template<typename Functor>
callback2( Functor f ) : m_impl( new ut_detail::callback2_impl_t<R,T1,T2,Functor>( f ) ) {}
void operator=( callback2 const& rhs ) { m_impl = rhs.m_impl; }
template<typename Functor>
void operator=( Functor f ) { m_impl.reset( new ut_detail::callback2_impl_t<R,T1,T2,Functor>( f ) ); }
R operator()( T1 t1, T2 t2 ) const { return m_impl->invoke( t1, t2 ); }
bool operator!() const { return !m_impl; }
private:
// Data members
boost::shared_ptr<ut_detail::callback2_impl<R,T1,T2> > m_impl;
};
// ************************************************************************** //
// ************** unit_test::callback3 ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename R, typename T1, typename T2, typename T3>
struct callback3_impl {
virtual ~callback3_impl() {}
virtual R invoke( T1 t1, T2 t2, T3 t3 ) = 0;
};
//____________________________________________________________________________//
template<typename R, typename T1, typename T2, typename T3, typename Functor>
struct callback3_impl_t : callback3_impl<R,T1,T2,T3> {
// Constructor
explicit callback3_impl_t( Functor f ) : m_f( f ) {}
virtual R invoke( T1 t1, T2 t2, T3 t3 ) { return invoker<R>().invoke( m_f, t1, t2, t3 ); }
private:
// Data members
Functor m_f;
};
//____________________________________________________________________________//
} // namespace ut_detail
template<typename T1,typename T2, typename T3, typename R = ut_detail::unused>
class callback3 {
public:
// Constructors
callback3() {}
#ifdef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
callback3( callback3 const& rhs ) : m_impl( rhs.m_impl ) {}
#endif
template<typename Functor>
callback3( Functor f )
: m_impl( new ut_detail::callback3_impl_t<R,T1,T2,T3,Functor>( f ) ) {}
void operator=( callback3 const& rhs ) { m_impl = rhs.m_impl; }
template<typename Functor>
void operator=( Functor f ) { m_impl.reset( new ut_detail::callback3_impl_t<R,T1,T2,T3,Functor>( f ) ); }
R operator()( T1 t1, T2 t2, T3 t3 ) const { return m_impl->invoke( t1, t2, t3 ); }
bool operator!() const { return !m_impl; }
private:
// Data members
boost::shared_ptr<ut_detail::callback3_impl<R,T1,T2,T3> > m_impl;
};
} // namespace unit_test
} // namespace boost
#undef BOOST_CALLBACK_EXPLICIT_COPY_CONSTRUCTOR
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_CALLBACK_020505GER

View File

@@ -0,0 +1,225 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : simple facility that mimmic notion of read-only read-write
// properties in C++ classes. Original idea by Henrik Ravn.
// ***************************************************************************
#ifndef BOOST_TEST_CLASS_PROPERTIES_HPP_071894GER
#define BOOST_TEST_CLASS_PROPERTIES_HPP_071894GER
// Boost.Test
#include <boost/test/detail/config.hpp>
// Boost
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
#include <boost/preprocessor/seq/for_each.hpp>
#endif
#include <boost/call_traits.hpp>
#include <boost/type_traits/add_pointer.hpp>
#include <boost/type_traits/add_const.hpp>
#include <boost/utility/addressof.hpp>
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** class_property ************** //
// ************************************************************************** //
template<class PropertyType>
class class_property {
protected:
typedef typename call_traits<PropertyType>::const_reference read_access_t;
typedef typename call_traits<PropertyType>::param_type write_param_t;
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x570))
typedef typename add_pointer<PropertyType const>::type address_res_t;
#else
typedef typename add_pointer<typename add_const<PropertyType>::type>::type address_res_t;
#endif
public:
// Constructor
class_property() : value( PropertyType() ) {}
explicit class_property( write_param_t init_value )
: value( init_value ) {}
// Access methods
operator read_access_t() const { return value; }
read_access_t get() const { return value; }
bool operator!() const { return !value; }
address_res_t operator&() const { return &value; }
// Data members
#ifndef BOOST_TEST_NO_PROTECTED_USING
protected:
#endif
PropertyType value;
};
//____________________________________________________________________________//
#ifdef BOOST_CLASSIC_IOSTREAMS
template<class PropertyType>
inline std::ostream&
operator<<( std::ostream& os, class_property<PropertyType> const& p )
#else
template<typename CharT1, typename Tr,class PropertyType>
inline std::basic_ostream<CharT1,Tr>&
operator<<( std::basic_ostream<CharT1,Tr>& os, class_property<PropertyType> const& p )
#endif
{
return os << p.get();
}
//____________________________________________________________________________//
#define DEFINE_PROPERTY_FREE_BINARY_OPERATOR( op ) \
template<class PropertyType> \
inline bool \
operator op( PropertyType const& lhs, class_property<PropertyType> const& rhs ) \
{ \
return lhs op rhs.get(); \
} \
template<class PropertyType> \
inline bool \
operator op( class_property<PropertyType> const& lhs, PropertyType const& rhs ) \
{ \
return lhs.get() op rhs; \
} \
template<class PropertyType> \
inline bool \
operator op( class_property<PropertyType> const& lhs, \
class_property<PropertyType> const& rhs ) \
{ \
return lhs.get() op rhs.get(); \
} \
/**/
DEFINE_PROPERTY_FREE_BINARY_OPERATOR( == )
DEFINE_PROPERTY_FREE_BINARY_OPERATOR( != )
#undef DEFINE_PROPERTY_FREE_BINARY_OPERATOR
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
#define DEFINE_PROPERTY_LOGICAL_OPERATOR( op ) \
template<class PropertyType> \
inline bool \
operator op( bool b, class_property<PropertyType> const& p ) \
{ \
return b op p.get(); \
} \
template<class PropertyType> \
inline bool \
operator op( class_property<PropertyType> const& p, bool b ) \
{ \
return b op p.get(); \
} \
/**/
DEFINE_PROPERTY_LOGICAL_OPERATOR( && )
DEFINE_PROPERTY_LOGICAL_OPERATOR( || )
#endif
// ************************************************************************** //
// ************** readonly_property ************** //
// ************************************************************************** //
template<class PropertyType>
class readonly_property : public class_property<PropertyType> {
typedef class_property<PropertyType> base_prop;
typedef typename base_prop::address_res_t arrow_res_t;
protected:
typedef typename base_prop::write_param_t write_param_t;
public:
// Constructor
readonly_property() {}
explicit readonly_property( write_param_t init_value ) : base_prop( init_value ) {}
// access methods
arrow_res_t operator->() const { return boost::addressof( base_prop::value ); }
};
//____________________________________________________________________________//
#if BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
#define BOOST_READONLY_PROPERTY( property_type, friends ) boost::unit_test::readwrite_property<property_type >
#else
#define BOOST_READONLY_PROPERTY_DECLARE_FRIEND(r, data, elem) friend class elem;
#define BOOST_READONLY_PROPERTY( property_type, friends ) \
class BOOST_JOIN( readonly_property, __LINE__ ) \
: public boost::unit_test::readonly_property<property_type > { \
typedef boost::unit_test::readonly_property<property_type > base_prop; \
BOOST_PP_SEQ_FOR_EACH( BOOST_READONLY_PROPERTY_DECLARE_FRIEND, ' ', friends ) \
typedef base_prop::write_param_t write_param_t; \
public: \
BOOST_JOIN( readonly_property, __LINE__ )() {} \
explicit BOOST_JOIN( readonly_property, __LINE__ )( write_param_t init_v ) \
: base_prop( init_v ) {} \
} \
/**/
#endif
// ************************************************************************** //
// ************** readwrite_property ************** //
// ************************************************************************** //
template<class PropertyType>
class readwrite_property : public class_property<PropertyType> {
typedef class_property<PropertyType> base_prop;
typedef typename add_pointer<PropertyType>::type arrow_res_t;
typedef typename base_prop::address_res_t const_arrow_res_t;
typedef typename base_prop::write_param_t write_param_t;
public:
readwrite_property() : base_prop() {}
explicit readwrite_property( write_param_t init_value ) : base_prop( init_value ) {}
// access methods
void set( write_param_t v ) { base_prop::value = v; }
arrow_res_t operator->() { return boost::addressof( base_prop::value ); }
const_arrow_res_t operator->() const { return boost::addressof( base_prop::value ); }
#ifndef BOOST_TEST_NO_PROTECTED_USING
using base_prop::value;
#endif
};
//____________________________________________________________________________//
} // unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#undef BOOST_TEST_NO_PROTECTED_USING
#endif // BOOST_TEST_CLASS_PROPERTIES_HPP_071894GER

View File

@@ -0,0 +1,63 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : simple helpers for creating cusom output manipulators
// ***************************************************************************
#ifndef BOOST_TEST_CUSTOM_MANIP_HPP_071894GER
#define BOOST_TEST_CUSTOM_MANIP_HPP_071894GER
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** custom manipulators helpers ************** //
// ************************************************************************** //
template<typename Manip>
struct custom_printer {
explicit custom_printer( std::ostream& ostr ) : m_ostr( &ostr ) {}
std::ostream& operator*() const { return *m_ostr; }
private:
std::ostream* const m_ostr;
};
//____________________________________________________________________________//
template<typename Uniq> struct custom_manip {};
//____________________________________________________________________________//
template<typename Uniq>
inline custom_printer<custom_manip<Uniq> >
operator<<( std::ostream& ostr, custom_manip<Uniq> const& ) { return custom_printer<custom_manip<Uniq> >( ostr ); }
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_CUSTOM_MANIP_HPP_071894GER

View File

@@ -0,0 +1,124 @@
// (C) Copyright Gennadiy Rozental 2001-2008.
// 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: 49312 $
//
// Description : fixed sized mapping with specified invalid value
// ***************************************************************************
#ifndef BOOST_TEST_FIXED_MAPPING_HPP_071894GER
#define BOOST_TEST_FIXED_MAPPING_HPP_071894GER
// Boost
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
#include <boost/call_traits.hpp>
#include <boost/detail/binary_search.hpp>
// STL
#include <vector>
#include <functional>
#include <algorithm>
#include <utility>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// configurable maximum fixed sized mapping size supported by this header.
// You could redefine it before inclusion of this file.
#ifndef MAX_MAP_SIZE
#define MAX_MAP_SIZE 20
#endif
#define CONSTR_DECL_MID( z, i, dummy1 ) key_param_type key##i, value_param_type v##i,
#define CONSTR_BODY_MID( z, i, dummy1 ) add_pair( key##i, v##i );
#define CONSTR_DECL( z, n, dummy1 ) \
fixed_mapping( BOOST_PP_REPEAT_ ## z( n, CONSTR_DECL_MID, "" ) \
value_param_type invalid_value ) \
: m_invalid_value( invalid_value ) \
{ \
BOOST_PP_REPEAT_ ## z( n, CONSTR_BODY_MID, "" ) \
init(); \
} \
/**/
#define CONTRUCTORS( n ) BOOST_PP_REPEAT( n, CONSTR_DECL, "" )
template<typename Key, typename Value, typename Compare = std::less<Key> >
class fixed_mapping
{
typedef std::pair<Key,Value> elem_type;
typedef std::vector<elem_type> map_type;
typedef typename std::vector<elem_type>::const_iterator iterator;
typedef typename call_traits<Key>::param_type key_param_type;
typedef typename call_traits<Value>::param_type value_param_type;
typedef typename call_traits<Value>::const_reference value_ref_type;
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
struct p1; friend struct p1;
struct p2; friend struct p2;
#endif
// bind( Compare(), bind(select1st<elem_type>(), _1), bind(identity<Key>(), _2) )
struct p1 : public std::binary_function<elem_type,Key,bool>
{
bool operator()( elem_type const& x, Key const& y ) const { return Compare()( x.first, y ); }
};
// bind( Compare(), bind(select1st<elem_type>(), _1), bind(select1st<elem_type>(), _2) )
struct p2 : public std::binary_function<elem_type,elem_type,bool>
{
bool operator()( elem_type const& x, elem_type const& y ) const { return Compare()( x.first, y.first ); }
};
public:
// Constructors
CONTRUCTORS( BOOST_PP_ADD( MAX_MAP_SIZE, 1 ) )
// key -> value access
value_ref_type operator[]( key_param_type key ) const
{
iterator it = boost::detail::lower_bound( m_map.begin(), m_map.end(), key, p1() );
return (it == m_map.end() || Compare()( key, it->first ) ) ? m_invalid_value : it->second;
}
private:
// Implementation
void init() { std::sort( m_map.begin(), m_map.end(), p2() ); }
void add_pair( key_param_type key, value_param_type value ) { m_map.push_back( elem_type( key, value ) ); }
// Data members
Value m_invalid_value;
map_type m_map;
};
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#undef MAX_MAP_SIZE
#undef CONSTR_DECL_MID
#undef CONSTR_BODY_MID
#undef CONSTR_DECL
#undef CONTRUCTORS
#endif // BOOST_TEST_FIXED_MAPPING_HPP_071894GER

View File

@@ -0,0 +1,281 @@
// (C) Copyright Eric Niebler 2004-2005
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : this is an abridged version of an excelent BOOST_FOREACH facility
// presented by Eric Niebler. I am so fond of it so I couldn't wait till it
// going to be accepted into Boost. Also I need version with less number of dependencies
// and more portable. This version doesn't support rvalues and will reeveluate it's
// parameters, but should be good enough for my purposes.
// ***************************************************************************
#ifndef BOOST_TEST_FOREACH_HPP_021005GER
#define BOOST_TEST_FOREACH_HPP_021005GER
// Boost.Test
#include <boost/test/detail/config.hpp>
// Boost
#include <boost/type.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace for_each {
// ************************************************************************** //
// ************** static_any ************** //
// ************************************************************************** //
struct static_any_base
{
operator bool() const { return false; }
};
//____________________________________________________________________________//
template<typename Iter>
struct static_any : static_any_base
{
static_any( Iter const& t ) : m_it( t ) {}
mutable Iter m_it;
};
//____________________________________________________________________________//
typedef static_any_base const& static_any_t;
//____________________________________________________________________________//
template<typename Iter>
inline Iter&
static_any_cast( static_any_t a, Iter* = 0 )
{
return static_cast<Iter&>( static_cast<static_any<Iter> const&>( a ).m_it );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** is_const ************** //
// ************************************************************************** //
template<typename C>
inline is_const<C>
is_const_coll( C& )
{
return is_const<C>();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** begin ************** //
// ************************************************************************** //
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::iterator>
begin( C& t, mpl::false_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.begin() );
}
//____________________________________________________________________________//
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>
begin( C const& t, mpl::true_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.begin() );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** end ************** //
// ************************************************************************** //
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::iterator>
end( C& t, mpl::false_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::iterator>( t.end() );
}
//____________________________________________________________________________//
template<typename C>
inline static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>
end( C const& t, mpl::true_ )
{
return static_any<BOOST_DEDUCED_TYPENAME C::const_iterator>( t.end() );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** done ************** //
// ************************************************************************** //
template<typename C>
inline bool
done( static_any_t cur, static_any_t end, C&, mpl::false_ )
{
return static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur ) ==
static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( end );
}
//____________________________________________________________________________//
template<typename C>
inline bool
done( static_any_t cur, static_any_t end, C const&, mpl::true_ )
{
return static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur ) ==
static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( end );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** next ************** //
// ************************************************************************** //
template<typename C>
inline void
next( static_any_t cur, C&, mpl::false_ )
{
++static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
}
//____________________________________________________________________________//
template<typename C>
inline void
next( static_any_t cur, C const&, mpl::true_ )
{
++static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** deref ************** //
// ************************************************************************** //
template<class RefType,typename C>
inline RefType
deref( static_any_t cur, C&, ::boost::type<RefType>, mpl::false_ )
{
return *static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
}
//____________________________________________________________________________//
template<class RefType,typename C>
inline RefType
deref( static_any_t cur, C const&, ::boost::type<RefType>, mpl::true_ )
{
return *static_any_cast<BOOST_DEDUCED_TYPENAME C::const_iterator>( cur );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** BOOST_TEST_FOREACH ************** //
// ************************************************************************** //
#define BOOST_TEST_FE_ANY ::boost::unit_test::for_each::static_any_t
#define BOOST_TEST_FE_IS_CONST( COL ) ::boost::unit_test::for_each::is_const_coll( COL )
#define BOOST_TEST_FE_BEG( COL ) \
::boost::unit_test::for_each::begin( \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_END( COL ) \
::boost::unit_test::for_each::end( \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_DONE( COL ) \
::boost::unit_test::for_each::done( \
BOOST_TEST_FE_CUR_VAR, \
BOOST_TEST_FE_END_VAR, \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_TEST_FE_NEXT( COL ) \
::boost::unit_test::for_each::next( \
BOOST_TEST_FE_CUR_VAR, \
COL, \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#define BOOST_FOREACH_NOOP(COL) \
((void)&(COL))
#define BOOST_TEST_FE_DEREF( COL, RefType ) \
::boost::unit_test::for_each::deref( \
BOOST_TEST_FE_CUR_VAR, \
COL, \
::boost::type<RefType >(), \
BOOST_TEST_FE_IS_CONST( COL ) ) \
/**/
#if BOOST_WORKAROUND( BOOST_MSVC, == 1310 )
#define BOOST_TEST_LINE_NUM
#else
#define BOOST_TEST_LINE_NUM __LINE__
#endif
#define BOOST_TEST_FE_CUR_VAR BOOST_JOIN( _fe_cur_, BOOST_TEST_LINE_NUM )
#define BOOST_TEST_FE_END_VAR BOOST_JOIN( _fe_end_, BOOST_TEST_LINE_NUM )
#define BOOST_TEST_FE_CON_VAR BOOST_JOIN( _fe_con_, BOOST_TEST_LINE_NUM )
#define BOOST_TEST_FOREACH( RefType, var, COL ) \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_END( COL ) ) {} else \
for( bool BOOST_TEST_FE_CON_VAR = true; \
BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); \
BOOST_TEST_FE_CON_VAR ? BOOST_TEST_FE_NEXT( COL ) : BOOST_FOREACH_NOOP( COL )) \
\
if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \
for( RefType var = BOOST_TEST_FE_DEREF( COL, RefType ); \
!BOOST_TEST_FE_CON_VAR; BOOST_TEST_FE_CON_VAR = true ) \
/**/
//____________________________________________________________________________//
} // namespace for_each
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_FOREACH_HPP_021005GER

View File

@@ -0,0 +1,104 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description :
// ***************************************************************************
#ifndef BOOST_IFSTREAM_LINE_ITERATOR_HPP_071894GER
#define BOOST_IFSTREAM_LINE_ITERATOR_HPP_071894GER
// Boost
#include <boost/test/utils/iterator/istream_line_iterator.hpp>
// STL
#include <fstream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
// ************************************************************************** //
// ************** ifstream_holder ************** //
// ************************************************************************** //
template<typename CharT>
class ifstream_holder {
public:
// Constructor
explicit ifstream_holder( basic_cstring<CharT const> file_name )
{
if( file_name.is_empty() )
return;
m_stream.open( file_name.begin(), std::ios::in );
}
bool is_valid()
{
return m_stream.is_open();
}
protected:
#ifdef BOOST_CLASSIC_IOSTREAMS
typedef std::ifstream stream_t;
#else
typedef std::basic_ifstream<CharT,std::char_traits<CharT> > stream_t;
#endif
// Data members
stream_t m_stream;
};
} // namespace ut_detail
// ************************************************************************** //
// ************** basic_ifstream_line_iterator ************** //
// ************************************************************************** //
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
template<typename CharT>
class basic_ifstream_line_iterator : ut_detail::ifstream_holder<CharT>, public basic_istream_line_iterator<CharT>
{
public:
basic_ifstream_line_iterator( basic_cstring<CharT const> file_name, CharT delimeter )
: ut_detail::ifstream_holder<CharT>( file_name ), basic_istream_line_iterator<CharT>( this->m_stream, delimeter ) {}
explicit basic_ifstream_line_iterator( basic_cstring<CharT const> file_name = basic_cstring<CharT const>() )
: ut_detail::ifstream_holder<CharT>( file_name ), basic_istream_line_iterator<CharT>( this->m_stream ) {}
};
#ifdef BOOST_MSVC
# pragma warning(default: 4355)
#endif
typedef basic_ifstream_line_iterator<char> ifstream_line_iterator;
typedef basic_ifstream_line_iterator<wchar_t> wifstream_line_iterator;
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_IFSTREAM_LINE_ITERATOR_HPP_071894GER

View File

@@ -0,0 +1,109 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : Input iterator facade
// ***************************************************************************
#ifndef BOOST_INPUT_ITERATOR_FACADE_HPP_071894GER
#define BOOST_INPUT_ITERATOR_FACADE_HPP_071894GER
// Boost
#include <boost/iterator/iterator_facade.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** input_iterator_core_access ************** //
// ************************************************************************** //
class input_iterator_core_access
{
#if defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) || BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x551))
public:
#else
template <class I, class V, class R, class TC> friend class input_iterator_facade;
#endif
template <class Facade>
static bool get( Facade& f )
{
return f.get();
}
private:
// objects of this class are useless
input_iterator_core_access(); //undefined
};
// ************************************************************************** //
// ************** input_iterator_facade ************** //
// ************************************************************************** //
template<typename Derived,
typename ValueType,
typename Reference = ValueType const&,
typename Traversal = single_pass_traversal_tag>
class input_iterator_facade : public iterator_facade<Derived,ValueType,Traversal,Reference>
{
public:
// Constructor
input_iterator_facade() : m_valid( false ), m_value() {}
protected: // provide access to the Derived
void init()
{
m_valid = true;
increment();
}
// Data members
mutable bool m_valid;
ValueType m_value;
private:
friend class boost::iterator_core_access;
// iterator facade interface implementation
void increment()
{
// we make post-end incrementation indefinetly safe
if( m_valid )
m_valid = input_iterator_core_access::get( *static_cast<Derived*>(this) );
}
Reference dereference() const
{
return m_value;
}
// iterator facade interface implementation
bool equal( input_iterator_facade const& rhs ) const
{
// two invalid iterator equals, inequal otherwise
return !m_valid && !rhs.m_valid;
}
};
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_INPUT_ITERATOR_FACADE_HPP_071894GER

View File

@@ -0,0 +1,93 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description :
// ***************************************************************************
#ifndef BOOST_ISTREAM_LINE_ITERATOR_HPP_071894GER
#define BOOST_ISTREAM_LINE_ITERATOR_HPP_071894GER
// Boost
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/iterator/input_iterator_facade.hpp>
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** basic_istream_line_iterator ************** //
// ************************************************************************** //
// !! Should we support policy based delimitation
template<typename CharT>
class basic_istream_line_iterator
: public input_iterator_facade<basic_istream_line_iterator<CharT>,
std::basic_string<CharT>,
basic_cstring<CharT const> > {
typedef input_iterator_facade<basic_istream_line_iterator<CharT>,
std::basic_string<CharT>,
basic_cstring<CharT const> > base;
#ifdef BOOST_CLASSIC_IOSTREAMS
typedef std::istream istream_type;
#else
typedef std::basic_istream<CharT> istream_type;
#endif
public:
// Constructors
basic_istream_line_iterator() {}
basic_istream_line_iterator( istream_type& input, CharT delimeter )
: m_input_stream( &input ), m_delimeter( delimeter )
{
this->init();
}
explicit basic_istream_line_iterator( istream_type& input )
: m_input_stream( &input )
, m_delimeter( input.widen( '\n' ) )
{
this->init();
}
private:
friend class input_iterator_core_access;
// increment implementation
bool get()
{
return !!std::getline( *m_input_stream, this->m_value, m_delimeter );
}
// Data members
istream_type* m_input_stream;
CharT m_delimeter;
};
typedef basic_istream_line_iterator<char> istream_line_iterator;
typedef basic_istream_line_iterator<wchar_t> wistream_line_iterator;
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_ISTREAM_LINE_ITERATOR_HPP_071894GER

View File

@@ -0,0 +1,418 @@
// (C) Copyright Gennadiy Rozental 2004-2008.
// 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: 49312 $
//
// Description : token iterator for string and range tokenization
// ***************************************************************************
#ifndef BOOST_TOKEN_ITERATOR_HPP_071894GER
#define BOOST_TOKEN_ITERATOR_HPP_071894GER
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
#include <boost/iterator/iterator_categories.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <boost/test/utils/iterator/input_iterator_facade.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/named_params.hpp>
#include <boost/test/utils/foreach.hpp>
// STL
#include <iosfwd>
#include <cctype>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std{ using ::ispunct; using ::isspace; }
#endif
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** ti_delimeter_type ************** //
// ************************************************************************** //
enum ti_delimeter_type {
dt_char, // character is delimeter if it among explicit list of some characters
dt_ispunct, // character is delimeter if it satisfies ispunct functor
dt_isspace, // character is delimeter if it satisfies isspace functor
dt_none // no character is delimeter
};
namespace ut_detail {
// ************************************************************************** //
// ************** default_char_compare ************** //
// ************************************************************************** //
template<typename CharT>
class default_char_compare {
public:
bool operator()( CharT c1, CharT c2 )
{
#ifdef BOOST_CLASSIC_IOSTREAMS
return std::string_char_traits<CharT>::eq( c1, c2 );
#else
return std::char_traits<CharT>::eq( c1, c2 );
#endif
}
};
// ************************************************************************** //
// ************** delim_policy ************** //
// ************************************************************************** //
template<typename CharT,typename CharCompare>
class delim_policy {
typedef basic_cstring<CharT const> cstring;
public:
// Constructor
explicit delim_policy( ti_delimeter_type t = dt_char, cstring d = cstring() )
: m_type( t )
{
set_delimeters( d );
}
void set_delimeters( ti_delimeter_type t ) { m_type = t; }
template<typename Src>
void set_delimeters( Src d )
{
nfp::optionally_assign( m_delimeters, d );
if( !m_delimeters.is_empty() )
m_type = dt_char;
}
bool operator()( CharT c )
{
switch( m_type ) {
case dt_char: {
BOOST_TEST_FOREACH( CharT, delim, m_delimeters )
if( CharCompare()( delim, c ) )
return true;
return false;
}
case dt_ispunct:
return (std::ispunct)( c ) != 0;
case dt_isspace:
return (std::isspace)( c ) != 0;
case dt_none:
return false;
}
return false;
}
private:
// Data members
cstring m_delimeters;
ti_delimeter_type m_type;
};
// ************************************************************************** //
// ************** token_assigner ************** //
// ************************************************************************** //
template<typename TraversalTag>
struct token_assigner {
#if BOOST_WORKAROUND( BOOST_DINKUMWARE_STDLIB, < 306 )
template<typename Iterator, typename C, typename T>
static void assign( Iterator b, Iterator e, std::basic_string<C,T>& t )
{ for( ; b != e; ++b ) t += *b; }
template<typename Iterator, typename C>
static void assign( Iterator b, Iterator e, basic_cstring<C>& t ) { t.assign( b, e ); }
#else
template<typename Iterator, typename Token>
static void assign( Iterator b, Iterator e, Token& t ) { t.assign( b, e ); }
#endif
template<typename Iterator, typename Token>
static void append_move( Iterator& b, Token& ) { ++b; }
};
//____________________________________________________________________________//
template<>
struct token_assigner<single_pass_traversal_tag> {
template<typename Iterator, typename Token>
static void assign( Iterator b, Iterator e, Token& t ) {}
template<typename Iterator, typename Token>
static void append_move( Iterator& b, Token& t ) { t += *b; ++b; }
};
} // namespace ut_detail
// ************************************************************************** //
// ************** modifiers ************** //
// ************************************************************************** //
namespace {
nfp::keyword<struct dropped_delimeters_t > dropped_delimeters;
nfp::keyword<struct kept_delimeters_t > kept_delimeters;
nfp::typed_keyword<bool,struct keep_empty_tokens_t > keep_empty_tokens;
nfp::typed_keyword<std::size_t,struct max_tokens_t > max_tokens;
}
// ************************************************************************** //
// ************** token_iterator_base ************** //
// ************************************************************************** //
template<typename Derived,
typename CharT,
typename CharCompare = ut_detail::default_char_compare<CharT>,
typename ValueType = basic_cstring<CharT const>,
typename Reference = basic_cstring<CharT const>,
typename Traversal = forward_traversal_tag>
class token_iterator_base
: public input_iterator_facade<Derived,ValueType,Reference,Traversal> {
typedef basic_cstring<CharT const> cstring;
typedef ut_detail::delim_policy<CharT,CharCompare> delim_policy;
typedef input_iterator_facade<Derived,ValueType,Reference,Traversal> base;
protected:
// Constructor
explicit token_iterator_base()
: m_is_dropped( dt_isspace )
, m_is_kept( dt_ispunct )
, m_keep_empty_tokens( false )
, m_tokens_left( (std::size_t)-1 )
, m_token_produced( false )
{
}
template<typename Modifier>
void
apply_modifier( Modifier const& m )
{
if( m.has( dropped_delimeters ) )
m_is_dropped.set_delimeters( m[dropped_delimeters] );
if( m.has( kept_delimeters ) )
m_is_kept.set_delimeters( m[kept_delimeters] );
if( m.has( keep_empty_tokens ) )
m_keep_empty_tokens = true;
nfp::optionally_assign( m_tokens_left, m, max_tokens );
}
template<typename Iter>
bool get( Iter& begin, Iter end )
{
typedef ut_detail::token_assigner<BOOST_DEDUCED_TYPENAME iterator_traversal<Iter>::type> Assigner;
Iter check_point;
this->m_value.clear();
if( !m_keep_empty_tokens ) {
while( begin != end && m_is_dropped( *begin ) )
++begin;
if( begin == end )
return false;
check_point = begin;
if( m_tokens_left == 1 )
while( begin != end )
Assigner::append_move( begin, this->m_value );
else if( m_is_kept( *begin ) )
Assigner::append_move( begin, this->m_value );
else
while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
Assigner::append_move( begin, this->m_value );
--m_tokens_left;
}
else { // m_keep_empty_tokens is true
check_point = begin;
if( begin == end ) {
if( m_token_produced )
return false;
m_token_produced = true;
}
if( m_is_kept( *begin ) ) {
if( m_token_produced )
Assigner::append_move( begin, this->m_value );
m_token_produced = !m_token_produced;
}
else if( !m_token_produced && m_is_dropped( *begin ) )
m_token_produced = true;
else {
if( m_is_dropped( *begin ) )
check_point = ++begin;
while( begin != end && !m_is_dropped( *begin ) && !m_is_kept( *begin ) )
Assigner::append_move( begin, this->m_value );
m_token_produced = true;
}
}
Assigner::assign( check_point, begin, this->m_value );
return true;
}
private:
// Data members
delim_policy m_is_dropped;
delim_policy m_is_kept;
bool m_keep_empty_tokens;
std::size_t m_tokens_left;
bool m_token_produced;
};
// ************************************************************************** //
// ************** basic_string_token_iterator ************** //
// ************************************************************************** //
template<typename CharT,
typename CharCompare = ut_detail::default_char_compare<CharT> >
class basic_string_token_iterator
: public token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> {
typedef basic_cstring<CharT const> cstring;
typedef token_iterator_base<basic_string_token_iterator<CharT,CharCompare>,CharT,CharCompare> base;
public:
explicit basic_string_token_iterator() {}
explicit basic_string_token_iterator( cstring src )
: m_src( src )
{
this->init();
}
template<typename Src, typename Modifier>
basic_string_token_iterator( Src src, Modifier const& m )
: m_src( src )
{
this->apply_modifier( m );
this->init();
}
private:
friend class input_iterator_core_access;
// input iterator implementation
bool get()
{
typename cstring::iterator begin = m_src.begin();
bool res = base::get( begin, m_src.end() );
m_src.assign( begin, m_src.end() );
return res;
}
// Data members
cstring m_src;
};
typedef basic_string_token_iterator<char> string_token_iterator;
typedef basic_string_token_iterator<wchar_t> wstring_token_iterator;
// ************************************************************************** //
// ************** range_token_iterator ************** //
// ************************************************************************** //
template<typename Iter,
typename CharCompare = ut_detail::default_char_compare<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
typename ValueType = std::basic_string<BOOST_DEDUCED_TYPENAME iterator_value<Iter>::type>,
typename Reference = ValueType const&>
class range_token_iterator
: public token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> {
typedef basic_cstring<typename ValueType::value_type> cstring;
typedef token_iterator_base<range_token_iterator<Iter,CharCompare,ValueType,Reference>,
typename iterator_value<Iter>::type,CharCompare,ValueType,Reference> base;
public:
explicit range_token_iterator() {}
explicit range_token_iterator( Iter begin, Iter end = Iter() )
: m_begin( begin ), m_end( end )
{
this->init();
}
range_token_iterator( range_token_iterator const& rhs )
: base( rhs )
{
if( this->m_valid ) {
m_begin = rhs.m_begin;
m_end = rhs.m_end;
}
}
template<typename Modifier>
range_token_iterator( Iter begin, Iter end, Modifier const& m )
: m_begin( begin ), m_end( end )
{
this->apply_modifier( m );
this->init();
}
private:
friend class input_iterator_core_access;
// input iterator implementation
bool get()
{
return base::get( m_begin, m_end );
}
// Data members
Iter m_begin;
Iter m_end;
};
// ************************************************************************** //
// ************** make_range_token_iterator ************** //
// ************************************************************************** //
template<typename Iter>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end = Iter() )
{
return range_token_iterator<Iter>( begin, end );
}
//____________________________________________________________________________//
template<typename Iter,typename Modifier>
inline range_token_iterator<Iter>
make_range_token_iterator( Iter begin, Iter end, Modifier const& m )
{
return range_token_iterator<Iter>( begin, end, m );
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TOKEN_ITERATOR_HPP_071894GER

View File

@@ -0,0 +1,114 @@
// (C) Copyright Gennadiy Rozental 2008.
// 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: 49312 $
//
// Description : contains definition for all test tools in test toolbox
// ***************************************************************************
#ifndef BOOST_TEST_LAZY_OSTREAM_HPP_070708GER
#define BOOST_TEST_LAZY_OSTREAM_HPP_070708GER
// Boost.Test
#include <boost/test/detail/config.hpp>
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** lazy_ostream ************** //
// ************************************************************************** //
namespace boost {
namespace unit_test {
class lazy_ostream {
public:
static lazy_ostream& instance() { static lazy_ostream inst; return inst; }
friend std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
// access method
bool empty() const { return m_empty; }
// actual printing interface; to be accessed only by this class and children
virtual std::ostream& operator()( std::ostream& ostr ) const { return ostr; }
protected:
explicit lazy_ostream( bool empty = true ) : m_empty( empty ) {}
// protected destructor to make sure right one is called
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x582))
public:
#endif
BOOST_TEST_PROTECTED_VIRTUAL ~lazy_ostream() {}
private:
// Data members
bool m_empty;
};
//____________________________________________________________________________//
template<typename T>
class lazy_ostream_impl : public lazy_ostream {
public:
lazy_ostream_impl( lazy_ostream const& prev, T value )
: lazy_ostream( false )
, m_prev( prev )
, m_value( value )
{}
private:
virtual std::ostream& operator()( std::ostream& ostr ) const
{
return m_prev(ostr) << m_value;
}
// Data members
lazy_ostream const& m_prev;
T m_value;
};
//____________________________________________________________________________//
template<typename T>
inline lazy_ostream_impl<T const&>
operator<<( lazy_ostream const& prev, T const& v )
{
return lazy_ostream_impl<T const&>( prev, v );
}
//____________________________________________________________________________//
#if BOOST_TEST_USE_STD_LOCALE
template<typename R,typename S>
inline lazy_ostream_impl<R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
return lazy_ostream_impl<R& (BOOST_TEST_CALL_DECL *)(S&)>( prev, man );
}
//____________________________________________________________________________//
#endif
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_LAZY_OSTREAM_HPP_070708GER

View File

@@ -0,0 +1,294 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : facilities for named function parameters support
// ***************************************************************************
#ifndef BOOST_TEST_NAMED_PARAM_022505GER
#define BOOST_TEST_NAMED_PARAM_022505GER
// Boost
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
// Boost.Test
#include <boost/test/utils/rtti.hpp>
#include <boost/test/utils/assign_op.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace nfp { // named function parameters
// ************************************************************************** //
// ************** forward declarations ************** //
// ************************************************************************** //
template<typename T, typename unique_id,typename RefType> struct named_parameter;
template<typename unique_id,bool required> struct keyword;
namespace nfp_detail {
template<typename NP1,typename NP2> struct named_parameter_combine;
// ************************************************************************** //
// ************** access_to_invalid_parameter ************** //
// ************************************************************************** //
struct access_to_invalid_parameter {};
//____________________________________________________________________________//
inline void
report_access_to_invalid_parameter()
{
throw access_to_invalid_parameter();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** nil ************** //
// ************************************************************************** //
struct nil {
template<typename T>
operator T() const
{ report_access_to_invalid_parameter(); static T* v = 0; return *v; }
template<typename Arg1>
nil operator()( Arg1 const& )
{ report_access_to_invalid_parameter(); return nil(); }
template<typename Arg1,typename Arg2>
nil operator()( Arg1 const&, Arg2 const& )
{ report_access_to_invalid_parameter(); return nil(); }
template<typename Arg1,typename Arg2,typename Arg3>
nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
{ report_access_to_invalid_parameter(); return nil(); }
// Visitation support
template<typename Visitor>
void apply_to( Visitor& V ) const {}
};
// ************************************************************************** //
// ************** named_parameter_base ************** //
// ************************************************************************** //
template<typename Derived>
struct named_parameter_base {
template<typename NP>
named_parameter_combine<NP,Derived>
operator,( NP const& np ) const { return named_parameter_combine<NP,Derived>( np, *static_cast<Derived const*>(this) ); }
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** named_parameter_combine ************** //
// ************************************************************************** //
template<typename NP, typename Rest = nil>
struct named_parameter_combine : Rest, named_parameter_base<named_parameter_combine<NP,Rest> > {
typedef typename NP::ref_type res_type;
typedef named_parameter_combine<NP,Rest> self_type;
// Constructor
named_parameter_combine( NP const& np, Rest const& r )
: Rest( r ), m_param( np ) {}
// Access methods
res_type operator[]( keyword<typename NP::id,true> kw ) const { return m_param[kw]; }
res_type operator[]( keyword<typename NP::id,false> kw ) const { return m_param[kw]; }
using Rest::operator[];
bool has( keyword<typename NP::id,false> ) const { return true; }
using Rest::has;
#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3206))
template<typename NP>
named_parameter_combine<NP,self_type> operator,( NP const& np ) const
{ return named_parameter_combine<NP,self_type>( np, *this ); }
#else
using named_parameter_base<named_parameter_combine<NP,Rest> >::operator,;
#endif
// Visitation support
template<typename Visitor>
void apply_to( Visitor& V ) const
{
m_param.apply_to( V );
Rest::apply_to( V );
}
private:
// Data members
NP m_param;
};
} // namespace nfp_detail
// ************************************************************************** //
// ************** named_parameter_combine ************** //
// ************************************************************************** //
template<typename T, typename unique_id,typename ReferenceType=T&>
struct named_parameter
: nfp_detail::named_parameter_base<named_parameter<T, unique_id,ReferenceType> >
{
typedef T data_type;
typedef ReferenceType ref_type;
typedef unique_id id;
// Constructor
explicit named_parameter( ref_type v ) : m_value( v ) {}
// Access methods
ref_type operator[]( keyword<unique_id,true> ) const { return m_value; }
ref_type operator[]( keyword<unique_id,false> ) const { return m_value; }
template<typename UnknownId>
nfp_detail::nil operator[]( keyword<UnknownId,false> ) const { return nfp_detail::nil(); }
bool has( keyword<unique_id,false> ) const { return true; }
template<typename UnknownId>
bool has( keyword<UnknownId,false> ) const { return false; }
// Visitation support
template<typename Visitor>
void apply_to( Visitor& V ) const
{
V.set_parameter( rtti::type_id<unique_id>(), m_value );
}
private:
// Data members
ref_type m_value;
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** no_params ************** //
// ************************************************************************** //
namespace nfp_detail {
typedef named_parameter<char, struct no_params_type_t,char> no_params_type;
}
namespace {
nfp_detail::no_params_type no_params( '\0' );
} // local namespace
//____________________________________________________________________________//
// ************************************************************************** //
// ************** keyword ************** //
// ************************************************************************** //
template<typename unique_id, bool required = false>
struct keyword {
typedef unique_id id;
template<typename T>
named_parameter<T const,unique_id>
operator=( T const& t ) const { return named_parameter<T const,unique_id>( t ); }
template<typename T>
named_parameter<T,unique_id>
operator=( T& t ) const { return named_parameter<T,unique_id>( t ); }
named_parameter<char const*,unique_id,char const*>
operator=( char const* t ) const { return named_parameter<char const*,unique_id,char const*>( t ); }
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** typed_keyword ************** //
// ************************************************************************** //
template<typename T, typename unique_id, bool required = false>
struct typed_keyword : keyword<unique_id,required> {
named_parameter<T const,unique_id>
operator=( T const& t ) const { return named_parameter<T const,unique_id>( t ); }
named_parameter<T,unique_id>
operator=( T& t ) const { return named_parameter<T,unique_id>( t ); }
};
//____________________________________________________________________________//
template<typename unique_id>
struct typed_keyword<bool,unique_id,false>
: keyword<unique_id,false>
, named_parameter<bool,unique_id,bool> {
typedef unique_id id;
typed_keyword() : named_parameter<bool,unique_id,bool>( true ) {}
named_parameter<bool,unique_id,bool>
operator!() const { return named_parameter<bool,unique_id,bool>( false ); }
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** optionally_assign ************** //
// ************************************************************************** //
template<typename T>
inline void
optionally_assign( T&, nfp_detail::nil )
{
nfp_detail::report_access_to_invalid_parameter();
}
//____________________________________________________________________________//
template<typename T, typename Source>
inline void
#if BOOST_WORKAROUND( __MWERKS__, BOOST_TESTED_AT( 0x3003 ) ) \
|| BOOST_WORKAROUND( __DECCXX_VER, BOOST_TESTED_AT(60590042) )
optionally_assign( T& target, Source src )
#else
optionally_assign( T& target, Source const& src )
#endif
{
using namespace unit_test;
assign_op( target, src, 0 );
}
//____________________________________________________________________________//
template<typename T, typename Params, typename Keyword>
inline void
optionally_assign( T& target, Params const& p, Keyword k )
{
if( p.has(k) )
optionally_assign( target, p[k] );
}
//____________________________________________________________________________//
} // namespace nfp
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_NAMED_PARAM_022505GER

View File

@@ -0,0 +1,100 @@
// (C) Copyright Gennadiy Rozental 2002-2008.
// (C) Copyright Daryle Walker 2000-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: 49312 $
//
// Description : simulate /dev/null stream
// ***************************************************************************
#ifndef BOOST_NULLSTREAM_HPP_071894GER
#define BOOST_NULLSTREAM_HPP_071894GER
#include <ostream> // for std::basic_ostream
#include <streambuf> // for std::basic_streambuf
#include <string> // for std::char_traits
#include <boost/utility/base_from_member.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
// ************************************************************************** //
// ************** basic_nullbuf ************** //
// ************************************************************************** //
// Class for a buffer that reads nothing and writes to nothing.
// Idea from an Usenet post by Tom <the_wid@my-deja.com> at
// 27 Oct 2000 14:06:21 GMT on comp.lang.c++.
template<typename CharType, class CharTraits = ::std::char_traits<CharType> >
class basic_nullbuf : public ::std::basic_streambuf<CharType, CharTraits> {
typedef ::std::basic_streambuf<CharType, CharTraits> base_type;
public:
// Types
typedef typename base_type::char_type char_type;
typedef typename base_type::traits_type traits_type;
typedef typename base_type::int_type int_type;
typedef typename base_type::pos_type pos_type;
typedef typename base_type::off_type off_type;
// Use automatic default constructor and destructor
protected:
// The default implementations of the miscellaneous virtual
// member functions are sufficient.
// The default implementations of the input & putback virtual
// member functions, being nowhere but EOF, are sufficient.
// The output virtual member functions need to be changed to
// accept anything without any problems, instead of being at EOF.
virtual ::std::streamsize xsputn( char_type const* /*s*/, ::std::streamsize n ) { return n; } // "s" is unused
virtual int_type overflow( int_type c = traits_type::eof() ) { return traits_type::not_eof( c ); }
};
typedef basic_nullbuf<char> nullbuf;
typedef basic_nullbuf<wchar_t> wnullbuf;
// ************************************************************************** //
// ************** basic_onullstream ************** //
// ************************************************************************** //
// Output streams based on basic_nullbuf.
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4355) // 'this' : used in base member initializer list
#endif
template< typename CharType, class CharTraits = ::std::char_traits<CharType> >
class basic_onullstream : private boost::base_from_member<basic_nullbuf<CharType, CharTraits> >
, public ::std::basic_ostream<CharType, CharTraits> {
typedef boost::base_from_member<basic_nullbuf<CharType, CharTraits> > pbase_type;
typedef ::std::basic_ostream<CharType, CharTraits> base_type;
public:
// Constructor
basic_onullstream() : pbase_type(), base_type( &this->pbase_type::member ) {}
};
#ifdef BOOST_MSVC
# pragma warning(default: 4355)
#endif
typedef basic_onullstream<char> onullstream;
typedef basic_onullstream<wchar_t> wonullstream;
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_NULLSTREAM_HPP_071894GER

View File

@@ -0,0 +1,64 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : simple facilities for accessing type information at runtime
// ***************************************************************************
#ifndef BOOST_TEST_RTTI_HPP_062604GER
#define BOOST_TEST_RTTI_HPP_062604GER
#include <cstddef>
namespace boost {
namespace rtti {
// ************************************************************************** //
// ************** rtti::type_id ************** //
// ************************************************************************** //
typedef std::ptrdiff_t id_t;
namespace rtti_detail {
template<typename T>
struct rttid_holder {
static id_t id() { return reinterpret_cast<id_t>( &inst() ); }
private:
struct rttid {};
static rttid const& inst() { static rttid s_inst; return s_inst; }
};
} // namespace rtti_detail
//____________________________________________________________________________//
template<typename T>
inline id_t
type_id()
{
return rtti_detail::rttid_holder<T>::id();
}
//____________________________________________________________________________//
#define BOOST_RTTI_SWITCH( type_id_ ) if( ::boost::rtti::id_t switch_by_id = type_id_ )
#define BOOST_RTTI_CASE( type ) if( switch_by_id == ::boost::rtti::type_id<type>() )
//____________________________________________________________________________//
} // namespace rtti
} // namespace boost
#endif // BOOST_RT_RTTI_HPP_062604GER

View File

@@ -0,0 +1,103 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// 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: 49312 $
//
// Description : model of actual argument (both typed and abstract interface)
// ***************************************************************************
#ifndef BOOST_RT_ARGUMENT_HPP_062604GER
#define BOOST_RT_ARGUMENT_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/validation.hpp>
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/rtti.hpp>
// STL
#include <cassert>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
// ************************************************************************** //
// ************** runtime::argument ************** //
// ************************************************************************** //
class argument {
public:
// Constructor
argument( parameter const& p, rtti::id_t value_type )
: p_formal_parameter( p )
, p_value_type( value_type )
{}
// Destructor
virtual ~argument() {}
// Public properties
unit_test::readonly_property<parameter const&> p_formal_parameter;
unit_test::readonly_property<rtti::id_t> p_value_type;
};
// ************************************************************************** //
// ************** runtime::typed_argument ************** //
// ************************************************************************** //
template<typename T>
class typed_argument : public argument {
public:
// Constructor
explicit typed_argument( parameter const& p )
: argument( p, rtti::type_id<T>() )
{}
typed_argument( parameter const& p, T const& t )
: argument( p, rtti::type_id<T>() )
, p_value( t )
{}
unit_test::readwrite_property<T> p_value;
};
// ************************************************************************** //
// ************** runtime::arg_value ************** //
// ************************************************************************** //
template<typename T>
inline T const&
arg_value( argument const& arg )
{
assert( arg.p_value_type == rtti::type_id<T>() ); // detect logic error
return static_cast<typed_argument<T> const&>( arg ).p_value.value;
}
//____________________________________________________________________________//
template<typename T>
inline T&
arg_value( argument& arg )
{
assert( arg.p_value_type == rtti::type_id<T>() ); // detect logic error
return static_cast<typed_argument<T>&>( arg ).p_value.value;
}
//____________________________________________________________________________//
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_ARGUMENT_HPP_062604GER

View File

@@ -0,0 +1,218 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : generic typed_argument_factory implementation
// ***************************************************************************
#ifndef BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
#define BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/validation.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/trace.hpp>
#include <boost/test/utils/runtime/interpret_argument_value.hpp>
#include <boost/test/utils/runtime/cla/fwd.hpp>
#include <boost/test/utils/runtime/cla/value_generator.hpp>
#include <boost/test/utils/runtime/cla/value_handler.hpp>
#include <boost/test/utils/runtime/cla/validation.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
#include <boost/test/utils/runtime/cla/detail/argument_value_usage.hpp>
#include <boost/test/utils/runtime/cla/iface/argument_factory.hpp>
// Boost.Test
#include <boost/test/utils/callback.hpp>
// Boost
#include <boost/optional.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** default_value_interpreter ************** //
// ************************************************************************** //
namespace rt_cla_detail {
struct default_value_interpreter {
template<typename T>
void operator()( argv_traverser& tr, boost::optional<T>& value )
{
if( interpret_argument_value( tr.token(), value, 0 ) )
tr.next_token();
}
};
} // namespace rt_cla_detail
// ************************************************************************** //
// ************** typed_argument_factory ************** //
// ************************************************************************** //
template<typename T>
struct typed_argument_factory : public argument_factory {
// Constructor
typed_argument_factory()
: m_value_interpreter( rt_cla_detail::default_value_interpreter() )
{}
BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~typed_argument_factory() {}
// properties modification
template<typename Modifier>
void accept_modifier( Modifier const& m )
{
optionally_assign( m_value_handler, m, handler );
optionally_assign( m_value_interpreter, m, interpreter );
if( m.has( default_value ) ) {
BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator,
BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );
T const& dv_ref = m[default_value];
m_value_generator = rt_cla_detail::const_generator<T>( dv_ref );
}
if( m.has( default_refer_to ) ) {
BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_generator,
BOOST_RT_PARAM_LITERAL( "multiple value generators for parameter" ) );
cstring ref_id = m[default_refer_to];
m_value_generator = rt_cla_detail::ref_generator<T>( ref_id );
}
if( m.has( assign_to ) ) {
BOOST_RT_PARAM_VALIDATE_LOGIC( !m_value_handler,
BOOST_RT_PARAM_LITERAL( "multiple value handlers for parameter" ) );
m_value_handler = rt_cla_detail::assigner<T>( m[assign_to] );
}
}
// Argument factory implementation
virtual argument_ptr produce_using( parameter& p, argv_traverser& tr );
virtual argument_ptr produce_using( parameter& p, parser const& );
virtual void argument_usage_info( format_stream& fs );
// !! private?
// Data members
unit_test::callback2<parameter const&,T&> m_value_handler;
unit_test::callback2<parser const&,boost::optional<T>&> m_value_generator;
unit_test::callback2<argv_traverser&,boost::optional<T>&> m_value_interpreter;
};
//____________________________________________________________________________//
template<typename T>
inline argument_ptr
typed_argument_factory<T>::produce_using( parameter& p, argv_traverser& tr )
{
boost::optional<T> value;
try {
m_value_interpreter( tr, value );
}
catch( ... ) { // !! should we do that?
BOOST_RT_PARAM_TRACE( "Fail to parse argument value" );
if( !p.p_optional_value )
throw;
}
argument_ptr arg = p.actual_argument();
BOOST_RT_CLA_VALIDATE_INPUT( !!value || p.p_optional_value, tr,
BOOST_RT_PARAM_LITERAL( "Argument value missing for parameter " ) << p.id_2_report() );
BOOST_RT_CLA_VALIDATE_INPUT( !arg || p.p_multiplicable, tr,
BOOST_RT_PARAM_LITERAL( "Unexpected repetition of the parameter " ) << p.id_2_report() );
if( !!value && !!m_value_handler )
m_value_handler( p, *value );
if( !p.p_multiplicable )
arg.reset( p.p_optional_value
? (argument*)new typed_argument<boost::optional<T> >( p, value )
: (argument*)new typed_argument<T>( p, *value ) );
else {
typedef std::list<boost::optional<T> > optional_list;
if( !arg )
arg.reset( p.p_optional_value
? (argument*)new typed_argument<optional_list>( p )
: (argument*)new typed_argument<std::list<T> >( p ) );
if( p.p_optional_value ) {
optional_list& values = arg_value<optional_list>( *arg );
values.push_back( value );
}
else {
std::list<T>& values = arg_value<std::list<T> >( *arg );
values.push_back( *value );
}
}
return arg;
}
//____________________________________________________________________________//
template<typename T>
inline argument_ptr
typed_argument_factory<T>::produce_using( parameter& p, parser const& pa )
{
argument_ptr arg;
if( !m_value_generator )
return arg;
boost::optional<T> value;
m_value_generator( pa, value );
if( !value )
return arg;
if( !!m_value_handler )
m_value_handler( p, *value );
arg.reset( new typed_argument<T>( p, *value ) );
return arg;
}
//____________________________________________________________________________//
template<typename T>
inline void
typed_argument_factory<T>::argument_usage_info( format_stream& fs )
{
rt_cla_detail::argument_value_usage( fs, 0, (T*)0 );
}
//____________________________________________________________________________//
} // namespace boost
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace cla
#endif // BOOST_RT_CLA_ARGUMENT_FACTORY_HPP_062604GER

View File

@@ -0,0 +1,16 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : offline implementation for argc/argv traverser
// ***************************************************************************
#define BOOST_RT_PARAM_INLINE
#include <boost/test/utils/runtime/cla/argv_traverser.ipp>

View File

@@ -0,0 +1,98 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : defines facility to hide input traversing details
// ***************************************************************************
#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER
#define BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
// Boost
#include <boost/noncopyable.hpp>
#include <boost/shared_array.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::argv_traverser ************** //
// ************************************************************************** //
class argv_traverser : noncopyable {
class parser;
public:
// Constructor
argv_traverser();
// public_properties
unit_test::readwrite_property<bool> p_ignore_mismatch;
unit_test::readwrite_property<char_type> p_separator;
// argc+argv <-> internal buffer exchange
void init( int argc, char_type** argv );
void remainder( int& argc, char_type** argv );
// token based parsing
cstring token() const;
void next_token();
// whole input parsing
cstring input() const;
void trim( std::size_t size );
bool match_front( cstring );
bool match_front( char_type c );
bool eoi() const;
// transaction logic support
void commit();
void rollback();
// current position access; used to save some reference points in input
std::size_t input_pos() const;
// returns true if mismatch detected during input parsing handled successfully
bool handle_mismatch();
private:
// Data members
dstring m_buffer;
cstring m_work_buffer;
cstring m_token;
cstring::iterator m_commited_end;
shared_array<char_type> m_remainder;
std::size_t m_remainder_size;
};
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#ifndef BOOST_RT_PARAM_OFFLINE
# define BOOST_RT_PARAM_INLINE inline
# include <boost/test/utils/runtime/cla/argv_traverser.ipp>
#endif
#endif // BOOST_RT_CLA_ARGV_TRAVERSER_HPP_062604GER

View File

@@ -0,0 +1,209 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : implements facility to hide input traversing details
// ***************************************************************************
#ifndef BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
#define BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/trace.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
// STL
#include <memory>
#include <cstring>
#ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::memcpy; }
#endif
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::argv_traverser ************** //
// ************************************************************************** //
BOOST_RT_PARAM_INLINE
argv_traverser::argv_traverser()
: p_ignore_mismatch( false ), p_separator( BOOST_RT_PARAM_LITERAL( ' ' ) )
{
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
argv_traverser::init( int argc, char_type** argv )
{
for( int index = 1; index < argc; ++index ) {
m_buffer += argv[index];
if( index != argc-1 )
m_buffer += BOOST_RT_PARAM_LITERAL( ' ' );
}
m_remainder.reset( new char_type[m_buffer.size()+1] );
m_remainder_size = 0;
m_work_buffer = m_buffer;
m_commited_end = m_work_buffer.begin();
BOOST_RT_PARAM_TRACE( "Input buffer: " << m_buffer );
next_token();
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
argv_traverser::remainder( int& argc, char_type** argv )
{
argc = 1;
std::size_t pos = 0;
while(pos < m_remainder_size ) {
argv[argc++] = m_remainder.get() + pos;
pos = std::find( m_remainder.get() + pos, m_remainder.get() + m_remainder_size,
BOOST_RT_PARAM_LITERAL( ' ' ) ) - m_remainder.get();
m_remainder[pos++] = BOOST_RT_PARAM_LITERAL( '\0' );
}
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE cstring
argv_traverser::token() const
{
return m_token;
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
argv_traverser::next_token()
{
if( m_work_buffer.is_empty() )
return;
m_work_buffer.trim_left( m_token.size() ); // skip remainder of current token
if( m_work_buffer.size() != m_buffer.size() ) // !! is there a better way to identify first token
m_work_buffer.trim_left( 1 ); // skip separator if not first token;
m_token.assign( m_work_buffer.begin(),
std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE cstring
argv_traverser::input() const
{
return m_work_buffer;
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
argv_traverser::trim( std::size_t size )
{
m_work_buffer.trim_left( size );
if( size <= m_token.size() )
m_token.trim_left( size );
else {
m_token.assign( m_work_buffer.begin(),
std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
}
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE bool
argv_traverser::match_front( cstring str )
{
return m_work_buffer.size() < str.size() ? false : m_work_buffer.substr( 0, str.size() ) == str;
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE bool
argv_traverser::match_front( char_type c )
{
return first_char( m_work_buffer ) == c;
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE bool
argv_traverser::eoi() const
{
return m_work_buffer.is_empty();
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
argv_traverser::commit()
{
m_commited_end = m_work_buffer.begin();
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
argv_traverser::rollback()
{
m_work_buffer.assign( m_commited_end, m_work_buffer.end() );
m_token.assign( m_work_buffer.begin(),
std::find( m_work_buffer.begin(), m_work_buffer.end(), p_separator ) );
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE std::size_t
argv_traverser::input_pos() const
{
return m_work_buffer.begin() - m_commited_end;
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE bool
argv_traverser::handle_mismatch()
{
if( !p_ignore_mismatch )
return false;
std::memcpy( m_remainder.get() + m_remainder_size, token().begin(), token().size() );
m_remainder_size += token().size();
m_remainder[m_remainder_size++] = p_separator;
next_token();
commit();
return true;
}
//____________________________________________________________________________//
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_CLA_ARGV_TRAVERSER_IPP_070604GER

View File

@@ -0,0 +1,84 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : generic custom parameter generator
// ***************************************************************************
#ifndef BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER
#define BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/cla/typed_parameter.hpp>
// Boost.Test
#include <boost/test/utils/rtti.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::basic_parameter ************** //
// ************************************************************************** //
template<typename T, typename IdPolicy>
class basic_parameter : public typed_parameter<T> {
public:
// Constructors
explicit basic_parameter( cstring n )
: typed_parameter<T>( m_id_policy )
{
this->accept_modifier( name = n );
}
// parameter properties modification
template<typename Modifier>
void accept_modifier( Modifier const& m )
{
typed_parameter<T>::accept_modifier( m );
m_id_policy.accept_modifier( m );
}
private:
IdPolicy m_id_policy;
};
//____________________________________________________________________________//
#define BOOST_RT_CLA_NAMED_PARAM_GENERATORS( param_type ) \
template<typename T> \
inline shared_ptr<param_type ## _t<T> > \
param_type( cstring name = cstring() ) \
{ \
return shared_ptr<param_type ## _t<T> >( new param_type ## _t<T>( name ) ); \
} \
\
inline shared_ptr<param_type ## _t<cstring> > \
param_type( cstring name = cstring() ) \
{ \
return shared_ptr<param_type ## _t<cstring> >( new param_type ## _t<cstring>( name ) ); \
} \
/**/
//____________________________________________________________________________//
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_CLA_BASIC_PARAMETER_HPP_062604GER

View File

@@ -0,0 +1,16 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : offline implementation of char parameter
// ***************************************************************************
#define BOOST_RT_PARAM_INLINE
#include <boost/test/utils/runtime/cla/char_parameter.ipp>

View File

@@ -0,0 +1,98 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : defines model of parameter with single char name
// ***************************************************************************
#ifndef BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER
#define BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/validation.hpp>
#include <boost/test/utils/runtime/cla/basic_parameter.hpp>
#include <boost/test/utils/runtime/cla/id_policy.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** char_name_policy ************** //
// ************************************************************************** //
class char_name_policy : public basic_naming_policy {
public:
// Constructor
char_name_policy();
BOOST_RT_PARAM_UNNEEDED_VIRTUAL ~char_name_policy() {}
// policy interface
virtual bool conflict_with( identification_policy const& ) const;
// Accept modifier
template<typename Modifier>
void accept_modifier( Modifier const& m )
{
basic_naming_policy::accept_modifier( m );
BOOST_RT_PARAM_VALIDATE_LOGIC( m_name.size() <= 1, "Invalid parameter name " << m_name );
}
};
// ************************************************************************** //
// ************** runtime::cla::char_parameter ************** //
// ************************************************************************** //
template<typename T>
class char_parameter_t : public basic_parameter<T,char_name_policy> {
typedef basic_parameter<T,char_name_policy> base;
public:
// Constructors
explicit char_parameter_t( char_type name ) : base( cstring( &name, 1 ) ) {}
};
//____________________________________________________________________________//
template<typename T>
inline shared_ptr<char_parameter_t<T> >
char_parameter( char_type name )
{
return shared_ptr<char_parameter_t<T> >( new char_parameter_t<T>( name ) );
}
//____________________________________________________________________________//
inline shared_ptr<char_parameter_t<cstring> >
char_parameter( char_type name )
{
return shared_ptr<char_parameter_t<cstring> >( new char_parameter_t<cstring>( name ) );
}
//____________________________________________________________________________//
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#ifndef BOOST_RT_PARAM_OFFLINE
# define BOOST_RT_PARAM_INLINE inline
# include <boost/test/utils/runtime/cla/char_parameter.ipp>
#endif
#endif // BOOST_RT_CLA_CHAR_PARAMETER_HPP_062604GER

View File

@@ -0,0 +1,57 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : implements model of parameter with single char name
// ***************************************************************************
#ifndef BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER
#define BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/cla/char_parameter.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** char_name_policy ************** //
// ************************************************************************** //
BOOST_RT_PARAM_INLINE
char_name_policy::char_name_policy()
: basic_naming_policy( rtti::type_id<char_name_policy>() )
{
assign_op( m_prefix, BOOST_RT_PARAM_CSTRING_LITERAL( "-" ), 0 );
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE bool
char_name_policy::conflict_with( identification_policy const& id ) const
{
return id.p_type_id == p_type_id &&
m_name == static_cast<char_name_policy const&>( id ).m_name;
}
//____________________________________________________________________________//
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_CLA_CHAR_PARAMETER_IPP_062904GER

View File

@@ -0,0 +1,82 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
// This software is provided "as is" without express or implied warranty,
// and with no claim as to its suitability for any purpose.
// See http://www.boost.org for updates, documentation, and revision history.
//
// File : $RCSfile$
//
// Version : $Revision: 49312 $
//
// Description : argument usage printing helpers
// ***************************************************************************
#ifndef BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER
#define BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
// Boost.Test
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/lexical_cast.hpp>
// STL
// !! could we eliminate these includes?
#include <list>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
namespace rt_cla_detail {
// ************************************************************************** //
// ************** argument_value_usage ************** //
// ************************************************************************** //
// generic case
template<typename T>
inline void
argument_value_usage( format_stream& fs, long, T* = 0 )
{
fs << BOOST_RT_PARAM_CSTRING_LITERAL( "<value>" );
}
//____________________________________________________________________________//
// specialization for list of values
template<typename T>
inline void
argument_value_usage( format_stream& fs, int, std::list<T>* = 0 )
{
fs << BOOST_RT_PARAM_CSTRING_LITERAL( "(<value1>, ..., <valueN>)" );
}
//____________________________________________________________________________//
// specialization for type bool
inline void
argument_value_usage( format_stream& fs, int, bool* = 0 )
{
fs << BOOST_RT_PARAM_CSTRING_LITERAL( "[yes|y|no|n]" );
}
//____________________________________________________________________________//
} // namespace rt_cla_detail
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_CLA_ARGUMENT_VALUE_USAGE_HPP_062604GER

View File

@@ -0,0 +1,16 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : offline implementation of generic parameter with dual naming
// ***************************************************************************
#define BOOST_RT_PARAM_INLINE
#include <boost/test/utils/runtime/cla/dual_name_parameter.ipp>

View File

@@ -0,0 +1,88 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : defines model of generic parameter with dual naming
// ***************************************************************************
#ifndef BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER
#define BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/cla/named_parameter.hpp>
#include <boost/test/utils/runtime/cla/char_parameter.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** dual_name_policy ************** //
// ************************************************************************** //
class dual_name_policy : public dual_id_policy<dual_name_policy,string_name_policy,char_name_policy> {
public:
dual_name_policy();
// Accept modifer
template<typename Modifier>
void accept_modifier( Modifier const& m )
{
if( m.has( prefix ) )
set_prefix( m[prefix] );
if( m.has( name ) )
set_name( m[name] );
if( m.has( separator ) )
set_separator( m[separator] );
}
private:
void set_prefix( cstring );
void set_name( cstring );
void set_separator( cstring );
};
// ************************************************************************** //
// ************** runtime::cla::dual_name_parameter ************** //
// ************************************************************************** //
template<typename T>
class dual_name_parameter_t : public basic_parameter<T,dual_name_policy> {
typedef basic_parameter<T,dual_name_policy> base;
public:
// Constructors
explicit dual_name_parameter_t( cstring name ) : base( name ) {}
};
//____________________________________________________________________________//
BOOST_RT_CLA_NAMED_PARAM_GENERATORS( dual_name_parameter )
//____________________________________________________________________________//
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#ifndef BOOST_RT_PARAM_OFFLINE
# define BOOST_RT_PARAM_INLINE inline
# include <boost/test/utils/runtime/cla/dual_name_parameter.ipp>
#endif
#endif // BOOST_RT_CLA_DUAL_NAME_PARAMETER_HPP_062604GER

View File

@@ -0,0 +1,90 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : implements model of generic parameter with dual naming
// ***************************************************************************
#ifndef BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER
#define BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
#include <boost/test/utils/runtime/validation.hpp>
#include <boost/test/utils/runtime/cla/dual_name_parameter.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
// ************************************************************************** //
// ************** dual_name_policy ************** //
// ************************************************************************** //
BOOST_RT_PARAM_INLINE
dual_name_policy::dual_name_policy()
{
m_primary.accept_modifier( prefix = BOOST_RT_PARAM_CSTRING_LITERAL( "--" ) );
m_secondary.accept_modifier( prefix = BOOST_RT_PARAM_CSTRING_LITERAL( "-" ) );
}
//____________________________________________________________________________//
namespace {
template<typename K>
inline void
split( string_name_policy& snp, char_name_policy& cnp, cstring src, K const& k )
{
cstring::iterator sep = std::find( src.begin(), src.end(), BOOST_RT_PARAM_LITERAL( '|' ) );
if( sep != src.begin() )
snp.accept_modifier( k = cstring( src.begin(), sep ) );
if( sep != src.end() )
cnp.accept_modifier( k = cstring( sep+1, src.end() ) );
}
} // local namespace
BOOST_RT_PARAM_INLINE void
dual_name_policy::set_prefix( cstring src )
{
split( m_primary, m_secondary, src, prefix );
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
dual_name_policy::set_name( cstring src )
{
split( m_primary, m_secondary, src, name );
}
//____________________________________________________________________________//
BOOST_RT_PARAM_INLINE void
dual_name_policy::set_separator( cstring src )
{
split( m_primary, m_secondary, src, separator );
}
//____________________________________________________________________________//
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_CLA_DUAL_NAME_PARAMETER_IPP_062904GER

View File

@@ -0,0 +1,55 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : cla subsystem forward declarations
// ***************************************************************************
#ifndef BOOST_RT_CLA_FWD_HPP_062604GER
#define BOOST_RT_CLA_FWD_HPP_062604GER
// Boost.Runtime.Parameter
#include <boost/test/utils/runtime/config.hpp>
// Boost
#include <boost/shared_ptr.hpp>
namespace boost {
namespace BOOST_RT_PARAM_NAMESPACE {
namespace cla {
class parser;
class parameter;
typedef shared_ptr<parameter> parameter_ptr;
class naming_policy;
typedef shared_ptr<naming_policy> naming_policy_ptr;
class argv_traverser;
namespace rt_cla_detail {
template<typename T> class const_generator;
template<typename T> class ref_generator;
template<typename T> class assigner;
class named_parameter_base;
class positional_parameter_base;
} // namespace rt_cla_detail
} // namespace cla
} // namespace BOOST_RT_PARAM_NAMESPACE
} // namespace boost
#endif // BOOST_RT_CLA_FWD_HPP_062604GER

View File

@@ -0,0 +1,16 @@
// (C) Copyright Gennadiy Rozental 2005-2008.
// Use, modification, and distribution are subject to 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: 49312 $
//
// Description : some generic identification policies offline implementation
// ***************************************************************************
#define BOOST_RT_PARAM_INLINE
#include <boost/test/utils/runtime/cla/id_policy.ipp>

Some files were not shown because too many files have changed in this diff Show More