New upstream version 8.1.0

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

View File

@@ -0,0 +1,138 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! @brief defines portable debug interfaces
//!
//! Intended to standardize interface of programs with debuggers
// ***************************************************************************
#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/basic_cstring/basic_cstring.hpp>
// Boost
#include <boost/function/function1.hpp>
// STL
#include <string>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
/// Contains debugger and debug C Runtime interfaces
namespace debug {
/// @defgroup DebuggerInterface Debugger and debug C Runtime portable interfaces
/// @{
/// These interfaces are intended to be used by application to:
/// - check if we are running under debugger
/// - attach the debugger to itself
///
/// Unfortunately these actions differ widely between different debuggers available in a field. These interface present generalized standard form of
/// performing these actions. Implementation depends a lot on the environment application is running in and thus there are several custom implementations
/// supported by the Boost.Test
///
/// In addition here you find interfaces for memory leaks detection and reporting.
///
/// All these interfaces are defined in namespace boost::debug
// ************************************************************************** //
/// Checks if programs runs under debugger
/// @returns true if current process is under debugger. False otherwise
// ************************************************************************** //
bool BOOST_TEST_DECL under_debugger();
// ************************************************************************** //
/// Cause program to break execution in debugger at call point
// ************************************************************************** //
void BOOST_TEST_DECL debugger_break();
// ************************************************************************** //
/// Collection of data, which is used by debugger starter routine
// ************************************************************************** //
struct dbg_startup_info {
long pid; ///< pid of a program to attach to
bool break_or_continue; ///< what to do after debugger is attached
unit_test::const_string binary_path; ///< path to executable for current process
unit_test::const_string display; ///< if debugger has a GUI, which display to use (on UNIX)
unit_test::const_string init_done_lock; ///< path to a uniquely named lock file, which is used to pause current application while debugger is being initialized
};
/// Signature of debugger starter routine. Takes an instance of dbg_startup_into as only argument
typedef boost::function<void (dbg_startup_info const&)> dbg_starter;
// ************************************************************************** //
/// Specifies which debugger to use when attaching and optionally what routine to use to start that debugger
/// There are many different debuggers available for different platforms. Some of them also can be used in a different setups/configuratins.
/// For example, gdb can be used in plain text mode, inside ddd, inside (x)emacs or in a separate xterm window.
/// Boost.Test identifies each configuration with unique string.
/// Also different debuggers configurations require different routines which is specifically tailored to start that debugger configuration.
/// Boost.Test comes with set of predefined configuration names and corresponding routines for these configurations:
/// - TODO
///
/// You can use this routine to select which one of the predefined debugger configurations to use in which case you do not need to provide starter
/// routine (the one provided by Boost.Test will be used). You can also use this routine to select your own debugger by providing unique configuration
/// id and starter routine for this configuration.
///
/// @param[in] dbg_id Unique id for debugger configuration (for example, gdb)
/// @param[in] s Optional starter routine for selected configuration (use only you want to define your own configuration)
/// @returns Id of previously selected debugger configuration
std::string BOOST_TEST_DECL set_debugger( unit_test::const_string dbg_id, dbg_starter s = dbg_starter() );
// ************************************************************************** //
/// Attaches debugger to the current process
/// Using currently selected debugger, this routine attempts to attach the debugger to this process.
/// @param[in] break_or_continue tells what we wan to do after the debugger is attached. If true - process execution breaks
/// in the point in invocation of this function. Otherwise execution continues, but now it is
/// under the debugger
/// @returns true if debugger successfully attached. False otherwise
// ************************************************************************** //
bool BOOST_TEST_DECL attach_debugger( bool break_or_continue = true );
// ************************************************************************** //
/// Switches on/off memory leaks detection
/// On platforms where memory leak detection is possible inside of running application (at the moment this is only Windows family) you can
/// switch this feature on and off using this interface. In addition you can specify the name of the file to write a report into. Otherwise
/// the report is going to be generated in standard error stream.
/// @param[in] on_off boolean switch
/// @param[in] report_file file, where the report should be directed to
// ************************************************************************** //
void BOOST_TEST_DECL detect_memory_leaks( bool on_off, unit_test::const_string report_file = unit_test::const_string() );
// ************************************************************************** //
/// Causes program to break execution in debugger at specific allocation point
/// On some platforms/memory managers (at the moment only on Windows/Visual Studio) one can tell a C Runtime to break
/// on specific memory allocation. This can be used in combination with memory leak detection (which reports leaked memory
/// allocation number) to locate the place where leak initiated.
/// @param[in] mem_alloc_order_num Specific memory allocation number
// ************************************************************************** //
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 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! @brief user's config for Boost.Test debugging support
//!
//! This file is intended to be edited by end user to specify varios macros, which configure debugger interface
//! Alterntively you can set these parameters in your own sources/makefiles
// ***************************************************************************
#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,127 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief 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 defined(_WIN32) && !defined(BOOST_DISABLE_WIN32) && \
(!defined(__COMO__) && !defined(__MWERKS__) && !defined(__GNUC__) || \
BOOST_WORKAROUND(__MWERKS__, >= 0x3000))
# define BOOST_SEH_BASED_SIGNAL_HANDLING
#endif
#if defined(__COMO__) && defined(_MSC_VER)
// eh.h uses type_info without declaring it.
class type_info;
# define BOOST_SEH_BASED_SIGNAL_HANDLING
#endif
//____________________________________________________________________________//
#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) && !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 !defined(__BORLANDC__) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
#define BOOST_TEST_SUPPORT_TOKEN_ITERATOR 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
# ifdef BOOST_TEST_SOURCE
# define BOOST_TEST_DECL BOOST_SYMBOL_EXPORT
# else
# define BOOST_TEST_DECL BOOST_SYMBOL_IMPORT
# endif // BOOST_TEST_SOURCE
#else
# 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
#ifndef BOOST_PP_VARIADICS /* we can change this only if not already defined) */
#ifdef __PGI
#define BOOST_PP_VARIADICS 1
#endif
#if BOOST_CLANG
#define BOOST_PP_VARIADICS 1
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 4 * 10000 + 8 * 100)
#define BOOST_PP_VARIADICS 1
#endif
#endif /* ifndef BOOST_PP_VARIADICS */
#endif // BOOST_TEST_CONFIG_HPP_071894GER

View File

@@ -0,0 +1,36 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief enable previously suppressed warnings
// ***************************************************************************
#ifdef BOOST_MSVC
# pragma warning(default: 4511) // copy constructor can't not be generated
# pragma warning(default: 4512) // assignment operator can't 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(default: 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data
# pragma warning(default: 4511) // 'class' : copy constructor could not be generated
# pragma warning(pop)
#endif
#if BOOST_CLANG
#pragma clang diagnostic pop
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 4 * 10000 + 6 * 100)
# pragma GCC diagnostic pop
#endif

View File

@@ -0,0 +1,45 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief 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,93 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief 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>
#include <boost/test/detail/workaround.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 { INV_REPORT_LEVEL, CONFIRMATION_REPORT, SHORT_REPORT, DETAILED_REPORT, NO_REPORT };
//____________________________________________________________________________//
enum output_format { OF_INVALID,
OF_CLF, ///< compiler log format
OF_XML, ///< XML format for report and log,
OF_DOT ///< dot format for output content
};
//____________________________________________________________________________//
enum test_unit_type { TUT_CASE = 0x01, TUT_SUITE = 0x10, TUT_ANY = 0x11 };
//____________________________________________________________________________//
enum assertion_result { AR_FAILED, AR_PASSED, AR_TRIGGERED };
//____________________________________________________________________________//
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;
//____________________________________________________________________________//
namespace ut_detail {
inline test_unit_type
test_id_2_unit_type( test_unit_id id )
{
return (id & 0xFFFF0000) != 0 ? TUT_CASE : TUT_SUITE;
}
//____________________________________________________________________________//
} // namespace ut_detail
// helper templates to prevent ODR violations
template<class T>
struct static_constant {
static T value;
};
template<class T>
T static_constant<T>::value;
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER

View File

@@ -0,0 +1,40 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief 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,49 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief few helpers for working with variadic macros
// ***************************************************************************
#ifndef BOOST_TEST_PP_VARIADIC_HPP_021515GER
#define BOOST_TEST_PP_VARIADIC_HPP_021515GER
// Boost
#include <boost/preprocessor/control/iif.hpp>
#include <boost/preprocessor/comparison/equal.hpp>
#include <boost/preprocessor/variadic/size.hpp>
//____________________________________________________________________________//
#if BOOST_PP_VARIADICS
#if BOOST_PP_VARIADICS_MSVC
# define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) BOOST_PP_CAT( tool (__VA_ARGS__), )
#else
# define BOOST_TEST_INVOKE_VARIADIC( tool, ... ) tool (__VA_ARGS__)
#endif
//____________________________________________________________________________//
/// if sizeof(__VA_ARGS__) == N: F1(__VA_ARGS__)
/// else: F2(__VA_ARGS__)
#define BOOST_TEST_INVOKE_IF_N_ARGS( N, F1, F2, ... ) \
BOOST_TEST_INVOKE_VARIADIC( \
BOOST_PP_IIF( \
BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), N), \
F1, \
F2), \
__VA_ARGS__ ) \
/**/
//____________________________________________________________________________//
#endif /* BOOST_PP_VARIADICS */
#endif // BOOST_TEST_PP_VARIADIC_HPP_021515GER
// EOF

View File

@@ -0,0 +1,38 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief suppress some warnings
// ***************************************************************************
#ifdef BOOST_MSVC
# pragma warning(push)
# pragma warning(disable: 4511) // copy constructor can't not be generated
# pragma warning(disable: 4512) // assignment operator can't 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 ...
# pragma warning(disable: 4267) // 'var' : conversion from 'size_t' to 'type', possible loss of data
# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated
#endif
#if BOOST_CLANG
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wvariadic-macros"
#endif
#if defined(BOOST_GCC) && (BOOST_GCC >= 4 * 10000 + 6 * 100)
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wvariadic-macros"
#endif

View File

@@ -0,0 +1,72 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief contains wrappers, which allows to build Boost.Test with no exception
// ***************************************************************************
#ifndef BOOST_TEST_DETAIL_THROW_EXCEPTION_HPP
#define BOOST_TEST_DETAIL_THROW_EXCEPTION_HPP
// Boost
#include <boost/config.hpp> // BOOST_NO_EXCEPTION
#ifdef BOOST_NO_EXCEPTION
// C RUNTIME
#include <stdlib.h>
#endif
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
#ifdef BOOST_NO_EXCEPTIONS
template<typename E>
BOOST_NORETURN inline void
throw_exception(E const& e) { abort(); }
#define BOOST_TEST_I_TRY
#define BOOST_TEST_I_CATCH( T, var ) for(T const& var = *(T*)0; false;)
#define BOOST_TEST_I_CATCH0( T ) if(0)
#define BOOST_TEST_I_CATCHALL() if(0)
#define BOOST_TEST_I_RETHROW
#else
template<typename E>
BOOST_NORETURN inline void
throw_exception(E const& e) { throw e; }
#define BOOST_TEST_I_TRY try
#define BOOST_TEST_I_CATCH( T, var ) catch( T const& var )
#define BOOST_TEST_I_CATCH0( T ) catch( T const& )
#define BOOST_TEST_I_CATCHALL() catch(...)
#define BOOST_TEST_I_RETHROW throw
#endif
//____________________________________________________________________________//
#define BOOST_TEST_I_THROW( E ) unit_test::ut_detail::throw_exception( E )
#define BOOST_TEST_I_THROW( E ) unit_test::ut_detail::throw_exception( E )
#define BOOST_TEST_I_ASSRT( cond, ex ) if( cond ) {} else BOOST_TEST_I_THROW( ex )
} // namespace ut_detail
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_DETAIL_THROW_EXCEPTION_HPP

View File

@@ -0,0 +1,56 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief 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 boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_WORKAROUND_HPP_021005GER

View File

@@ -0,0 +1,518 @@
// (C) Copyright Gennadiy Rozental 2001.
// (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
//!@brief Defines public interface of the Execution Monitor and related classes
// ***************************************************************************
#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/detail/throw_exception.hpp>
#include <boost/test/utils/class_properties.hpp>
// Boost
#include <boost/shared_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/type.hpp>
#include <boost/cstdlib.hpp>
#include <boost/function/function0.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
// for the FP constants and control routines
#include <float.h>
#ifndef EM_INVALID
#define EM_INVALID _EM_INVALID
#endif
#ifndef EM_DENORMAL
#define EM_DENORMAL _EM_DENORMAL
#endif
#ifndef EM_ZERODIVIDE
#define EM_ZERODIVIDE _EM_ZERODIVIDE
#endif
#ifndef EM_OVERFLOW
#define EM_OVERFLOW _EM_OVERFLOW
#endif
#ifndef EM_UNDERFLOW
#define EM_UNDERFLOW _EM_UNDERFLOW
#endif
#ifndef MCW_EM
#define MCW_EM _MCW_EM
#endif
#else // based on ISO C standard
#if !defined(BOOST_NO_FENV_H)
#include <boost/detail/fenv.hpp>
#endif
#endif
//____________________________________________________________________________//
namespace boost {
/// @defgroup ExecutionMonitor Function Execution Monitor
/// @{
/// @section Intro Introduction
/// Sometimes we need to call a function and make sure that no user or system originated exceptions are being thrown by it. Uniform exception reporting
/// is also may be convenient. That's the purpose of the Boost.Test's Execution Monitor.
///
/// The Execution Monitor is a lower-level component of the Boost Test Library. It is the base for implementing all other Boost.Test components, but also
/// can be used standalone to get controlled execution of error-prone functions with a uniform error notification. The Execution Monitor calls a user-supplied
/// function in a controlled environment, relieving users from messy error detection.
///
/// The Execution Monitor usage is demonstrated in the example exec_mon_example.
///
/// @section DesignRationale Design Rationale
///
/// The Execution Monitor design assumes that it can be used when no (or almost no) memory available. Also the Execution Monitor is intended to be portable to as many platforms as possible.
///
/// @section UserGuide User's guide
/// The Execution Monitor is designed to solve the problem of executing potentially dangerous function that may result in any number of error conditions,
/// in monitored environment that should prevent any undesirable exceptions to propagate out of function call and produce consistent result report for all outcomes.
/// The Execution Monitor is able to produce informative report for all standard C++ exceptions and intrinsic types. All other exceptions are reported as unknown.
/// If you prefer different message for your exception type or need to perform any action, the Execution Monitor supports custom exception translators.
/// There are several other parameters of the monitored environment can be configured by setting appropriate properties of the Execution Monitor.
///
/// All symbols in the Execution Monitor implementation are located in the namespace boost. To use the Execution Monitor you need to:
/// -# include @c boost/test/execution_monitor.hpp
/// -# Make an instance of execution_monitor.
/// -# Optionally register custom exception translators for exception classes which require special processing.
///
/// @subsection FuncExec Monitored function execution
///
/// The class execution_monitor can monitor functions with the following signatures:
/// - int ()
/// - void ()
///
/// This function is expected to be self sufficient part of your application. You can't pass any arguments to this function directly. Instead you
/// should bind them into executable nullary function using bind function (either standard or boost variant). Neither you can return any other value,
/// but an integer result code. If necessary you can bind output parameters by reference or use some other more complicated nullary functor, which
/// maintains state. This includes class methods, static class methods etc.
///
/// To start the monitored function, invoke the method execution_monitor::execute and pass the monitored function as an argument. If the call succeeds,
/// the method returns the result code produced by the monitored function. If any of the following conditions occur:
/// - Uncaught C++ exception
/// - Hardware or software signal, trap, or other exception
/// - Timeout reached
/// - Debug assert event occurred (under Microsoft Visual C++ or compatible compiler)
///
/// then the method throws the execution_exception. The exception contains unique error_code value identifying the error condition and the detailed message
/// that can be used to report the error.
///
/// @subsection Reporting Errors reporting and translation
///
/// If you need to report an error inside monitored function execution you have to throw an exception. Do not use the execution_exception - it's not intended
/// to be used for this purpose. The simplest choice is to use one of the following C++ types as an exception:
/// - C string
/// - std:string
/// - any exception class in std::exception hierarchy
/// - boost::exception
///
/// execution_monitor will catch and report these types of exceptions. If exception is thrown which is unknown to execution_monitor, it can only
/// report the fact of the exception. So in case if you prefer to use your own exception types or can't govern what exceptions are generated by monitored
/// function and would like to see proper error message in a report, execution_monitor can be configured with custom "translator" routine, which will have
/// a chance to either record the fact of the exception itself or translate it into one of standard exceptions and rethrow (or both). The translator routine
/// is registered per exception type and is invoked when exception of this class (or one inherited from it) is thrown inside monitored routine. You can
/// register as many independent translators as you like. See execution_monitor::register_exception_translator specification for requirements on translator
/// function.
///
/// Finally, if you need to abort the monitored function execution without reporting any errors, you can throw an exception execution_aborted. As a result
/// the execution is aborted and zero result code is produced by the method execution_monitor::execute.
///
/// @subsection Parameters Supported parameters
///
/// The Execution Monitor behavior is configurable through the set of parameters (properties) associated with the instance of the monitor. See execution_monitor
/// specification for a list of supported parameters and their semantic.
// ************************************************************************** //
// ************** detail::translator_holder_base ************** //
// ************************************************************************** //
namespace detail {
class translator_holder_base;
typedef boost::shared_ptr<translator_holder_base> translator_holder_base_ptr;
class BOOST_TEST_DECL translator_holder_base {
protected:
typedef boost::unit_test::const_string const_string;
public:
// Constructor
translator_holder_base( translator_holder_base_ptr next, const_string tag )
: m_next( next )
, m_tag( std::string() + tag )
{
}
// Destructor
virtual ~translator_holder_base() {}
// translator holder interface
// invokes the function F inside the try/catch guarding against specific exception
virtual int operator()( boost::function<int ()> const& F ) = 0;
// erases specific translator holder from the chain
translator_holder_base_ptr erase( translator_holder_base_ptr this_, const_string tag )
{
if( m_next )
m_next = m_next->erase( m_next, tag );
return m_tag == tag ? m_next : this_;
}
#ifndef BOOST_NO_RTTI
virtual translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ) = 0;
template<typename ExceptionType>
translator_holder_base_ptr erase( translator_holder_base_ptr this_, boost::type<ExceptionType>* = 0 )
{
if( m_next )
m_next = m_next->erase<ExceptionType>( m_next );
return erase( this_, typeid(ExceptionType) );
}
#endif
protected:
// Data members
translator_holder_base_ptr m_next;
std::string m_tag;
};
} // namespace detail
// ************************************************************************** //
/// @class execution_exception
/// @brief This class is used to report any kind of an failure during execution of a monitored function inside of execution_monitor
///
/// The instance of this class is thrown out of execution_monitor::execute invocation when failure is detected. Regardless of a kind of failure occurred
/// the instance will provide a uniform way to catch and report it.
///
/// One important design rationale for this class is that we should be ready to work after fatal memory corruptions or out of memory conditions. To facilitate
/// this class never allocates any memory and assumes that strings it refers to are either some constants or live in a some kind of persistent (preallocated) memory.
// ************************************************************************** //
class BOOST_TEST_DECL execution_exception {
typedef boost::unit_test::const_string const_string;
public:
/// 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.
///
/// @note(1) Only uncaught C++ exceptions are treated as errors.
/// If a function catches a C++ exception, it never reaches
/// the execution_monitor.
///
/// The implementation decides what is a system_fatal_error 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.
///
/// @note(2) These errors include Unix signals and Windows structured
/// exceptions. They are often initiated by hardware traps.
enum error_code {
no_error = 0, ///< for completeness only; never returned
user_error = 200, ///< user reported non-fatal error
cpp_exception_error = 205, ///< see note (1) above
system_error = 210, ///< see note (2) above
timeout_error = 215, ///< only detectable on certain platforms
user_fatal_error = 220, ///< user reported fatal error
system_fatal_error = 225 ///< see note (2) above
};
/// Simple model for the location of failure in a source code
struct BOOST_TEST_DECL location {
explicit location( char const* file_name = 0, size_t line_num = 0, char const* func = 0 );
const_string m_file_name; ///< File name
size_t m_line_num; ///< Line number
const_string m_function; ///< Function name
};
/// @name Constructors
/// Constructs instance based on message, location and error code
/// @param[in] ec error code
/// @param[in] what_msg error message
/// @param[in] location error location
execution_exception( error_code ec, const_string what_msg, location const& location );
/// @name Access methods
/// Exception error code
error_code code() const { return m_error_code; }
/// Exception message
const_string what() const { return m_what; }
/// Exception location
location const& where() const { return m_location; }
///@}
private:
// Data members
error_code m_error_code;
const_string m_what;
location m_location;
}; // execution_exception
// ************************************************************************** //
/// Function execution monitor
/// This class is used to uniformly detect and report an occurrence of several types of signals and exceptions, reducing various
/// errors to a uniform execution_exception that is returned to a caller.
///
/// The executiom_monitor behavior can be customized through a set of public parameters (properties) associated with the execution_monitor instance.
/// All parameters are implemented as public unit_test::readwrite_property data members of the class execution_monitor.
// ************************************************************************** //
class BOOST_TEST_DECL execution_monitor {
typedef boost::unit_test::const_string const_string;
public:
/// Default constructor initializes all execution monitor properties
execution_monitor();
/// Should monitor catch system errors.
///
/// The @em p_catch_system_errors property is a boolean flag (default value is true) specifying whether or not execution_monitor should trap system
/// errors/system level exceptions/signals, which would cause program to crash in a regular case (without execution_monitor).
/// Set this property to false, for example, if you wish to force coredump file creation. The Unit Test Framework provides a
/// runtime parameter @c \-\-catch_system_errors=yes to alter the behavior in monitored test cases.
unit_test::readwrite_property<bool> p_catch_system_errors;
/// Should monitor try to attach debugger in case of caught system error.
///
/// The @em p_auto_start_dbg property is a boolean flag (default value is false) specifying whether or not execution_monitor should try to attach debugger
/// in case system error is caught.
unit_test::readwrite_property<bool> p_auto_start_dbg;
/// Specifies the seconds that elapse before a timer_error occurs.
///
/// The @em p_timeout property is an integer timeout (in seconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
/// or indefinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
unit_test::readwrite_property<unsigned> p_timeout;
/// Should monitor use alternative stack for the signal catching.
///
/// The @em p_use_alt_stack property is a boolean flag (default value is false) specifying whether or not execution_monitor should use an alternative stack
/// for the sigaction based signal catching. When enabled the signals are delivered to the execution_monitor on a stack different from current execution
/// stack, which is safer in case if it is corrupted by monitored function. For more details on alternative stack handling see appropriate manuals.
unit_test::readwrite_property<bool> p_use_alt_stack;
/// Should monitor try to detect hardware floating point exceptions (!= 0), and which specific exception to catch.
///
/// The @em p_detect_fp_exceptions property is a boolean flag (default value is false) specifying whether or not execution_monitor should install hardware
/// traps for the floating point exception on platforms where it's supported.
unit_test::readwrite_property<unsigned> p_detect_fp_exceptions;
// @name Monitoring entry points
/// @brief Execution monitor entry point for functions returning integer value
///
/// This method executes supplied function F inside a try/catch block and also may include other unspecified platform dependent error detection code.
///
/// This method throws an execution_exception on an uncaught C++ exception, a hardware or software signal, trap, or other user exception.
///
/// @note execute() doesn't consider it an error for F to return a non-zero value.
/// @param[in] F Function to monitor
/// @returns value returned by function call F().
/// @see vexecute
int execute( boost::function<int ()> const& F );
/// @brief Execution monitor entry point for functions returning void
///
/// This method is semantically identical to execution_monitor::execute, but des't produce any result code.
/// @param[in] F Function to monitor
/// @see execute
void vexecute( boost::function<void ()> const& F );
// @}
// @name Exception translator registration
/// @brief Registers custom (user supplied) exception translator
/// This method template registers a translator for an exception type specified as a first template argument. For example
/// @code
/// void myExceptTr( MyException const& ex ) { /*do something with the exception here*/}
/// em.register_exception_translator<MyException>( myExceptTr );
/// @endcode
/// The translator should be any unary function/functor object which accepts MyException const&. This can be free standing function
/// or bound class method. The second argument is an optional string tag you can associate with this translator routine. The only reason
/// to specify the tag is if you plan to erase the translator eventually. This can be useful in scenario when you reuse the same
/// execution_monitor instance to monitor different routines and need to register a translator specific to the routine being monitored.
/// While it is possible to erase the translator based on an exception type it was registered for, tag string provides simpler way of doing this.
/// @tparam ExceptionType type of the exception we register a translator for
/// @tparam ExceptionTranslator type of the translator we register for this exception
/// @param[in] tr translator function object with the signature <em> void (ExceptionType const&)</em>
/// @param[in] tag tag associated with this translator
template<typename ExceptionType, typename ExceptionTranslator>
void register_exception_translator( ExceptionTranslator const& tr, const_string tag = const_string(), boost::type<ExceptionType>* = 0 );
/// @brief Erases custom exception translator based on a tag
/// Use the same tag as the one used during translator registration
/// @param[in] tag tag associated with translator you wants to erase
void erase_exception_translator( const_string tag )
{
m_custom_translators = m_custom_translators->erase( m_custom_translators, tag );
}
#ifndef BOOST_NO_RTTI
/// @brief Erases custom exception translator based on an exception type
///
/// tparam ExceptionType Exception type for which you want to erase the translator
template<typename ExceptionType>
void erase_exception_translator( boost::type<ExceptionType>* = 0 )
{
m_custom_translators = m_custom_translators->erase<ExceptionType>( m_custom_translators );
}
//@}
#endif
private:
// implementation helpers
int catch_signals( boost::function<int ()> const& F );
// Data members
detail::translator_holder_base_ptr m_custom_translators;
boost::scoped_array<char> m_alt_stack;
}; // execution_monitor
// ************************************************************************** //
// ************** detail::translator_holder ************** //
// ************************************************************************** //
namespace detail {
template<typename ExceptionType, typename ExceptionTranslator>
class translator_holder : public translator_holder_base
{
public:
explicit translator_holder( ExceptionTranslator const& tr, translator_holder_base_ptr& next, const_string tag = const_string() )
: translator_holder_base( next, tag ), m_translator( tr ) {}
// translator holder interface
virtual int operator()( boost::function<int ()> const& F )
{
BOOST_TEST_I_TRY {
return m_next ? (*m_next)( F ) : F();
}
BOOST_TEST_I_CATCH( ExceptionType, e ) {
m_translator( e );
return boost::exit_exception_failure;
}
}
#ifndef BOOST_NO_RTTI
virtual translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ti )
{
return ti == typeid(ExceptionType) ? m_next : this_;
}
#endif
private:
// Data members
ExceptionTranslator m_translator;
};
} // namespace detail
template<typename ExceptionType, typename ExceptionTranslator>
void
execution_monitor::register_exception_translator( ExceptionTranslator const& tr, const_string tag, boost::type<ExceptionType>* )
{
m_custom_translators.reset(
new detail::translator_holder<ExceptionType,ExceptionTranslator>( tr, m_custom_translators, tag ) );
}
// ************************************************************************** //
/// @class execution_aborted
/// @brief This is a trivial default constructible class. Use it to report graceful abortion of a monitored function execution.
// ************************************************************************** //
struct execution_aborted {};
// ************************************************************************** //
// ************** system_error ************** //
// ************************************************************************** //
class system_error {
public:
// Constructor
explicit system_error( char const* exp );
long const p_errno;
char const* const p_failed_exp;
};
#define BOOST_TEST_SYS_ASSERT( cond ) BOOST_TEST_I_ASSRT( cond, ::boost::system_error( BOOST_STRINGIZE( exp ) ) )
// ************************************************************************** //
// **************Floating point exception management interface ************** //
// ************************************************************************** //
namespace fpe {
enum masks {
BOOST_FPE_OFF = 0,
#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
BOOST_FPE_DIVBYZERO = EM_ZERODIVIDE,
BOOST_FPE_INEXACT = EM_INEXACT,
BOOST_FPE_INVALID = EM_INVALID,
BOOST_FPE_OVERFLOW = EM_OVERFLOW,
BOOST_FPE_UNDERFLOW = EM_UNDERFLOW|EM_DENORMAL,
BOOST_FPE_ALL = MCW_EM,
#elif defined(BOOST_NO_FENV_H) || defined(BOOST_CLANG)
BOOST_FPE_ALL = 1,
#else
BOOST_FPE_DIVBYZERO = FE_DIVBYZERO,
BOOST_FPE_INEXACT = FE_INEXACT,
BOOST_FPE_INVALID = FE_INVALID,
BOOST_FPE_OVERFLOW = FE_OVERFLOW,
BOOST_FPE_UNDERFLOW = FE_UNDERFLOW,
BOOST_FPE_ALL = FE_ALL_EXCEPT,
#endif
BOOST_FPE_INV = BOOST_FPE_ALL+1
};
//____________________________________________________________________________//
// return the previous set of enabled exceptions when successful, and BOOST_FPE_INV otherwise
unsigned BOOST_TEST_DECL enable( unsigned mask );
unsigned BOOST_TEST_DECL disable( unsigned mask );
//____________________________________________________________________________//
} // namespace fpe
///@}
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif

View File

@@ -0,0 +1,275 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief Defines Unit Test Framework mono-state interfaces.
//! The framework interfaces are based on Monostate design pattern.
// ***************************************************************************
#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/detail/throw_exception.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// STL
#include <stdexcept>
//____________________________________________________________________________//
namespace boost {
/// Main namespace for the Unit Test Framework interfaces and implementation
namespace unit_test {
// ************************************************************************** //
// ************** init_unit_test_func ************** //
// ************************************************************************** //
/// Test module initialization routine signature
/// Different depending on whether BOOST_TEST_ALTERNATIVE_INIT_API is defined or not
#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 of the Unit Test Framework mono-state
namespace framework {
/// @name Unit Test Framework initialization and shutdown
/// @{
/// @brief This function performs initialization of the framework mono-state.
///
/// It needs to be called every time before the test is started.
/// @param[in] init_func test module initialization routine
/// @param[in] argc command line arguments collection
/// @param[in] argv command line arguments collection
BOOST_TEST_DECL void init( init_unit_test_func init_func, int argc, char* argv[] );
/// This function applies all the decorators and figures out default run status. This argument facilitates an
/// ability of the test cases to prepare some other test units (primarily used internally for self testing).
/// @param[in] tu Optional id of the test unit representing root of test tree. If absent, master test suite is used
BOOST_TEST_DECL void finalize_setup_phase( test_unit_id tu = INV_TEST_UNIT_ID);
/// This function returns true when testing is in progress (setup is finished).
BOOST_TEST_DECL bool test_in_progress();
/// This function shuts down the framework and clears up its mono-state.
///
/// It needs to be at the very end of test module execution
BOOST_TEST_DECL void shutdown();
/// @}
/// @name Test unit registration
/// @{
/// Provides both read and write access to current "leaf" auto test suite during the test unit registration phase.
///
/// During auto-registration phase the framework maintain a FIFO queue of test units being registered. New test units become children
/// of the current "leaf" test suite and if this is test suite it is pushed back into queue and becomes a new leaf.
/// When test suite registration is completed, a test suite is popped from the back of the queue. Only automatically registered test suites
/// should be added to this queue. Master test suite is always a zero element in this queue, so if no other test suites are registered
/// all test cases are added to master test suite.
/// This function facilitates all three possible actions:
/// - if no argument are provided it returns the current queue leaf test suite
/// - if test suite is provided and no second argument are set, test suite is added to the queue
/// - if no test suite are provided and last argument is false, the semantic of this function is similar to queue pop: last element is popped from the queue
/// @param[in] ts test suite to push back to the queue
/// @param[in] push_or_pop should we push ts to the queue or pop leaf test suite instead
/// @returns a reference to the currently active/"leaf" test suite
BOOST_TEST_DECL test_suite& current_auto_test_suite( test_suite* ts = 0, bool push_or_pop = true );
/// This function add new test case into the global collection of test units the framework aware of.
/// This function also assignes unique test unit id for every test case. Later on one can use this id to locate
/// the test case if necessary. This is the way for the framework to maintain weak references between test units.
/// @param[in] tc test case to register
BOOST_TEST_DECL void register_test_unit( test_case* tc );
/// This function add new test suite into the global collection of test units the framework aware of.
/// This function also assignes unique test unit id for every test suite. Later on one can use this id to locate
/// the test case if necessary. This is the way for the framework to maintain weak references between test units.
/// @param[in] ts test suite to register
BOOST_TEST_DECL void register_test_unit( test_suite* ts );
/// This function removes the test unit from the collection of known test units and destroys the test unit object.
/// This function also assigns unique test unit id for every test case. Later on one can use this id to located
/// the test case if necessary. This is the way for the framework to maintain weak references between test units.
/// @param[in] tu test unit to deregister
BOOST_TEST_DECL void deregister_test_unit( test_unit* tu );
// This function clears up the framework mono-state.
/// After this call the framework can be reinitialized to perform a second test run during the same program lifetime.
BOOST_TEST_DECL void clear();
/// @}
/// @name Test observer registration
/// @{
/// Adds new test execution observer object into the framework's list of test observers.
/// Observer lifetime should exceed the the testing execution timeframe
/// @param[in] to test observer object to add
BOOST_TEST_DECL void register_observer( test_observer& to );
/// Excldes the observer object form the framework's list of test observers
/// @param[in] to test observer object to exclude
BOOST_TEST_DECL void deregister_observer( test_observer& to );
/// @}
/// @name Assertion/uncaught exception context support
/// @{
/// Context accessor
struct BOOST_TEST_DECL context_generator {
context_generator() : m_curr_frame( 0 ) {}
/// Is there any context?
bool is_empty() const;
/// Give me next frame; empty - last frame
const_string next() const;
private:
// Data members
mutable unsigned m_curr_frame;
};
/// Records context frame message.
/// Some context frames are sticky - they can only explicitly cleared by specifying context id. Other (non sticky) context frames cleared after every assertion.
/// @param[in] context_descr context frame message
/// @param[in] sticky is this sticky frame or not
/// @returns id of the newly created frame
BOOST_TEST_DECL int add_context( lazy_ostream const& context_descr, bool sticky );
/// Erases context frame (when test exits context scope)
/// If context_id is passed clears that specific context frame identified by this id, otherwise clears all non sticky contexts.
BOOST_TEST_DECL void clear_context( int context_id = -1 );
/// Produces an instance of small "delegate" object, which facilitates access to collected context.
BOOST_TEST_DECL context_generator get_context();
/// @}
/// @name Access to registered test units.
/// @{
/// This function provides access to the master test suite.
/// There is only only master test suite per test module.
/// @returns a reference the master test suite instance
BOOST_TEST_DECL master_test_suite_t& master_test_suite();
/// This function provides an access to the test case currently being executed.
/// This function is only valid during test execution phase.
/// @see current_test_case_id
BOOST_TEST_DECL test_case const& current_test_case();
/// This function provides an access to an id of the test case currently being executed.
/// This function safer than current_test_case, cause if wont throw if no test case is being executed.
/// @see current_test_case
BOOST_TEST_DECL test_unit_id current_test_case_id(); /* safe version of above */
/// This function provides access to a test unit by id and type combination. It will throw if no test unit located.
/// @param[in] tu_id id of a test unit to locate
/// @param[in] tu_type type of a test unit to locate
/// @returns located test unit
BOOST_TEST_DECL test_unit& get( test_unit_id tu_id, test_unit_type tu_type );
/// This function template provides access to a typed test unit by id
/// It will throw if you specify incorrect test unit type
/// @tparam UnitType compile time type of test unit to get (test_suite or test_case)
/// @param id id of test unit to get
template<typename UnitType>
inline UnitType& get( test_unit_id id )
{
return static_cast<UnitType&>( get( id, static_cast<test_unit_type>(UnitType::type) ) );
}
///@}
/// @name Test initiation interface
/// @{
/// Initiates test execution
/// This function is used to start the test execution from a specific "root" test unit.
/// If no root provided, test is started from master test suite. This second argument facilitates an ability of the test cases to
/// start some other test units (primarily used internally for self testing).
/// @param[in] tu Optional id of the test unit or test unit itself from which the test is started. If absent, master test suite is used
/// @param[in] continue_test true == continue test if it was already started, false == restart the test from scratch regardless
BOOST_TEST_DECL void run( test_unit_id tu = INV_TEST_UNIT_ID, bool continue_test = true );
/// Initiates test execution. Same as other overload
BOOST_TEST_DECL void run( test_unit const* tu, bool continue_test = true );
/// @}
/// @name Test events dispatchers
/// @{
/// Reports results of assertion to all test observers
BOOST_TEST_DECL void assertion_result( unit_test::assertion_result ar );
/// Reports uncaught exception to all test observers
BOOST_TEST_DECL void exception_caught( execution_exception const& );
/// Reports aborted test unit to all test observers
BOOST_TEST_DECL void test_unit_aborted( test_unit const& );
/// @}
namespace impl {
// exclusively for self test
BOOST_TEST_DECL void setup_for_execution( test_unit const& );
} // namespace impl
// ************************************************************************** //
// ************** framework errors ************** //
// ************************************************************************** //
/// This exception type is used to report internal Boost.Test framework errors.
struct BOOST_TEST_DECL internal_error : public std::runtime_error {
internal_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {}
};
//____________________________________________________________________________//
/// This exception type is used to report test module setup errors.
struct BOOST_TEST_DECL setup_error : public std::runtime_error {
setup_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {}
};
#define BOOST_TEST_SETUP_ASSERT( cond, msg ) BOOST_TEST_I_ASSRT( cond, unit_test::framework::setup_error( msg ) )
//____________________________________________________________________________//
struct nothing_to_test {
explicit nothing_to_test( int rc ) : m_result_code( rc ) {}
int m_result_code;
};
//____________________________________________________________________________//
} // namespace framework
} // unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_FRAMEWORK_HPP_020805GER

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,680 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : supplies offline implementation for the Test Tools
// ***************************************************************************
#ifndef BOOST_TEST_TEST_TOOLS_IPP_012205GER
#define BOOST_TEST_TEST_TOOLS_IPP_012205GER
// Boost.Test
#include <boost/test/unit_test_log.hpp>
#include <boost/test/tools/context.hpp>
#include <boost/test/tools/output_test_stream.hpp>
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/print_helper.hpp>
#include <boost/test/framework.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/execution_monitor.hpp> // execution_aborted
#include <boost/test/detail/throw_exception.hpp>
// Boost
#include <boost/config.hpp>
// STL
#include <fstream>
#include <string>
#include <cstring>
#include <cctype>
#include <cwchar>
#include <stdexcept>
#include <vector>
#include <utility>
#include <ios>
// !! should we use #include <cstdarg>
#include <stdarg.h>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
# ifdef BOOST_NO_STDC_NAMESPACE
namespace std { using ::strcmp; using ::strlen; using ::isprint; }
#if !defined( BOOST_NO_CWCHAR )
namespace std { using ::wcscmp; }
#endif
# endif
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** print_log_value ************** //
// ************************************************************************** //
void
print_log_value<char>::operator()( std::ostream& ostr, char t )
{
if( (std::isprint)( static_cast<unsigned char>(t) ) )
ostr << '\'' << t << '\'';
else
ostr << std::hex
#if BOOST_TEST_USE_STD_LOCALE
<< std::showbase
#else
<< "0x"
#endif
<< static_cast<int>(t);
}
//____________________________________________________________________________//
void
print_log_value<unsigned char>::operator()( std::ostream& ostr, unsigned char t )
{
ostr << std::hex
// showbase is only available for new style streams:
#if BOOST_TEST_USE_STD_LOCALE
<< std::showbase
#else
<< "0x"
#endif
<< static_cast<int>(t);
}
//____________________________________________________________________________//
void
print_log_value<char const*>::operator()( std::ostream& ostr, char const* t )
{
ostr << ( t ? t : "null string" );
}
//____________________________________________________________________________//
void
print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const* t )
{
ostr << ( t ? t : L"null string" );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** TOOL BOX Implementation ************** //
// ************************************************************************** //
using ::boost::unit_test::lazy_ostream;
static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
template<typename OutStream>
void
format_report( OutStream& os, assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
tool_level tl, check_type ct,
std::size_t num_args, va_list args,
char const* prefix, char const* suffix )
{
using namespace unit_test;
switch( ct ) {
case CHECK_PRED:
os << prefix << assertion_descr << suffix;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
case CHECK_BUILT_ASSERTION: {
os << prefix << assertion_descr << suffix;
if( tl != PASS ) {
const_string details_message = pr.message();
if( !details_message.is_empty() ) {
os << details_message;
}
}
break;
}
case CHECK_MSG:
if( tl == PASS )
os << prefix << "'" << assertion_descr << "'" << suffix;
else
os << assertion_descr;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
case CHECK_EQUAL:
case CHECK_NE:
case CHECK_LT:
case CHECK_LE:
case CHECK_GT:
case CHECK_GE: {
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
char const* arg2_descr = va_arg( args, char const* );
lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
if( tl != PASS )
os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_CLOSE:
case CHECK_CLOSE_FRACTION: {
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
char const* arg2_descr = va_arg( args, char const* );
lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
/* toler_descr = */ va_arg( args, char const* );
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
os << "difference{" << pr.message()
<< "} between " << arg1_descr << "{" << *arg1_val
<< "} and " << arg2_descr << "{" << *arg2_val
<< ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
<< *toler_val;
if( ct == CHECK_CLOSE )
os << "%";
break;
}
case CHECK_SMALL: {
char const* arg1_descr = va_arg( args, char const* );
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
/* toler_descr = */ va_arg( args, char const* );
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
<< ( tl == PASS ? " doesn't exceed " : " exceeds " )
<< *toler_val;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_PRED_WITH_ARGS: {
std::vector< std::pair<char const*, lazy_ostream const*> > args_copy;
args_copy.reserve( num_args );
for( std::size_t i = 0; i < num_args; ++i ) {
char const* desc = va_arg( args, char const* );
lazy_ostream const* value = va_arg( args, lazy_ostream const* );
args_copy.push_back( std::make_pair( desc, value ) );
}
os << prefix << assertion_descr;
// print predicate call description
os << "( ";
for( std::size_t i = 0; i < num_args; ++i ) {
os << args_copy[i].first;
if( i != num_args-1 )
os << ", ";
}
os << " )" << suffix;
if( tl != PASS ) {
os << " for ( ";
for( std::size_t i = 0; i < num_args; ++i ) {
os << *args_copy[i].second;
if( i != num_args-1 )
os << ", ";
}
os << " )";
}
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_EQUAL_COLL: {
char const* left_begin_descr = va_arg( args, char const* );
char const* left_end_descr = va_arg( args, char const* );
char const* right_begin_descr = va_arg( args, char const* );
char const* right_end_descr = va_arg( args, char const* );
os << prefix << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
<< right_begin_descr << ", " << right_end_descr << " }"
<< suffix;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
case CHECK_BITWISE_EQUAL: {
char const* left_descr = va_arg( args, char const* );
char const* right_descr = va_arg( args, char const* );
os << prefix << left_descr << " =.= " << right_descr << suffix;
if( !pr.has_empty_message() )
os << ". " << pr.message();
break;
}
}
}
//____________________________________________________________________________//
bool
report_assertion( assertion_result const& ar,
lazy_ostream const& assertion_descr,
const_string file_name,
std::size_t line_num,
tool_level tl,
check_type ct,
std::size_t num_args, ... )
{
using namespace unit_test;
BOOST_TEST_I_ASSRT( framework::current_test_case_id() != INV_TEST_UNIT_ID,
std::runtime_error( "Can't use testing tools outside of test case implementation." ) );
if( !!ar )
tl = PASS;
log_level ll;
char const* prefix;
char const* suffix;
switch( tl ) {
case PASS:
ll = log_successful_tests;
prefix = "check ";
suffix = " has passed";
break;
case WARN:
ll = log_warnings;
prefix = "condition ";
suffix = " is not satisfied";
break;
case CHECK:
ll = log_all_errors;
prefix = "check ";
suffix = " has failed";
break;
case REQUIRE:
ll = log_fatal_errors;
prefix = "critical check ";
suffix = " has failed";
break;
default:
return true;
}
unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
va_list args;
va_start( args, num_args );
format_report( unit_test_log, ar, assertion_descr, tl, ct, num_args, args, prefix, suffix );
va_end( args );
unit_test_log << unit_test::log::end();
switch( tl ) {
case PASS:
framework::assertion_result( AR_PASSED );
return true;
case WARN:
framework::assertion_result( AR_TRIGGERED );
return false;
case CHECK:
framework::assertion_result( AR_FAILED );
return false;
case REQUIRE:
framework::assertion_result( AR_FAILED );
framework::test_unit_aborted( framework::current_test_case() );
BOOST_TEST_I_THROW( execution_aborted() );
}
return true;
}
//____________________________________________________________________________//
assertion_result
format_assertion_result( const_string expr_val, const_string details )
{
assertion_result res(false);
bool starts_new_line = first_char( expr_val ) == '\n';
if( !starts_new_line && !expr_val.is_empty() )
res.message().stream() << " [" << expr_val << "]";
if( !details.is_empty() ) {
if( first_char(details) != '[' )
res.message().stream() << ". ";
else
res.message().stream() << " ";
res.message().stream() << details;
}
if( starts_new_line )
res.message().stream() << "." << expr_val;
return res;
}
//____________________________________________________________________________//
BOOST_TEST_DECL std::string
prod_report_format( assertion_result const& ar, unit_test::lazy_ostream const& assertion_descr, check_type ct, std::size_t num_args, ... )
{
std::ostringstream msg_buff;
va_list args;
va_start( args, num_args );
format_report( msg_buff, ar, assertion_descr, CHECK, ct, num_args, args, "assertion ", " failed" );
va_end( args );
return msg_buff.str();
}
//____________________________________________________________________________//
assertion_result
equal_impl( char const* left, char const* right )
{
return (left && right) ? std::strcmp( left, right ) == 0 : (left == right);
}
//____________________________________________________________________________//
#if !defined( BOOST_NO_CWCHAR )
assertion_result
equal_impl( wchar_t const* left, wchar_t const* right )
{
return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right);
}
#endif // !defined( BOOST_NO_CWCHAR )
//____________________________________________________________________________//
bool
is_defined_impl( const_string symbol_name, const_string symbol_value )
{
symbol_value.trim_left( 2 );
return symbol_name != symbol_value;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** context_frame ************** //
// ************************************************************************** //
context_frame::context_frame( ::boost::unit_test::lazy_ostream const& context_descr )
: m_frame_id( unit_test::framework::add_context( context_descr, true ) )
{
}
//____________________________________________________________________________//
context_frame::~context_frame()
{
unit_test::framework::clear_context( m_frame_id );
}
//____________________________________________________________________________//
context_frame::operator bool()
{
return true;
}
//____________________________________________________________________________//
} // namespace tt_detail
// ************************************************************************** //
// ************** output_test_stream ************** //
// ************************************************************************** //
struct output_test_stream::Impl
{
std::fstream m_pattern;
bool m_match_or_save;
bool m_text_or_binary;
std::string m_synced_string;
char get_char()
{
char res;
do {
m_pattern.get( res );
} while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );
return res;
}
void check_and_fill( assertion_result& res )
{
if( !res.p_predicate_value )
res.message() << "Output content: \"" << m_synced_string << '\"';
}
};
//____________________________________________________________________________//
output_test_stream::output_test_stream( const_string pattern_file_name, bool match_or_save, bool text_or_binary )
: m_pimpl( new Impl )
{
if( !pattern_file_name.is_empty() ) {
std::ios::openmode m = match_or_save ? std::ios::in : std::ios::out;
if( !text_or_binary )
m |= std::ios::binary;
m_pimpl->m_pattern.open( pattern_file_name.begin(), m );
if( !m_pimpl->m_pattern.is_open() )
BOOST_TEST_MESSAGE( "Can't open pattern file " << pattern_file_name << " for " << (match_or_save ? "reading" : "writing") );
}
m_pimpl->m_match_or_save = match_or_save;
m_pimpl->m_text_or_binary = text_or_binary;
}
//____________________________________________________________________________//
output_test_stream::~output_test_stream()
{
delete m_pimpl;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::is_empty( bool flush_stream )
{
sync();
assertion_result res( m_pimpl->m_synced_string.empty() );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::check_length( std::size_t length_, bool flush_stream )
{
sync();
assertion_result res( m_pimpl->m_synced_string.length() == length_ );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::is_equal( const_string arg, bool flush_stream )
{
sync();
assertion_result res( const_string( m_pimpl->m_synced_string ) == arg );
m_pimpl->check_and_fill( res );
if( flush_stream )
flush();
return res;
}
//____________________________________________________________________________//
assertion_result
output_test_stream::match_pattern( bool flush_stream )
{
sync();
assertion_result result( true );
if( !m_pimpl->m_pattern.is_open() ) {
result = false;
result.message() << "Pattern file can't be opened!";
}
else {
if( m_pimpl->m_match_or_save ) {
for ( std::string::size_type i = 0; i < m_pimpl->m_synced_string.length(); ++i ) {
char c = m_pimpl->get_char();
result = !m_pimpl->m_pattern.fail() &&
!m_pimpl->m_pattern.eof() &&
(m_pimpl->m_synced_string[i] == c);
if( !result ) {
std::string::size_type suffix_size = (std::min)( m_pimpl->m_synced_string.length() - i,
static_cast<std::string::size_type>(5) );
// try to log area around the mismatch
result.message() << "Mismatch at position " << i << '\n'
<< "..." << m_pimpl->m_synced_string.substr( i, suffix_size ) << "..." << '\n'
<< "..." << c;
std::string::size_type counter = suffix_size;
while( --counter ) {
char c2 = m_pimpl->get_char();
if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
break;
result.message() << c2;
}
result.message() << "...";
// skip rest of the bytes. May help for further matching
m_pimpl->m_pattern.ignore(
static_cast<std::streamsize>( m_pimpl->m_synced_string.length() - i - suffix_size) );
break;
}
}
}
else {
m_pimpl->m_pattern.write( m_pimpl->m_synced_string.c_str(),
static_cast<std::streamsize>( m_pimpl->m_synced_string.length() ) );
m_pimpl->m_pattern.flush();
}
}
if( flush_stream )
flush();
return result;
}
//____________________________________________________________________________//
void
output_test_stream::flush()
{
m_pimpl->m_synced_string.erase();
#ifndef BOOST_NO_STRINGSTREAM
str( std::string() );
#else
seekp( 0, std::ios::beg );
#endif
}
//____________________________________________________________________________//
std::size_t
output_test_stream::length()
{
sync();
return m_pimpl->m_synced_string.length();
}
//____________________________________________________________________________//
void
output_test_stream::sync()
{
#ifdef BOOST_NO_STRINGSTREAM
m_pimpl->m_synced_string.assign( str(), pcount() );
freeze( false );
#else
m_pimpl->m_synced_string = str();
#endif
}
//____________________________________________________________________________//
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_TOOLS_IPP_012205GER

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,156 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Deprecated implementation of simple minimal testing
/// @deprecated
/// To convert to Unit Test Framework simply rewrite:
/// @code
/// #include <boost/test/minimal.hpp>
///
/// int test_main( int, char *[] )
/// {
/// ...
/// }
/// @endcode
/// as
/// @code
/// #include <boost/test/included/unit_test.hpp>
///
/// BOOST_AUTO_TEST_CASE(test_main)
/// {
/// ...
/// }
/// @endcode
// ***************************************************************************
#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/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 \"" ) + exex.what() + "\" 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,72 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : 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:
compiler_log_formatter() : m_color_output( false ) {}
// 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, const_string reason );
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
void log_exception_finish( std::ostream& );
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& );
void entry_context_start( std::ostream&, log_level );
void log_entry_context( std::ostream&, const_string );
void entry_context_finish( std::ostream& );
protected:
virtual void print_prefix( std::ostream&, const_string file, std::size_t line );
// Data members
bool m_color_output;
};
} // 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,59 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : plain report formatter 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:
plain_report_formatter() : m_indent( 0 ), m_color_output( false ) {}
// 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;
bool m_color_output;
};
} // 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 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : contains OF_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, const_string reason );
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
void log_exception_finish( std::ostream& );
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& );
void entry_context_start( std::ostream&, log_level );
void log_entry_context( std::ostream&, const_string );
void entry_context_finish( std::ostream& );
private:
// Data members
const_string m_curr_tag;
bool m_value_closed;
};
} // 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,52 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : OF_XML report formatter 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,66 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief 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/tree/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 ************** //
// ************************************************************************** //
/// This class implements test observer interface and updates test progress as test units finish or get aborted
class BOOST_TEST_DECL progress_monitor_t : public test_observer, public singleton<progress_monitor_t> {
public:
/// @name Test observer interface
/// @{
virtual void test_start( counter_t test_cases_amount );
virtual void test_aborted();
virtual void test_unit_finish( test_unit const&, unsigned long );
virtual void test_unit_skipped( test_unit const&, const_string );
virtual int priority() { return 3; }
/// @}
/// @name 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,128 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file results_collector.hpp @brief defines testing result collector components
///
/// Defines class results_collector_t that is responsible for
/// gathering test results and class test_results for 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/tree/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 {
namespace {
// ************************************************************************** //
/// First failed assertion debugger hook
///
/// This function is a placeholder where user can set a breakpoint in debugger to catch the
/// very first assertion failure in each test case
// ************************************************************************** //
inline void first_failed_assertion() {}
}
// ************************************************************************** //
/// @brief Collection of attributes constituting test unit results
///
/// This class is a collection of attributes describing testing results. The atributes presented as public properties on
/// an instance of the class. In addition summary conclusion methods are presented to generate simple answer to pass/fail question
// ************************************************************************** //
class BOOST_TEST_DECL test_results {
public:
test_results();
/// Type representing counter like public property
typedef BOOST_READONLY_PROPERTY( counter_t, (results_collector_t)(test_results)(results_collect_helper) ) counter_prop;
/// Type representing boolean like public property
typedef BOOST_READONLY_PROPERTY( bool, (results_collector_t)(test_results)(results_collect_helper) ) bool_prop;
/// @name Public properties
counter_prop p_assertions_passed;
counter_prop p_assertions_failed;
counter_prop p_warnings_failed;
counter_prop p_expected_failures;
counter_prop p_test_cases_passed;
counter_prop p_test_cases_warned;
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;
/// @}
/// @name Summary conclusion
/// Returns true if test unit passed
bool passed() const;
/// Produces result code for the test unit execution
/// This methhod return one of the result codes defined in boost/cstdlib.hpp
/// @returns boost::exit_success on success, boost::exit_exception_failure in case test unit was aborted for any reason
/// (incuding uncausght exception) and boost::exit_test_failure otherwise
int result_code() const;
/// @}
// collection helper
void operator+=( test_results const& );
void clear();
};
// ************************************************************************** //
/// This class implements test observer interface to collect the result of test unit execution
// ************************************************************************** //
class BOOST_TEST_DECL results_collector_t : public test_observer, public singleton<results_collector_t> {
public:
virtual void test_start( counter_t test_cases_amount );
virtual void test_unit_start( test_unit const& );
virtual void test_unit_finish( test_unit const&, unsigned long );
virtual void test_unit_skipped( test_unit const&, const_string );
virtual void test_unit_aborted( test_unit const& );
virtual void assertion_result( unit_test::assertion_result );
virtual void exception_caught( execution_exception const& );
virtual int priority() { return 2; }
/// Results access per test unit
/// @param[in] tu_id id of a test unit
test_results const& results( test_unit_id tu_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,122 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief defines testing result reporter interfaces
///
/// This file defines interfaces that are responsible for results reporting. Interface is presented in a form of
/// free standing function implemented in namespace result_reporter
// ***************************************************************************
#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 for results reporter interfaces
namespace results_reporter {
// ************************************************************************** //
/// @brief Results report formatter interface
///
/// This is abstract interface for the report formatter used by results reporter routines.
/// You can define a custom formatter by implementing this interface and setting the formatter using set_format function.
/// This is usually done during test module initialization
// ************************************************************************** //
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;
};
// ************************************************************************** //
/// @name report configuration
// ************************************************************************** //
/// Sets reporting level
/// There are only four possible levels for results report:
/// - confirmation report (boost::unit_test::CONFIRMATION_REPORT). This report level only produces short confirmation
/// message about test module pass/fail status
/// - short report (boost::unit_test::SHORT_REPORT). This report level produces short summary report for failed/passed
/// assertions and test units.
/// - detailed report (boost::unit_test::DETAILED_REPORT). This report level produces detailed report per test unit for
/// passed/failed assertions and uncaught exceptions
/// - no report (boost::unit_test::NO_REPORT). This report level produces no results report. This is used for test modules
/// running as part of some kind of continues integration framework
/// @param[in] l report level
BOOST_TEST_DECL void set_level( report_level l );
/// Sets output stream for results reporting
/// By default std::cerr is used. Use this function to set a different stream. The framework
/// refers to the stream by reference, so you need to make sure the stream object lifetime exceeds the testing main scope.
BOOST_TEST_DECL void set_stream( std::ostream& );
/// Sets one of the predefined formats
/// The framework implements two results report formats:
/// - plain human readable format (boost::unit_test::OF_CLF)
/// - XML format (boost::unit_test::OF_XML)
/// @param[in] of one of the presefined enumeration values for output formats
BOOST_TEST_DECL void set_format( output_format of );
/// Sets custom report formatter
/// The framework takes ownership of the pointer passed as an argument. So this should be a pointer to
/// a heap allocated object
/// @param[in] f pointer to heap allocated instance of custom report formatter class
BOOST_TEST_DECL void set_format( results_reporter::format* f );
/// @brief Access to configured results reporter stream
///
/// Use this stream to report additional information abut test module execution
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,68 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief test tools compatibility header
///
/// This file is used to select the test tools implementation and includes all the necessary headers
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_HPP_111812GER
#define BOOST_TEST_TOOLS_HPP_111812GER
#include <boost/config.hpp>
// brings some compiler configuration like BOOST_PP_VARIADICS
#include <boost/test/detail/config.hpp>
#include <boost/preprocessor/config/config.hpp>
#if defined(BOOST_NO_CXX11_VARIADIC_MACROS) \
|| defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) \
|| defined(BOOST_NO_CXX11_DECLTYPE)
# define BOOST_TEST_MACRO_LIMITED_SUPPORT
#endif
// Boost.Test
// #define BOOST_TEST_NO_OLD_TOOLS
#if defined(BOOST_TEST_MACRO_LIMITED_SUPPORT) \
&& ( !BOOST_PP_VARIADICS \
|| !(__cplusplus >= 201103L) && defined(BOOST_NO_CXX11_VARIADIC_MACROS))
# define BOOST_TEST_NO_NEW_TOOLS
#endif
// #define BOOST_TEST_TOOLS_UNDER_DEBUGGER
// #define BOOST_TEST_TOOLS_DEBUGGABLE
#include <boost/test/tools/context.hpp>
#ifndef BOOST_TEST_NO_OLD_TOOLS
# include <boost/test/tools/old/interface.hpp>
# include <boost/test/tools/old/impl.hpp>
# include <boost/test/tools/detail/print_helper.hpp>
#endif
#ifndef BOOST_TEST_NO_NEW_TOOLS
# include <boost/test/tools/interface.hpp>
# include <boost/test/tools/assertion.hpp>
# include <boost/test/tools/fpc_op.hpp>
# include <boost/test/tools/collection_comparison_op.hpp>
# include <boost/test/tools/cstring_comparison_op.hpp>
# include <boost/test/tools/detail/fwd.hpp>
# include <boost/test/tools/detail/print_helper.hpp>
# include <boost/test/tools/detail/it_pair.hpp>
# include <boost/test/tools/detail/bitwise_manip.hpp>
# include <boost/test/tools/detail/tolerance_manip.hpp>
# include <boost/test/tools/detail/per_element_manip.hpp>
# include <boost/test/tools/detail/lexicographic_manip.hpp>
#endif
#endif // BOOST_TEST_TOOLS_HPP_111812GER

View File

@@ -0,0 +1,410 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief Defines framework for automated assertion construction
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
#define BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER
// Boost.Test
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/tools/detail/print_helper.hpp>
#include <boost/test/tools/detail/fwd.hpp>
// Boost
#include <boost/type.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/utility/declval.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_const.hpp>
// STL
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
#include <utility>
#endif
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace assertion {
// ************************************************************************** //
// ************** assertion::operators ************** //
// ************************************************************************** //
// precedence 4: ->*, .*
// precedence 5: *, /, %
// precedence 6: +, -
// precedence 7: << , >>
// precedence 8: <, <=, > and >=
// precedence 9: == and !=
// precedence 10: bitwise AND
// precedence 11: bitwise XOR
// precedence 12: bitwise OR
// precedence 13: logical AND
// disabled
// precedence 14: logical OR
// disabled
// precedence 15: ternary conditional
// disabled
// precedence 16: = and OP= operators
// precedence 17: throw operator
// not supported
// precedence 18: comma
// not supported
namespace op {
#define BOOST_TEST_FOR_EACH_COMP_OP(action) \
action( < , LT, >= ) \
action( <=, LE, > ) \
action( > , GT, <= ) \
action( >=, GE, < ) \
action( ==, EQ, != ) \
action( !=, NE, == ) \
/**/
//____________________________________________________________________________//
#ifndef BOOST_NO_CXX11_DECLTYPE
#define BOOST_TEST_FOR_EACH_CONST_OP(action)\
action(->*, MEMP, ->* ) \
\
action( * , MUL, * ) \
action( / , DIV, / ) \
action( % , MOD, % ) \
\
action( + , ADD, + ) \
action( - , SUB, - ) \
\
action( <<, LSH, << ) \
action( >>, RSH, >> ) \
\
BOOST_TEST_FOR_EACH_COMP_OP(action) \
\
action( & , BAND, & ) \
action( ^ , XOR, ^ ) \
action( | , BOR, | ) \
/**/
#else
#define BOOST_TEST_FOR_EACH_CONST_OP(action)\
BOOST_TEST_FOR_EACH_COMP_OP(action) \
/**/
#endif
//____________________________________________________________________________//
#define BOOST_TEST_FOR_EACH_MUT_OP(action) \
action( = , SET , = ) \
action( +=, IADD, += ) \
action( -=, ISUB, -= ) \
action( *=, IMUL, *= ) \
action( /=, IDIV, /= ) \
action( %=, IMOD, %= ) \
action(<<=, ILSH, <<=) \
action(>>=, IRSH, >>=) \
action( &=, IAND, &= ) \
action( ^=, IXOR, ^= ) \
action( |=, IOR , |= ) \
/**/
//____________________________________________________________________________//
#ifndef BOOST_NO_CXX11_DECLTYPE
# define DEDUCE_RESULT_TYPE( oper ) \
decltype(boost::declval<Lhs>() oper boost::declval<Rhs>() ) optype; \
typedef typename boost::remove_reference<optype>::type \
/**/
#else
# define DEDUCE_RESULT_TYPE( oper ) bool
#endif
#define DEFINE_CONST_OPER( oper, name, rev ) \
template<typename Lhs, typename Rhs, \
typename Enabler=void> \
struct name { \
typedef DEDUCE_RESULT_TYPE( oper ) result_type; \
\
static result_type \
eval( Lhs const& lhs, Rhs const& rhs ) \
{ \
return lhs oper rhs; \
} \
\
template<typename PrevExprType> \
static void \
report( std::ostream& ostr, \
PrevExprType const& lhs, \
Rhs const& rhs) \
{ \
lhs.report( ostr ); \
ostr << revert() \
<< tt_detail::print_helper( rhs ); \
} \
\
static char const* revert() \
{ return " " #rev " "; } \
}; \
/**/
BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER )
#undef DEDUCE_RESULT_TYPE
#undef DEFINE_CONST_OPER
//____________________________________________________________________________//
} // namespace op
// ************************************************************************** //
// ************** assertion::expression_base ************** //
// ************************************************************************** //
// Defines expression operators
template<typename Lhs, typename Rhs, typename OP> class binary_expr;
template<typename ExprType,typename ValType>
class expression_base {
public:
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
template<typename T>
struct RhsT : remove_const<typename remove_reference<T>::type> {};
#define ADD_OP_SUPPORT( oper, name, _ ) \
template<typename T> \
binary_expr<ExprType,T, \
op::name<ValType,typename RhsT<T>::type> > \
operator oper( T&& rhs ) \
{ \
return binary_expr<ExprType,T, \
op::name<ValType,typename RhsT<T>::type> > \
( std::forward<ExprType>( \
*static_cast<ExprType*>(this) ), \
std::forward<T>(rhs) ); \
} \
/**/
#else
#define ADD_OP_SUPPORT( oper, name, _ ) \
template<typename T> \
binary_expr<ExprType,typename boost::decay<T const>::type, \
op::name<ValType,typename boost::decay<T const>::type> >\
operator oper( T const& rhs ) const \
{ \
typedef typename boost::decay<T const>::type Rhs; \
return binary_expr<ExprType,Rhs,op::name<ValType,Rhs> > \
( *static_cast<ExprType const*>(this), \
rhs ); \
} \
/**/
#endif
BOOST_TEST_FOR_EACH_CONST_OP( ADD_OP_SUPPORT )
#undef ADD_OP_SUPPORT
#ifndef BOOST_NO_CXX11_AUTO_DECLARATIONS
// Disabled operators
template<typename T>
ExprType&
operator ||( T const& /*rhs*/ )
{
BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_OR_WITHIN_THIS_TESTING_TOOL, () );
return *static_cast<ExprType*>(this);
}
template<typename T>
ExprType&
operator &&( T const& /*rhs*/ )
{
BOOST_MPL_ASSERT_MSG(false, CANT_USE_LOGICAL_OPERATOR_AND_WITHIN_THIS_TESTING_TOOL, () );
return *static_cast<ExprType*>(this);
}
operator bool()
{
BOOST_MPL_ASSERT_MSG(false, CANT_USE_TERNARY_OPERATOR_WITHIN_THIS_TESTING_TOOL, () );
return false;
}
#endif
};
// ************************************************************************** //
// ************** assertion::value_expr ************** //
// ************************************************************************** //
// simple value expression
template<typename T>
class value_expr : public expression_base<value_expr<T>,typename remove_const<typename remove_reference<T>::type>::type> {
public:
// Public types
typedef T result_type;
// Constructor
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
value_expr( value_expr&& ve )
: m_value( std::forward<T>(ve.m_value) )
{}
explicit value_expr( T&& val )
: m_value( std::forward<T>(val) )
{}
#else
explicit value_expr( T const& val )
: m_value( val )
{}
#endif
// Specific expression interface
T const& value() const
{
return m_value;
}
void report( std::ostream& ostr ) const
{
ostr << tt_detail::print_helper( m_value );
}
// Mutating operators
#define ADD_OP_SUPPORT( OPER, ID, _ ) \
template<typename U> \
value_expr<T>& \
operator OPER( U const& rhs ) \
{ \
m_value OPER rhs; \
\
return *this; \
} \
/**/
BOOST_TEST_FOR_EACH_MUT_OP( ADD_OP_SUPPORT )
#undef ADD_OP_SUPPORT
// expression interface
assertion_result evaluate( bool no_message = false ) const
{
assertion_result res( value() );
if( no_message || res )
return res;
format_message( res.message(), value() );
return tt_detail::format_assertion_result( "", res.message().str() );
}
private:
template<typename U>
static void format_message( wrap_stringstream& ostr, U const& v ) { ostr << "[(bool)" << v << " is false]"; }
static void format_message( wrap_stringstream& /*ostr*/, bool /*v*/ ) {}
static void format_message( wrap_stringstream& /*ostr*/, assertion_result const& /*v*/ ) {}
// Data members
T m_value;
};
// ************************************************************************** //
// ************** assertion::binary_expr ************** //
// ************************************************************************** //
// binary expression
template<typename LExpr, typename Rhs, typename OP>
class binary_expr : public expression_base<binary_expr<LExpr,Rhs,OP>,typename OP::result_type> {
public:
// Public types
typedef typename OP::result_type result_type;
// Constructor
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
binary_expr( binary_expr&& be )
: m_lhs( std::forward<LExpr>(be.m_lhs) )
, m_rhs( std::forward<Rhs>(be.m_rhs) )
{}
binary_expr( LExpr&& lhs, Rhs&& rhs )
: m_lhs( std::forward<LExpr>(lhs) )
, m_rhs( std::forward<Rhs>(rhs) )
{}
#else
binary_expr( LExpr const& lhs, Rhs const& rhs )
: m_lhs( lhs )
, m_rhs( rhs )
{}
#endif
// Specific expression interface
result_type value() const
{
return OP::eval( m_lhs.value(), m_rhs );
}
void report( std::ostream& ostr ) const
{
return OP::report( ostr, m_lhs, m_rhs );
}
assertion_result evaluate( bool no_message = false ) const
{
assertion_result const expr_res( value() );
if( no_message || expr_res )
return expr_res;
wrap_stringstream buff;
report( buff.stream() );
return tt_detail::format_assertion_result( buff.stream().str(), expr_res.message() );
}
// To support custom manipulators
LExpr const& lhs() const { return m_lhs; }
Rhs const& rhs() const { return m_rhs; }
private:
// Data members
LExpr m_lhs;
Rhs m_rhs;
};
// ************************************************************************** //
// ************** assertion::seed ************** //
// ************************************************************************** //
// seed added ot the input expression to form an assertion expression
class seed {
public:
// ->* is highest precedence left to right operator
template<typename T>
value_expr<T>
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
operator->*( T&& v ) const
{
return value_expr<T>( std::forward<T>( v ) );
}
#else
operator->*( T const& v ) const
{
return value_expr<T>( v );
}
#endif
};
#undef BOOST_TEST_FOR_EACH_CONST_OP
} // namespace assertion
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_ASSERTION_HPP_100911GER

View File

@@ -0,0 +1,90 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// 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 {
// ************************************************************************** //
// ************** assertion_result ************** //
// ************************************************************************** //
//!@brief Type used for storing the result of an assertion.
class BOOST_TEST_DECL assertion_result {
//!@internal
typedef unit_test::const_string const_string;
//!@internal
struct dummy { void nonnull() {} };
//!@internal
typedef void (dummy::*safe_bool)();
public:
// Constructor
assertion_result( bool pv_ )
: p_predicate_value( pv_ )
{}
template<typename BoolConvertable>
assertion_result( BoolConvertable const& pv_ ) : p_predicate_value( !!pv_ ) {}
// Access methods
bool operator!() const { return !p_predicate_value; }
void operator=( bool pv_ ) { p_predicate_value.value = pv_; }
operator safe_bool() const { return !!p_predicate_value ? &dummy::nonnull : 0; }
// Public properties
BOOST_READONLY_PROPERTY( bool, (assertion_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;
};
typedef assertion_result predicate_result;
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_PREDICATE_RESULT_HPP_012705GER

View File

@@ -0,0 +1,378 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief Collection comparison with enhanced reporting
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
#define BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER
// Boost.Test
#include <boost/test/tools/assertion.hpp>
#include <boost/test/utils/is_forward_iterable.hpp>
// Boost
#include <boost/mpl/bool.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace assertion {
// ************************************************************************** //
// ************* selectors for specialized comparizon routines ************** //
// ************************************************************************** //
template<typename T>
struct specialized_compare : public mpl::false_ {};
#define BOOST_TEST_SPECIALIZED_COLLECTION_COMPARE(Col) \
namespace boost { namespace test_tools { namespace assertion { \
template<> \
struct specialized_compare<Col> : public mpl::true_ {}; \
}}} \
/**/
// ************************************************************************** //
// ************** lexicographic_compare ************** //
// ************************************************************************** //
namespace op {
template <typename OP, bool can_be_equal, bool prefer_shorter,
typename Lhs, typename Rhs>
inline assertion_result
lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
{
assertion_result ar( true );
typename Lhs::const_iterator first1 = lhs.begin();
typename Rhs::const_iterator first2 = rhs.begin();
typename Lhs::const_iterator last1 = lhs.end();
typename Rhs::const_iterator last2 = rhs.end();
std::size_t pos = 0;
for( ; (first1 != last1) && (first2 != last2); ++first1, ++first2, ++pos ) {
assertion_result const& element_ar = OP::eval(*first1, *first2);
if( !can_be_equal && element_ar )
return ar; // a < b
assertion_result const& reverse_ar = OP::eval(*first2, *first1);
if( element_ar && !reverse_ar )
return ar; // a<=b and !(b<=a) => a < b => return true
if( element_ar || !reverse_ar )
continue; // (a<=b and b<=a) or (!(a<b) and !(b<a)) => a == b => keep looking
// !(a<=b) and b<=a => b < a => return false
ar = false;
ar.message() << "\nFailure at position " << pos << ": "
<< tt_detail::print_helper(*first1)
<< OP::revert()
<< tt_detail::print_helper(*first2)
<< ". " << element_ar.message();
return ar;
}
if( first1 != last1 ) {
if( prefer_shorter ) {
ar = false;
ar.message() << "\nFirst collection has extra trailing elements.";
}
}
else if( first2 != last2 ) {
if( !prefer_shorter ) {
ar = false;
ar.message() << "\nSecond collection has extra trailing elements.";
}
}
else if( !can_be_equal ) {
ar = false;
ar.message() << "\nCollections appear to be equal.";
}
return ar;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** equality_compare ************** //
// ************************************************************************** //
template <typename OP, typename Lhs, typename Rhs>
inline assertion_result
element_compare( Lhs const& lhs, Rhs const& rhs )
{
assertion_result ar( true );
if( lhs.size() != rhs.size() ) {
ar = false;
ar.message() << "\nCollections size mismatch: " << lhs.size() << " != " << rhs.size();
return ar;
}
typename Lhs::const_iterator left = lhs.begin();
typename Rhs::const_iterator right = rhs.begin();
std::size_t pos = 0;
for( ; pos < lhs.size(); ++left, ++right, ++pos ) {
assertion_result const element_ar = OP::eval( *left, *right );
if( element_ar )
continue;
ar = false;
ar.message() << "\nMismatch at position " << pos << ": "
<< tt_detail::print_helper(*left)
<< OP::revert()
<< tt_detail::print_helper(*right)
<< ". " << element_ar.message();
}
return ar;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** non_equality_compare ************** //
// ************************************************************************** //
template <typename OP, typename Lhs, typename Rhs>
inline assertion_result
non_equality_compare( Lhs const& lhs, Rhs const& rhs )
{
assertion_result ar( true );
if( lhs.size() != rhs.size() )
return ar;
typename Lhs::const_iterator left = lhs.begin();
typename Rhs::const_iterator right = rhs.begin();
typename Lhs::const_iterator end = lhs.end();
for( ; left != end; ++left, ++right ) {
if( OP::eval( *left, *right ) )
return ar;
}
ar = false;
ar.message() << "\nCollections appear to be equal";
return ar;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** cctraits ************** //
// ************************************************************************** //
// set of collection comparison traits per comparison OP
template<typename OP>
struct cctraits;
template<typename Lhs, typename Rhs>
struct cctraits<op::EQ<Lhs, Rhs> > {
typedef specialized_compare<Lhs> is_specialized;
};
template<typename Lhs, typename Rhs>
struct cctraits<op::NE<Lhs, Rhs> > {
typedef specialized_compare<Lhs> is_specialized;
};
template<typename Lhs, typename Rhs>
struct cctraits<op::LT<Lhs, Rhs> > {
static const bool can_be_equal = false;
static const bool prefer_short = true;
typedef specialized_compare<Lhs> is_specialized;
};
template<typename Lhs, typename Rhs>
struct cctraits<op::LE<Lhs, Rhs> > {
static const bool can_be_equal = true;
static const bool prefer_short = true;
typedef specialized_compare<Lhs> is_specialized;
};
template<typename Lhs, typename Rhs>
struct cctraits<op::GT<Lhs, Rhs> > {
static const bool can_be_equal = false;
static const bool prefer_short = false;
typedef specialized_compare<Lhs> is_specialized;
};
template<typename Lhs, typename Rhs>
struct cctraits<op::GE<Lhs, Rhs> > {
static const bool can_be_equal = true;
static const bool prefer_short = false;
typedef specialized_compare<Lhs> is_specialized;
};
// ************************************************************************** //
// ************** compare_collections ************** //
// ************************************************************************** //
// Overloaded set of functions dispatching to specific implementation of comparison
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::EQ<L, R> >*, mpl::true_ )
{
return assertion::op::element_compare<op::EQ<L, R> >( lhs, rhs );
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::EQ<L, R> >*, mpl::false_ )
{
return lhs == rhs;
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::NE<L, R> >*, mpl::true_ )
{
return assertion::op::non_equality_compare<op::NE<L, R> >( lhs, rhs );
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::NE<L, R> >*, mpl::false_ )
{
return lhs != rhs;
}
//____________________________________________________________________________//
template <typename OP, typename Lhs, typename Rhs>
inline assertion_result
lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
{
return assertion::op::lexicographic_compare<OP, cctraits<OP>::can_be_equal, cctraits<OP>::prefer_short>( lhs, rhs );
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename OP>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<OP>*, mpl::true_ )
{
return lexicographic_compare<OP>( lhs, rhs );
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LT<L, R> >*, mpl::false_ )
{
return lhs < rhs;
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::LE<L, R> >*, mpl::false_ )
{
return lhs <= rhs;
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GT<L, R> >*, mpl::false_ )
{
return lhs > rhs;
}
//____________________________________________________________________________//
template <typename Lhs, typename Rhs, typename L, typename R>
inline assertion_result
compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >*, mpl::false_ )
{
return lhs >= rhs;
}
//____________________________________________________________________________//
// ************************************************************************** //
// ********* specialization of comparison operators for collections ********* //
// ************************************************************************** //
#define DEFINE_COLLECTION_COMPARISON( oper, name, rev ) \
template<typename Lhs,typename Rhs> \
struct name<Lhs,Rhs,typename boost::enable_if_c< \
unit_test::is_forward_iterable<Lhs>::value && \
unit_test::is_forward_iterable<Rhs>::value>::type> { \
public: \
typedef assertion_result result_type; \
\
typedef name<Lhs, Rhs> OP; \
typedef typename \
mpl::if_c<is_same<typename decay<Lhs>::type, \
typename decay<Rhs>::type>::value, \
typename cctraits<OP>::is_specialized, \
mpl::false_>::type is_specialized; \
\
typedef name<typename Lhs::value_type, \
typename Rhs::value_type> elem_op; \
\
static assertion_result \
eval( Lhs const& lhs, Rhs const& rhs) \
{ \
return assertion::op::compare_collections( lhs, rhs, \
(boost::type<elem_op>*)0, \
is_specialized() ); \
} \
\
template<typename PrevExprType> \
static void \
report( std::ostream&, \
PrevExprType const&, \
Rhs const& ) {} \
\
static char const* revert() \
{ return " " #rev " "; } \
\
}; \
/**/
BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_COLLECTION_COMPARISON )
#undef DEFINE_COLLECTION_COMPARISON
//____________________________________________________________________________//
} // namespace op
} // namespace assertion
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_COLLECTION_COMPARISON_OP_HPP_050815GER

View File

@@ -0,0 +1,65 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : test tools context interfaces
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER
#define BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER
// Boost.Test
#include <boost/test/utils/lazy_ostream.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** context_frame ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL context_frame {
explicit context_frame( ::boost::unit_test::lazy_ostream const& context_descr );
~context_frame();
operator bool();
private:
// Data members
int m_frame_id;
};
//____________________________________________________________________________//
#define BOOST_TEST_INFO( context_descr ) \
::boost::unit_test::framework::add_context( BOOST_TEST_LAZY_MSG( context_descr ) , false ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_CONTEXT( context_descr ) \
if( ::boost::test_tools::tt_detail::context_frame BOOST_JOIN( context_frame_, __LINE__ ) = \
::boost::test_tools::tt_detail::context_frame( BOOST_TEST_LAZY_MSG( context_descr ) ) ) \
/**/
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER

View File

@@ -0,0 +1,91 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief C string comparison with enhanced reporting
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
#define BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
// Boost.Test
#include <boost/test/tools/assertion.hpp>
#include <boost/test/utils/is_cstring.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
// Boost
#include <boost/utility/enable_if.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace assertion {
namespace op {
// ************************************************************************** //
// ************** string_compare ************** //
// ************************************************************************** //
#define DEFINE_CSTRING_COMPARISON( oper, name, rev ) \
template<typename Lhs,typename Rhs> \
struct name<Lhs,Rhs,typename boost::enable_if_c< \
unit_test::is_cstring<Lhs>::value && \
unit_test::is_cstring<Rhs>::value>::type> { \
typedef typename boost::add_const< \
typename remove_pointer< \
typename decay<Lhs>::type>::type>::type \
lhs_char_type; \
typedef typename boost::add_const< \
typename remove_pointer< \
typename decay<Rhs>::type>::type>::type \
rhs_char_type; \
public: \
typedef assertion_result result_type; \
\
static bool \
eval( Lhs const& lhs, Rhs const& rhs) \
{ \
return unit_test::basic_cstring<lhs_char_type>(lhs) oper \
unit_test::basic_cstring<rhs_char_type>(rhs); \
} \
\
template<typename PrevExprType> \
static void \
report( std::ostream& ostr, \
PrevExprType const& lhs, \
Rhs const& rhs) \
{ \
lhs.report( ostr ); \
ostr << revert() \
<< tt_detail::print_helper( rhs ); \
} \
\
static char const* revert() \
{ return " " #rev " "; } \
}; \
/**/
BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_CSTRING_COMPARISON )
#undef DEFINE_CSTRING_COMPARISON
//____________________________________________________________________________//
} // namespace op
} // namespace assertion
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER

View File

@@ -0,0 +1,123 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! Bitwise comparison manipulator implementation
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
#define BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER
// Boost Test
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/indirections.hpp>
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/tools/assertion.hpp>
// STL
#include <climits> // for CHAR_BIT
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
// ************************************************************************** //
// ************** bitwise comparison manipulator ************** //
// ************************************************************************** //
//! Bitwise comparison manipulator
struct bitwise {};
//____________________________________________________________________________//
inline int
operator<<( unit_test::lazy_ostream const&, bitwise ) { return 0; }
//____________________________________________________________________________//
namespace tt_detail {
/*!@brief Bitwise comparison of two operands
*
* This class constructs an @ref assertion_result that contains precise bit comparison information.
* In particular the location of the mismatches (if any) are printed in the assertion result.
*/
template<typename Lhs, typename Rhs, typename E>
inline assertion_result
bitwise_compare(Lhs const& lhs, Rhs const& rhs, E const& expr )
{
assertion_result pr( true );
std::size_t left_bit_size = sizeof(Lhs)*CHAR_BIT;
std::size_t right_bit_size = sizeof(Rhs)*CHAR_BIT;
static Lhs const leftOne( 1 );
static Rhs 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( (lhs & ( leftOne << counter )) != (rhs & (rightOne << counter)) ) {
if( pr ) {
pr.message() << " [";
expr.report( pr.message().stream() );
pr.message() << "]. Bitwise comparison failed";
pr = false;
}
pr.message() << "\nMismatch at position " << counter;
}
}
if( left_bit_size != right_bit_size ) {
if( pr ) {
pr.message() << " [";
expr.report( pr.message().stream() );
pr.message() << "]. Bitwise comparison failed";
pr = false;
}
pr.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
}
return pr;
}
//____________________________________________________________________________//
//! Returns an assertion_result using the bitwise comparison out of an expression
//!
//! This is used as a modifer of the normal operator<< on expressions to use the
//! bitwise comparison.
//!
//! @note Available only for compilers supporting the @c auto declaration.
template<typename T1, typename T2, typename T3, typename T4>
inline assertion_result
operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,assertion::op::EQ<T3,T4> > > const& ae, bitwise )
{
return bitwise_compare( ae.m_e.lhs().value(), ae.m_e.rhs(), ae.m_e );
}
//____________________________________________________________________________//
inline check_type
operator<<( assertion_type const& , bitwise )
{
return CHECK_BUILT_ASSERTION;
}
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_DETAIL_BITWISE_MANIP_HPP_012705GER

View File

@@ -0,0 +1,70 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : toolbox implementation details
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_EXPRESSION_HOLDER_HPP_012705GER
#define BOOST_TEST_TOOLS_DETAIL_EXPRESSION_HOLDER_HPP_012705GER
#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** tt_detail::expression_holder ************** //
// ************************************************************************** //
class expression_holder {
public:
virtual ~expression_holder() {}
virtual assertion_result evaluate( bool no_message = false ) const = 0;
};
//____________________________________________________________________________//
template<typename E>
class expression_holder_t: public expression_holder {
public:
explicit expression_holder_t( E const& e ) : m_expr( e ) {}
private:
virtual assertion_result evaluate( bool no_message = false ) const { return m_expr.evaluate( no_message ); }
E m_expr;
};
//____________________________________________________________________________//
template<typename E>
expression_holder_t<E>
hold_expression( E const& e )
{
return expression_holder_t<E>( e );
}
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif
#endif // BOOST_TEST_TOOLS_DETAIL_EXPRESSION_HOLDER_HPP_012705GER

View File

@@ -0,0 +1,121 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : toolbox implementation types and forward declarations
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_FWD_HPP_012705GER
#define BOOST_TEST_TOOLS_DETAIL_FWD_HPP_012705GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/basic_cstring/io.hpp>
// STL
#include <cstddef> // for std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
class lazy_ostream;
} // namespace unit_test
namespace test_tools {
using unit_test::const_string;
class assertion_result;
//____________________________________________________________________________//
namespace tt_detail {
inline bool dummy_cond() { return false; }
// ************************************************************************** //
// ************** types of supported assertions ************** //
// ************************************************************************** //
//____________________________________________________________________________//
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,
CHECK_BUILT_ASSERTION
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** levels of supported assertions ************** //
// ************************************************************************** //
enum tool_level {
WARN, CHECK, REQUIRE, PASS
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** Tools offline implementation ************** //
// ************************************************************************** //
BOOST_TEST_DECL bool
report_assertion( assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
const_string file_name, std::size_t line_num,
tool_level tl, check_type ct,
std::size_t num_args, ... );
//____________________________________________________________________________//
BOOST_TEST_DECL assertion_result
format_assertion_result( const_string expr_val, const_string details );
//____________________________________________________________________________//
BOOST_TEST_DECL assertion_result
format_fpc_report( const_string expr_val, const_string details );
//____________________________________________________________________________//
BOOST_TEST_DECL bool
is_defined_impl( const_string symbol_name, const_string symbol_value );
//____________________________________________________________________________//
BOOST_TEST_DECL assertion_result
equal_impl( char const* left, char const* right );
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_DETAIL_FWD_HPP_012705GER

View File

@@ -0,0 +1,94 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : inidiration interfaces to support manipulators and message output
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_INDIRECTIONS_HPP_112812GER
#define BOOST_TEST_TOOLS_DETAIL_INDIRECTIONS_HPP_112812GER
// Boost.Test
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** assertion_evaluate indirection ************** //
// ************************************************************************** //
template<typename E>
struct assertion_evaluate_t {
assertion_evaluate_t( E const& e ) : m_e( e ) {}
operator assertion_result() { return m_e.evaluate( true ); }
E const& m_e;
};
//____________________________________________________________________________//
template<typename E>
inline assertion_evaluate_t<E>
assertion_evaluate( E const& e ) { return assertion_evaluate_t<E>( e ); }
//____________________________________________________________________________//
template<typename E, typename T>
inline assertion_evaluate_t<E>
operator<<( assertion_evaluate_t<E> const& ae, T const& ) { return ae; }
//____________________________________________________________________________//
// ************************************************************************** //
// ************** assertion_text indirection ************** //
// ************************************************************************** //
template<typename T>
inline unit_test::lazy_ostream const&
assertion_text( unit_test::lazy_ostream const& /*et*/, T const& m ) { return m; }
//____________________________________________________________________________//
inline unit_test::lazy_ostream const&
assertion_text( unit_test::lazy_ostream const& et, int ) { return et; }
//____________________________________________________________________________//
// ************************************************************************** //
// ************** assertion_evaluate indirection ************** //
// ************************************************************************** //
struct assertion_type {
operator check_type() { return CHECK_MSG; }
};
//____________________________________________________________________________//
template<typename T>
inline assertion_type
operator<<( assertion_type const& at, T const& ) { return at; }
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_DETAIL_INDIRECTIONS_HPP_112812GER

View File

@@ -0,0 +1,74 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : support for backward compatible collection comparison interface
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_IT_PAIR_HPP_112812GER
#define BOOST_TEST_TOOLS_DETAIL_IT_PAIR_HPP_112812GER
#ifdef BOOST_TEST_NO_OLD_TOOLS
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** backward compatibility support ************** //
// ************************************************************************** //
template<typename It>
struct it_pair {
typedef It const_iterator;
typedef typename std::iterator_traits<It>::value_type value_type;
it_pair( It const& b, It const& e ) : m_begin( b ), m_size( 0 )
{
It tmp = b;
while( tmp != e ) { ++m_size; ++tmp; }
}
It begin() const { return m_begin; }
It end() const { return m_begin + m_size; }
size_t size() const { return m_size; }
private:
It m_begin;
size_t m_size;
};
//____________________________________________________________________________//
template<typename It>
it_pair<It>
make_it_pair( It const& b, It const& e ) { return it_pair<It>( b, e ); }
//____________________________________________________________________________//
template<typename T>
it_pair<T const*>
make_it_pair( T const* b, T const* e ) { return it_pair<T const*>( b, e ); }
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_NO_OLD_TOOLS
#endif // BOOST_TEST_TOOLS_DETAIL_IT_PAIR_HPP_112812GER

View File

@@ -0,0 +1,69 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! Lexicographic comparison manipulator implementation
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_LEXICOGRAPHIC_MANIP_HPP_050815GER
#define BOOST_TEST_TOOLS_DETAIL_LEXICOGRAPHIC_MANIP_HPP_050815GER
// Boost Test
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/indirections.hpp>
#include <boost/test/tools/assertion.hpp>
#include <boost/test/tools/collection_comparison_op.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
// ************************************************************************** //
// ************** per element comparison manipulator ************** //
// ************************************************************************** //
//! Lexicographic comparison manipulator, for containers
struct lexicographic {};
//____________________________________________________________________________//
inline int
operator<<( unit_test::lazy_ostream const&, lexicographic ) { return 0; }
//____________________________________________________________________________//
namespace tt_detail {
template<typename T1, typename T2, typename OP>
inline assertion_result
operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,OP> > const& ae, lexicographic )
{
typedef typename OP::elem_op elem_op;
return assertion::op::lexicographic_compare<elem_op>( ae.m_e.lhs().value(), ae.m_e.rhs() );
}
//____________________________________________________________________________//
inline check_type
operator<<( assertion_type const&, lexicographic )
{
return CHECK_BUILT_ASSERTION;
}
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_DETAIL_LEXICOGRAPHIC_MANIP_HPP_050815GER

View File

@@ -0,0 +1,69 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! Per element comparison manipulator implementation
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_PER_ELEMENT_MANIP_HPP_050815GER
#define BOOST_TEST_TOOLS_DETAIL_PER_ELEMENT_MANIP_HPP_050815GER
// Boost Test
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/indirections.hpp>
#include <boost/test/tools/assertion.hpp>
#include <boost/test/tools/collection_comparison_op.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
// ************************************************************************** //
// ************** per element comparison manipulator ************** //
// ************************************************************************** //
//! Per element comparison manipulator, for containers
struct per_element {};
//____________________________________________________________________________//
inline int
operator<<( unit_test::lazy_ostream const&, per_element ) { return 0; }
//____________________________________________________________________________//
namespace tt_detail {
template<typename T1, typename T2, typename OP>
inline assertion_result
operator<<(assertion_evaluate_t<assertion::binary_expr<T1,T2,OP> > const& ae, per_element )
{
typedef typename OP::elem_op elem_op;
return assertion::op::element_compare<elem_op>( ae.m_e.lhs().value(), ae.m_e.rhs() );
}
//____________________________________________________________________________//
inline check_type
operator<<( assertion_type const&, per_element )
{
return CHECK_BUILT_ASSERTION;
}
//____________________________________________________________________________//
} // namespace tt_detail
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_DETAIL_PER_ELEMENT_MANIP_HPP_050815GER

View File

@@ -0,0 +1,205 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : defines level of indiration facilitating workarounds for non printable types
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER
#define BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/workaround.hpp>
// Boost
#include <boost/mpl/or.hpp>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/is_function.hpp>
#include <boost/type_traits/is_abstract.hpp>
#include <boost/type_traits/has_left_shift.hpp>
#include <limits>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** print_log_value ************** //
// ************************************************************************** //
template<typename T>
struct print_log_value {
BOOST_STATIC_ASSERT_MSG( (boost::has_left_shift<std::ostream,T>::value),
"Type has to implement operator<< to be printable");
void operator()( std::ostream& ostr, T const& t )
{
typedef typename mpl::or_<is_array<T>,is_function<T>,is_abstract<T> >::type cant_use_nl;
std::streamsize old_precision = set_precision( ostr, cant_use_nl() );
ostr << t;
if( old_precision != (std::streamsize)-1 )
ostr.precision( old_precision );
}
std::streamsize set_precision( std::ostream& ostr, mpl::false_ )
{
if( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 2 )
return ostr.precision( 2 + std::numeric_limits<T>::digits * 301/1000 );
else if ( std::numeric_limits<T>::is_specialized && std::numeric_limits<T>::radix == 10 ) {
#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
// (was BOOST_NO_NUMERIC_LIMITS_LOWEST but now deprecated).
// No support for std::numeric_limits<double>::max_digits10,
// so guess that a couple of guard digits more than digits10 will display any difference.
return ostr.precision( 2 + std::numeric_limits<T>::digits10 );
#else
// std::numeric_limits<double>::max_digits10; IS supported.
// Any noisy or guard digits needed to display any difference are included in max_digits10.
return ostr.precision( std::numeric_limits<T>::max_digits10 );
#endif
}
// else if T is not specialized for std::numeric_limits<>,
// then will just get the default precision of 6 digits.
return (std::streamsize)-1;
}
std::streamsize set_precision( std::ostream&, mpl::true_ ) { return (std::streamsize)-1; }
};
//____________________________________________________________________________//
#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 );
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** 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;
}
//____________________________________________________________________________//
} // namespace tt_detail
// ************************************************************************** //
// ************** BOOST_TEST_DONT_PRINT_LOG_VALUE ************** //
// ************************************************************************** //
#define BOOST_TEST_DONT_PRINT_LOG_VALUE( the_type ) \
namespace boost{ namespace test_tools{ namespace tt_detail{ \
template<> \
struct print_log_value<the_type > { \
void operator()( std::ostream&, the_type const& ) {} \
}; \
}}} \
/**/
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_IMPL_COMMON_HPP_012705GER

View File

@@ -0,0 +1,130 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! @brief Floating point comparison tolerance manipulators
//!
//! This file defines several manipulators for floating point comparison. These
//! manipulators are intended to be used with BOOST_TEST.
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
#define BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER
// Boost Test
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/indirections.hpp>
#include <boost/test/tools/fpc_tolerance.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** fpc tolerance manipulator ************** //
// ************************************************************************** //
template<typename FPT>
struct tolerance_manip {
explicit tolerance_manip( FPT const & tol ) : m_value( tol ) {}
FPT m_value;
};
//____________________________________________________________________________//
struct tolerance_manip_delay {};
template<typename FPT>
inline tolerance_manip<FPT>
operator%( FPT v, tolerance_manip_delay const& )
{
BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
"tolerance should be specified using a floating points type" );
return tolerance_manip<FPT>( FPT(v / 100) );
}
//____________________________________________________________________________//
template<typename E, typename FPT>
inline assertion_result
operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
{
local_fpc_tolerance<FPT> lt( tol.m_value );
return ae.m_e.evaluate();
}
//____________________________________________________________________________//
template<typename FPT>
inline int
operator<<( unit_test::lazy_ostream const&, tolerance_manip<FPT> const& ) { return 0; }
//____________________________________________________________________________//
template<typename FPT>
inline check_type
operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& ) { return CHECK_BUILT_ASSERTION; }
//____________________________________________________________________________//
} // namespace tt_detail
/*! Tolerance manipulator
*
* These functions return a manipulator that can be used in conjunction with BOOST_TEST
* in order to specify the tolerance with which floating point comparisons are made.
*/
template<typename FPT>
inline tt_detail::tolerance_manip<FPT>
tolerance( FPT v )
{
BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
"tolerance only for floating points" );
return tt_detail::tolerance_manip<FPT>( v );
}
//____________________________________________________________________________//
//! @overload tolerance( FPT v )
template<typename FPT>
inline tt_detail::tolerance_manip<FPT>
tolerance( fpc::percent_tolerance_t<FPT> v )
{
BOOST_STATIC_ASSERT_MSG( (fpc::tolerance_based<FPT>::value),
"tolerance only for floating points" );
return tt_detail::tolerance_manip<FPT>( static_cast<FPT>(v.m_value / 100) );
}
//____________________________________________________________________________//
//! @overload tolerance( FPT v )
inline tt_detail::tolerance_manip_delay
tolerance()
{
return tt_detail::tolerance_manip_delay();
}
//____________________________________________________________________________//
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_DETAIL_TOLERANCE_MANIP_HPP_012705GER

View File

@@ -0,0 +1,315 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief algorithms for comparing floating point values
// ***************************************************************************
#ifndef BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
#define BOOST_TEST_FLOATING_POINT_COMPARISON_HPP_071894GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/tools/assertion_result.hpp>
// Boost
#include <boost/limits.hpp> // for std::numeric_limits
#include <boost/static_assert.hpp>
#include <boost/assert.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/conditional.hpp>
#include <boost/utility/enable_if.hpp>
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace math {
namespace fpc {
// ************************************************************************** //
// ************** fpc::tolerance_based ************** //
// ************************************************************************** //
//! @internal
//! Protects the instanciation of std::numeric_limits from non-supported types (eg. T=array)
template <typename T, bool enabled>
struct tolerance_based_delegate;
template <typename T>
struct tolerance_based_delegate<T, false> : mpl::false_ {};
template <typename T>
struct tolerance_based_delegate<T, true>
: mpl::bool_<
is_floating_point<T>::value ||
(!std::numeric_limits<T>::is_integer && std::numeric_limits<T>::is_specialized && !std::numeric_limits<T>::is_exact)>
{};
/*!@brief Indicates if a type can be compared using a tolerance scheme
*
* This is a metafunction that should evaluate to @c mpl::true_ if the type
* @c T can be compared using a tolerance based method, typically for floating point
* types.
*
* This metafunction can be specialized further to declare user types that are
* floating point (eg. boost.multiprecision).
*/
template <typename T>
struct tolerance_based : tolerance_based_delegate<T, !is_array<T>::value >::type {};
// ************************************************************************** //
// ************** fpc::strength ************** //
// ************************************************************************** //
//! Method for comparing floating point numbers
enum strength {
FPC_STRONG, //!< "Very close" - equation 2' in docs, the default
FPC_WEAK //!< "Close enough" - equation 3' in docs.
};
// ************************************************************************** //
// ************** tolerance presentation types ************** //
// ************************************************************************** //
template<typename FPT>
struct percent_tolerance_t {
explicit percent_tolerance_t( FPT v ) : m_value( v ) {}
FPT m_value;
};
//____________________________________________________________________________//
template<typename FPT>
inline std::ostream& operator<<( std::ostream& 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 );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** details ************** //
// ************************************************************************** //
namespace fpc_detail {
// FPT is Floating-Point Type: float, double, long double or User-Defined.
template<typename FPT>
inline FPT
fpt_abs( FPT fpv )
{
return fpv < static_cast<FPT>(0) ? -fpv : fpv;
}
//____________________________________________________________________________//
template<typename FPT>
struct fpt_specialized_limits
{
static FPT min_value() { return (std::numeric_limits<FPT>::min)(); }
static FPT max_value() { return (std::numeric_limits<FPT>::max)(); }
};
template<typename FPT>
struct fpt_non_specialized_limits
{
static FPT min_value() { return static_cast<FPT>(0); }
static FPT max_value() { return static_cast<FPT>(1000000); } // for our purposes it doesn't really matter what value is returned here
};
template<typename FPT>
struct fpt_limits : boost::conditional<std::numeric_limits<FPT>::is_specialized,
fpt_specialized_limits<FPT>,
fpt_non_specialized_limits<FPT>
>::type
{};
//____________________________________________________________________________//
// 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;
}
//____________________________________________________________________________//
template<typename FPT, typename ToleranceType>
inline FPT
fraction_tolerance( ToleranceType tolerance )
{
return static_cast<FPT>(tolerance);
}
//____________________________________________________________________________//
template<typename FPT2, typename FPT>
inline FPT2
fraction_tolerance( percent_tolerance_t<FPT> tolerance )
{
return FPT2(tolerance.m_value)*FPT2(0.01);
}
//____________________________________________________________________________//
} // namespace fpc_detail
// ************************************************************************** //
// ************** close_at_tolerance ************** //
// ************************************************************************** //
/*!@brief Predicate for comparing floating point numbers
*
* This predicate is used to compare floating point numbers. In addition the comparison produces maximum
* related differnce, which can be used to generate detailed error message
* The methods for comparing floating points are detailed in the documentation. The method is chosen
* by the @ref boost::math::fpc::strength given at construction.
*/
template<typename FPT>
class close_at_tolerance {
public:
// Public typedefs
typedef bool result_type;
// Constructor
template<typename ToleranceType>
explicit close_at_tolerance( ToleranceType tolerance, fpc::strength fpc_strength = FPC_STRONG )
: m_fraction_tolerance( fpc_detail::fraction_tolerance<FPT>( tolerance ) )
, m_strength( fpc_strength )
, m_tested_rel_diff( 0 )
{
BOOST_ASSERT_MSG( m_fraction_tolerance >= FPT(0), "tolerance must not be negative!" ); // no reason for tolerance to be negative
}
// Access methods
//! Returns the tolerance
FPT fraction_tolerance() const { return m_fraction_tolerance; }
//! Returns the comparison method
fpc::strength strength() const { return m_strength; }
//! Returns the failing fraction
FPT tested_rel_diff() const { return m_tested_rel_diff; }
/*! Compares two floating point numbers a and b such that their "left" relative difference |a-b|/a and/or
* "right" relative difference |a-b|/b does not exceed specified relative (fraction) tolerance.
*
* @param[in] left first floating point number to be compared
* @param[in] right second floating point number to be compared
*
* What is reported by @c tested_rel_diff in case of failure depends on the comparison method:
* - for @c FPC_STRONG: the max of the two fractions
* - for @c FPC_WEAK: the min of the two fractions
* The rationale behind is to report the tolerance to set in order to make a test pass.
*/
bool operator()( FPT left, FPT right ) const
{
FPT diff = fpc_detail::fpt_abs<FPT>( left - right );
FPT fraction_of_right = fpc_detail::safe_fpt_division( diff, fpc_detail::fpt_abs( right ) );
FPT fraction_of_left = fpc_detail::safe_fpt_division( diff, fpc_detail::fpt_abs( left ) );
FPT max_rel_diff = (std::max)( fraction_of_left, fraction_of_right );
FPT min_rel_diff = (std::min)( fraction_of_left, fraction_of_right );
m_tested_rel_diff = m_strength == FPC_STRONG ? max_rel_diff : min_rel_diff;
return m_tested_rel_diff <= m_fraction_tolerance;
}
private:
// Data members
FPT m_fraction_tolerance;
fpc::strength m_strength;
mutable FPT m_tested_rel_diff;
};
// ************************************************************************** //
// ************** small_with_tolerance ************** //
// ************************************************************************** //
/*!@brief Predicate for comparing floating point numbers against 0
*
* Serves the same purpose as boost::math::fpc::close_at_tolerance, but used when one
* of the operand is null.
*/
template<typename FPT>
class small_with_tolerance {
public:
// Public typedefs
typedef bool result_type;
// Constructor
explicit small_with_tolerance( FPT tolerance ) // <= absolute tolerance
: m_tolerance( tolerance )
{
BOOST_ASSERT( m_tolerance >= FPT(0) ); // no reason for the tolerance to be negative
}
// Action method
bool operator()( FPT fpv ) const
{
return fpc::fpc_detail::fpt_abs( fpv ) <= m_tolerance;
}
private:
// Data members
FPT m_tolerance;
};
// ************************************************************************** //
// ************** is_small ************** //
// ************************************************************************** //
template<typename FPT>
inline bool
is_small( FPT fpv, FPT tolerance )
{
return small_with_tolerance<FPT>( tolerance )( fpv );
}
//____________________________________________________________________________//
} // namespace fpc
} // namespace math
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_FLOATING_POINT_COMAPARISON_HPP_071894GER

View File

@@ -0,0 +1,224 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief Floating point comparison with enhanced reporting
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
#define BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
// Boost.Test
#include <boost/test/tools/assertion.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>
#include <boost/test/tools/fpc_tolerance.hpp>
// Boost
#include <boost/type_traits/common_type.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace assertion {
namespace op {
// ************************************************************************** //
// ************** fpctraits ************** //
// ************************************************************************** //
// set of floating point comparison traits per comparison OP
template<typename OP>
struct fpctraits {
static const bool cmp_direct = true;
};
template <typename Lhs, typename Rhs>
struct fpctraits<op::NE<Lhs,Rhs> > {
static const bool cmp_direct = false;
};
template <typename Lhs, typename Rhs>
struct fpctraits<op::LT<Lhs,Rhs> > {
static const bool cmp_direct = false;
};
template <typename Lhs, typename Rhs>
struct fpctraits<op::GT<Lhs,Rhs> > {
static const bool cmp_direct = false;
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** set of overloads to select correct fpc algo ************** //
// ************************************************************************** //
// we really only care about EQ vs NE. All other comparisons use direct first
// and then need EQ. For example a < b (tolerance t) IFF a < b OR a == b (tolerance t)
template <typename FPT, typename Lhs, typename Rhs, typename OP>
inline assertion_result
compare_fpv( Lhs const& lhs, Rhs const& rhs, OP* )
{
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_STRONG );
assertion_result ar( P( lhs, rhs ) );
if( !ar )
ar.message() << "Relative difference exceeds tolerance ["
<< P.tested_rel_diff() << " > " << P.fraction_tolerance() << ']';
return ar;
}
//____________________________________________________________________________//
template <typename FPT, typename OP>
inline assertion_result
compare_fpv_near_zero( FPT const& fpv, OP* )
{
fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
assertion_result ar( P( fpv ) );
if( !ar )
ar.message() << "Absolute value exceeds tolerance [|" << fpv << "| > "<< fpc_tolerance<FPT>() << ']';
return ar;
}
//____________________________________________________________________________//
template <typename FPT, typename Lhs, typename Rhs>
inline assertion_result
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
{
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_WEAK );
assertion_result ar( !P( lhs, rhs ) );
if( !ar )
ar.message() << "Relative difference is within tolerance ["
<< P.tested_rel_diff() << " < " << fpc_tolerance<FPT>() << ']';
return ar;
}
//____________________________________________________________________________//
template <typename FPT, typename Lhs, typename Rhs>
inline assertion_result
compare_fpv_near_zero( FPT const& fpv, op::NE<Lhs,Rhs>* )
{
fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
assertion_result ar( !P( fpv ) );
if( !ar )
ar.message() << "Absolute value is within tolerance [|" << fpv << "| < "<< fpc_tolerance<FPT>() << ']';
return ar;
}
//____________________________________________________________________________//
template <typename FPT, typename Lhs, typename Rhs>
inline assertion_result
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::LT<Lhs,Rhs>* )
{
return lhs >= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
}
template <typename FPT, typename Lhs, typename Rhs>
inline assertion_result
compare_fpv_near_zero( FPT const& fpv, op::LT<Lhs,Rhs>* )
{
return fpv >= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
}
//____________________________________________________________________________//
template <typename FPT, typename Lhs, typename Rhs>
inline assertion_result
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::GT<Lhs,Rhs>* )
{
return lhs <= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
}
template <typename FPT, typename Lhs, typename Rhs>
inline assertion_result
compare_fpv_near_zero( FPT const& fpv, op::GT<Lhs,Rhs>* )
{
return fpv <= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
}
//____________________________________________________________________________//
#define DEFINE_FPV_COMPARISON( oper, name, rev ) \
template<typename Lhs,typename Rhs> \
struct name<Lhs,Rhs,typename boost::enable_if_c< \
(fpc::tolerance_based<Lhs>::value && \
fpc::tolerance_based<Rhs>::value)>::type> { \
public: \
typedef typename common_type<Lhs,Rhs>::type FPT; \
typedef name<Lhs,Rhs> OP; \
\
typedef assertion_result result_type; \
\
static bool \
eval_direct( Lhs const& lhs, Rhs const& rhs ) \
{ \
return lhs oper rhs; \
} \
\
static assertion_result \
eval( Lhs const& lhs, Rhs const& rhs ) \
{ \
if( lhs == 0 ) \
return compare_fpv_near_zero( rhs, (OP*)0 ); \
\
if( rhs == 0 ) \
return compare_fpv_near_zero( lhs, (OP*)0 ); \
\
bool direct_res = eval_direct( lhs, rhs ); \
\
if( (direct_res && fpctraits<OP>::cmp_direct) || \
fpc_tolerance<FPT>() == FPT(0) ) \
return direct_res; \
\
return compare_fpv<FPT>( lhs, rhs, (OP*)0 ); \
} \
\
template<typename PrevExprType> \
static void \
report( std::ostream& ostr, \
PrevExprType const& lhs, \
Rhs const& rhs ) \
{ \
lhs.report( ostr ); \
ostr << revert() \
<< tt_detail::print_helper( rhs ); \
} \
\
static char const* revert() \
{ return " " #rev " "; } \
}; \
/**/
BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_FPV_COMPARISON )
#undef DEFINE_FPV_COMPARISON
//____________________________________________________________________________//
} // namespace op
} // namespace assertion
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER

View File

@@ -0,0 +1,103 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : FPC tools tolerance holder
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_FPC_TOLERANCE_HPP_121612GER
#define BOOST_TEST_TOOLS_FPC_TOLERANCE_HPP_121612GER
// Boost Test
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace fpc = math::fpc;
// ************************************************************************** //
// ************** floating point comparison tolerance ************** //
// ************************************************************************** //
template<typename FPT>
inline FPT&
fpc_tolerance()
{
static FPT s_value = 0;
return s_value;
}
//____________________________________________________________________________//
template<typename FPT>
struct local_fpc_tolerance {
local_fpc_tolerance( FPT fraction_tolerance ) : m_old_tolerance( fpc_tolerance<FPT>() )
{
fpc_tolerance<FPT>() = fraction_tolerance;
}
~local_fpc_tolerance()
{
if( m_old_tolerance != (FPT)-1 )
fpc_tolerance<FPT>() = m_old_tolerance;
}
private:
// Data members
FPT m_old_tolerance;
};
//____________________________________________________________________________//
} // namespace test_tools
// ************************************************************************** //
// ************** decorator::tolerance ************** //
// ************************************************************************** //
namespace unit_test {
namespace decorator {
template<typename FPT>
inline fixture_t
tolerance( FPT v )
{
return fixture_t( test_unit_fixture_ptr(
new unit_test::class_based_fixture<test_tools::local_fpc_tolerance<FPT>,FPT>( v ) ) );
}
//____________________________________________________________________________//
template<typename FPT>
inline fixture_t
tolerance( test_tools::fpc::percent_tolerance_t<FPT> v )
{
return fixture_t( test_unit_fixture_ptr(
new unit_test::class_based_fixture<test_tools::local_fpc_tolerance<FPT>,FPT>( boost::math::fpc::fpc_detail::fraction_tolerance<FPT>( v ) ) ) );
}
//____________________________________________________________________________//
} // namespace decorator
using decorator::tolerance;
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_FPC_TOLERANCE_HPP_121612GER

View File

@@ -0,0 +1,369 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 81247 $
//
// Description : contains definition for all test tools in test toolbox
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_INTERFACE_HPP_111712GER
#define BOOST_TEST_TOOLS_INTERFACE_HPP_111712GER
// Boost.Test
#include <boost/test/unit_test_log.hpp>
#ifdef BOOST_TEST_TOOLS_DEBUGGABLE
#include <boost/test/debug.hpp>
#endif
#ifdef BOOST_NO_CXX11_AUTO_DECLARATIONS
#include <boost/test/tools/detail/expression_holder.hpp>
#endif
#include <boost/test/detail/pp_variadic.hpp>
#ifdef BOOST_TEST_NO_OLD_TOOLS
#include <boost/preprocessor/seq/to_tuple.hpp>
#include <iterator>
#endif // BOOST_TEST_NO_OLD_TOOLS
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** BOOST_TEST_<level> ************** //
// ************************************************************************** //
#define BOOST_TEST_BUILD_ASSERTION( P ) \
(::boost::test_tools::assertion::seed()->*P) \
/**/
//____________________________________________________________________________//
// Implementation based on direct predicate evaluation
#define BOOST_TEST_TOOL_DIRECT_IMPL( P, level, M ) \
do { \
::boost::test_tools::assertion_result res = (P); \
report_assertion( \
res, \
BOOST_TEST_LAZY_MSG( M ), \
BOOST_TEST_L(__FILE__), \
static_cast<std::size_t>(__LINE__), \
::boost::test_tools::tt_detail::level, \
::boost::test_tools::tt_detail::CHECK_MSG, \
0 ); \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
//____________________________________________________________________________//
// Implementation based on expression template construction
#define BOOST_TEST_TOOL_ET_IMPL( P, level ) \
do { \
BOOST_TEST_PASSPOINT(); \
\
::boost::test_tools::tt_detail:: \
report_assertion( \
BOOST_TEST_BUILD_ASSERTION( P ).evaluate(), \
BOOST_TEST_LAZY_MSG( BOOST_TEST_STRINGIZE( P ) ), \
BOOST_TEST_L(__FILE__), \
static_cast<std::size_t>(__LINE__), \
::boost::test_tools::tt_detail::level, \
::boost::test_tools::tt_detail::CHECK_BUILT_ASSERTION, \
0 ); \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
//____________________________________________________________________________//
// Implementation based on expression template construction with extra tool arguments
#define BOOST_TEST_TOOL_ET_IMPL_EX( P, level, arg ) \
do { \
BOOST_TEST_PASSPOINT(); \
\
::boost::test_tools::tt_detail:: \
report_assertion( \
::boost::test_tools::tt_detail::assertion_evaluate( \
BOOST_TEST_BUILD_ASSERTION( P ) ) \
<< arg, \
::boost::test_tools::tt_detail::assertion_text( \
BOOST_TEST_LAZY_MSG( BOOST_TEST_STRINGIZE(P) ), \
BOOST_TEST_LAZY_MSG( arg ) ), \
BOOST_TEST_L(__FILE__), \
static_cast<std::size_t>(__LINE__), \
::boost::test_tools::tt_detail::level, \
::boost::test_tools::tt_detail::assertion_type() \
<< arg, \
0 ); \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
//____________________________________________________________________________//
#ifdef BOOST_TEST_TOOLS_UNDER_DEBUGGER
#define BOOST_TEST_TOOL_UNIV( level, P ) \
BOOST_TEST_TOOL_DIRECT_IMPL( P, level, BOOST_TEST_STRINGIZE( P ) ) \
/**/
#define BOOST_TEST_TOOL_UNIV_EX( level, P, ... ) \
BOOST_TEST_TOOL_UNIV( level, P ) \
/**/
#elif defined(BOOST_TEST_TOOLS_DEBUGGABLE)
#define BOOST_TEST_TOOL_UNIV( level, P ) \
do { \
if( ::boost::debug::under_debugger() ) \
BOOST_TEST_TOOL_DIRECT_IMPL( P, level, BOOST_TEST_STRINGIZE( P ) ); \
else \
BOOST_TEST_TOOL_ET_IMPL( P, level ); \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
#define BOOST_TEST_TOOL_UNIV_EX( level, P, ... ) \
BOOST_TEST_TOOL_UNIV( level, P ) \
/**/
#else
#define BOOST_TEST_TOOL_UNIV( level, P ) \
BOOST_TEST_TOOL_ET_IMPL( P, level ) \
/**/
#define BOOST_TEST_TOOL_UNIV_EX( level, P, ... ) \
BOOST_TEST_TOOL_ET_IMPL_EX( P, level, __VA_ARGS__ ) \
/**/
#endif
//____________________________________________________________________________//
#define BOOST_TEST_WARN( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, WARN, __VA_ARGS__ ) \
/**/
#define BOOST_TEST_CHECK( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, CHECK, __VA_ARGS__ ) \
/**/
#define BOOST_TEST_REQUIRE( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, REQUIRE, __VA_ARGS__ )\
/**/
#define BOOST_TEST( ... ) BOOST_TEST_INVOKE_IF_N_ARGS( \
2, BOOST_TEST_TOOL_UNIV, BOOST_TEST_TOOL_UNIV_EX, CHECK, __VA_ARGS__ ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_ERROR( M ) BOOST_CHECK_MESSAGE( false, M )
#define BOOST_TEST_FAIL( M ) BOOST_REQUIRE_MESSAGE( false, M )
//____________________________________________________________________________//
#define BOOST_TEST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( symb, BOOST_STRINGIZE(= symb) )
//____________________________________________________________________________//
#ifdef BOOST_TEST_NO_OLD_TOOLS
#ifdef BOOST_TEST_TOOLS_UNDER_DEBUGGER
#define BOOST_CHECK_THROW_IMPL(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)\
do { try { \
S; \
BOOST_TEST_TOOL_DIRECT_IMPL( Ppassed, TL, Mpassed ); \
} catch( E ) { \
BOOST_TEST_TOOL_DIRECT_IMPL( Pcaught, TL, Mcaught ); \
}} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
#elif defined(BOOST_TEST_TOOLS_DEBUGGABLE)
#define BOOST_CHECK_THROW_IMPL(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)\
do { try { \
if( ::boost::debug::under_debugger() ) \
BOOST_TEST_PASSPOINT(); \
S; \
BOOST_TEST_TOOL_DIRECT_IMPL( Ppassed, TL, Mpassed ); \
} catch( E ) { \
BOOST_TEST_TOOL_DIRECT_IMPL( Pcaught, TL, Mcaught ); \
}} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
#else
#define BOOST_CHECK_THROW_IMPL(S, E, TL, Ppassed, Mpassed, Pcaught, Mcaught)\
do { try { \
BOOST_TEST_PASSPOINT(); \
S; \
BOOST_TEST_TOOL_DIRECT_IMPL( Ppassed, TL, Mpassed ); \
} catch( E ) { \
BOOST_TEST_TOOL_DIRECT_IMPL( Pcaught, TL, Mcaught ); \
}} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
#endif
//____________________________________________________________________________//
#define BOOST_WARN_THROW( S, E ) \
BOOST_CHECK_THROW_IMPL(S, E const&, WARN, \
false, "exception " BOOST_STRINGIZE(E) " is expected", \
true , "exception " BOOST_STRINGIZE(E) " is caught" ) \
/**/
#define BOOST_CHECK_THROW( S, E ) \
BOOST_CHECK_THROW_IMPL(S, E const&, CHECK, \
false, "exception " BOOST_STRINGIZE(E) " is expected", \
true , "exception " BOOST_STRINGIZE(E) " is caught" ) \
/**/
#define BOOST_REQUIRE_THROW( S, E ) \
BOOST_CHECK_THROW_IMPL(S, E const&, REQUIRE, \
false, "exception " BOOST_STRINGIZE(E) " is expected", \
true , "exception " BOOST_STRINGIZE(E) " is caught" ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_EXCEPTION( S, E, P ) \
BOOST_CHECK_THROW_IMPL(S, E const& ex, WARN, \
false, "exception " BOOST_STRINGIZE(E) " is expected", \
P(ex), "incorrect exception " BOOST_STRINGIZE(E) " is caught" ) \
/**/
#define BOOST_CHECK_EXCEPTION( S, E, P ) \
BOOST_CHECK_THROW_IMPL(S, E const& ex, CHECK, \
false, "exception " BOOST_STRINGIZE(E) " is expected", \
P(ex), "incorrect exception " BOOST_STRINGIZE(E) " is caught" ) \
/**/
#define BOOST_REQUIRE_EXCEPTION( S, E, P ) \
BOOST_CHECK_THROW_IMPL(S, E const& ex, REQUIRE, \
false, "exception " BOOST_STRINGIZE(E) " is expected", \
P(ex), "incorrect exception " BOOST_STRINGIZE(E) " is caught" ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_NO_THROW( S ) \
BOOST_CHECK_THROW_IMPL(S, ..., WARN, \
true , "no exceptions thrown by " BOOST_STRINGIZE( S ), \
false, "exception thrown by " BOOST_STRINGIZE( S ) ) \
/**/
#define BOOST_CHECK_NO_THROW( S ) \
BOOST_CHECK_THROW_IMPL(S, ..., CHECK, \
true , "no exceptions thrown by " BOOST_STRINGIZE( S ), \
false, "exception thrown by " BOOST_STRINGIZE( S ) ) \
/**/
#define BOOST_REQUIRE_NO_THROW( S ) \
BOOST_CHECK_THROW_IMPL(S, ..., REQUIRE, \
true , "no exceptions thrown by " BOOST_STRINGIZE( S ), \
false, "exception thrown by " BOOST_STRINGIZE( S ) ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_MESSAGE( P, M ) BOOST_TEST_TOOL_DIRECT_IMPL( P, WARN, M )
#define BOOST_CHECK_MESSAGE( P, M ) BOOST_TEST_TOOL_DIRECT_IMPL( P, CHECK, M )
#define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_TEST_TOOL_DIRECT_IMPL( P, REQUIRE, M )
//____________________________________________________________________________//
////////////////////////////////////////////////////////////////////////////////
///////////////////////////// DEPRECATED TOOLS /////////////////////////////
#define BOOST_WARN( P ) BOOST_TEST_WARN( P )
#define BOOST_CHECK( P ) BOOST_TEST_CHECK( P )
#define BOOST_REQUIRE( P ) BOOST_TEST_REQUIRE( P )
//____________________________________________________________________________//
#define BOOST_ERROR( M ) BOOST_TEST_ERROR( M )
#define BOOST_FAIL( M ) BOOST_TEST_FAIL( M )
//____________________________________________________________________________//
#define BOOST_WARN_EQUAL( L, R ) BOOST_TEST_WARN( L == R )
#define BOOST_CHECK_EQUAL( L, R ) BOOST_TEST_CHECK( L == R )
#define BOOST_REQUIRE_EQUAL( L, R ) BOOST_TEST_REQUIRE( L == R )
#define BOOST_WARN_NE( L, R ) BOOST_TEST_WARN( L != R )
#define BOOST_CHECK_NE( L, R ) BOOST_TEST_CHECK( L != R )
#define BOOST_REQUIRE_NE( L, R ) BOOST_TEST_REQUIRE( L != R )
#define BOOST_WARN_LT( L, R ) BOOST_TEST_WARN( L < R )
#define BOOST_CHECK_LT( L, R ) BOOST_TEST_CHECK( L < R )
#define BOOST_REQUIRE_LT( L, R ) BOOST_TEST_REQUIRE( L < R )
#define BOOST_WARN_LE( L, R ) BOOST_TEST_WARN( L <= R )
#define BOOST_CHECK_LE( L, R ) BOOST_TEST_CHECK( L <= R )
#define BOOST_REQUIRE_LE( L, R ) BOOST_TEST_REQUIRE( L <= R )
#define BOOST_WARN_GT( L, R ) BOOST_TEST_WARN( L > R )
#define BOOST_CHECK_GT( L, R ) BOOST_TEST_CHECK( L > R )
#define BOOST_REQUIRE_GT( L, R ) BOOST_TEST_REQUIRE( L > R )
#define BOOST_WARN_GE( L, R ) BOOST_TEST_WARN( L >= R )
#define BOOST_CHECK_GE( L, R ) BOOST_TEST_CHECK( L >= R )
#define BOOST_REQUIRE_GE( L, R ) BOOST_TEST_REQUIRE( L >= R )
//____________________________________________________________________________//
#define BOOST_WARN_CLOSE( L, R, T ) BOOST_TEST_WARN( L == R, T % ::boost::test_tools::tolerance() )
#define BOOST_CHECK_CLOSE( L, R, T ) BOOST_TEST_CHECK( L == R, T % ::boost::test_tools::tolerance() )
#define BOOST_REQUIRE_CLOSE( L, R, T ) BOOST_TEST_REQUIRE( L == R, T % ::boost::test_tools::tolerance() )
#define BOOST_WARN_CLOSE_FRACTION(L, R, T) BOOST_TEST_WARN( L == R, ::boost::test_tools::tolerance( T ) )
#define BOOST_CHECK_CLOSE_FRACTION(L, R, T) BOOST_TEST_CHECK( L == R, ::boost::test_tools::tolerance( T ) )
#define BOOST_REQUIRE_CLOSE_FRACTION(L,R,T) BOOST_TEST_REQUIRE( L == R, ::boost::test_tools::tolerance( T ) )
#define BOOST_WARN_SMALL( FPV, T ) BOOST_TEST_WARN( FPV == 0., ::boost::test_tools::tolerance( T ) )
#define BOOST_CHECK_SMALL( FPV, T ) BOOST_TEST_CHECK( FPV == 0., ::boost::test_tools::tolerance( T ) )
#define BOOST_REQUIRE_SMALL( FPV, T ) BOOST_TEST_REQUIRE( FPV == 0., ::boost::test_tools::tolerance( T ) )
//____________________________________________________________________________//
#define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_TEST_WARN( ::boost::test_tools::tt_detail::make_it_pair(L_begin, L_end) ==\
::boost::test_tools::tt_detail::make_it_pair(R_begin, R_end), \
::boost::test_tools::per_element() ) \
/**/
#define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_TEST_CHECK( ::boost::test_tools::tt_detail::make_it_pair(L_begin, L_end) ==\
::boost::test_tools::tt_detail::make_it_pair(R_begin, R_end), \
::boost::test_tools::per_element() ) \
/**/
#define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_TEST_REQUIRE( ::boost::test_tools::tt_detail::make_it_pair(L_begin, L_end) ==\
::boost::test_tools::tt_detail::make_it_pair(R_begin, R_end), \
::boost::test_tools::per_element() ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_TEST_WARN( L == R, ::boost::test_tools::bitwise() )
#define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_TEST_CHECK( L == R, ::boost::test_tools::bitwise() )
#define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_TEST_REQUIRE( L == R, ::boost::test_tools::bitwise() )
//____________________________________________________________________________//
#define BOOST_WARN_PREDICATE( P, ARGS ) BOOST_TEST_WARN( P BOOST_PP_SEQ_TO_TUPLE(ARGS) )
#define BOOST_CHECK_PREDICATE( P, ARGS ) BOOST_TEST_CHECK( P BOOST_PP_SEQ_TO_TUPLE(ARGS) )
#define BOOST_REQUIRE_PREDICATE( P, ARGS ) BOOST_TEST_REQUIRE( P BOOST_PP_SEQ_TO_TUPLE(ARGS) )
//____________________________________________________________________________//
#define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
//____________________________________________________________________________//
#endif // BOOST_TEST_NO_OLD_TOOLS
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_INTERFACE_HPP_111712GER

View File

@@ -0,0 +1,358 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74248 $
//
// Description : implementation details for old toolbox
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER
#define BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER
// Boost.Test
#include <boost/test/unit_test_log.hpp>
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/tools/floating_point_comparison.hpp>
#include <boost/test/tools/detail/fwd.hpp>
#include <boost/test/tools/detail/print_helper.hpp>
// Boost
#include <boost/limits.hpp>
#include <boost/numeric/conversion/conversion_traits.hpp> // for numeric::conversion_traits
#include <boost/type_traits/is_array.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/preprocessor/arithmetic/add.hpp>
// STL
#include <cstddef> // for std::size_t
#include <climits> // for CHAR_BIT
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace test_tools {
namespace tt_detail {
// ************************************************************************** //
// ************** old TOOLBOX Implementation ************** //
// ************************************************************************** //
// This function adds level of indirection, but it makes sure we evaluate predicate
// arguments only once
#ifndef BOOST_TEST_PROD
#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 ) \
, &static_cast<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& assertion_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 \
report_assertion( P( BOOST_PP_REPEAT_ ## z(BOOST_PP_ADD(n, 1), PRED_PARAMS,_) ),\
assertion_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
#endif
//____________________________________________________________________________//
template <class Left, class Right>
inline assertion_result equal_impl( Left const& left, Right const& right )
{
return left == right;
}
//____________________________________________________________________________//
inline assertion_result equal_impl( char* left, char const* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
inline assertion_result equal_impl( char const* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
inline assertion_result equal_impl( char* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
#if !defined( BOOST_NO_CWCHAR )
assertion_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
inline assertion_result equal_impl( wchar_t* left, wchar_t const* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
inline assertion_result equal_impl( wchar_t const* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
inline assertion_result equal_impl( wchar_t* left, wchar_t* right ) { return equal_impl( static_cast<wchar_t const*>(left), static_cast<wchar_t const*>(right) ); }
#endif
//____________________________________________________________________________//
struct equal_impl_frwd {
template <typename Left, typename Right>
inline assertion_result
call_impl( Left const& left, Right const& right, mpl::false_ ) const
{
return equal_impl( left, right );
}
template <typename Left, typename Right>
inline assertion_result
call_impl( Left const& left, Right const& right, mpl::true_ ) const
{
return (*this)( right, &left[0] );
}
template <typename Left, typename Right>
inline assertion_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>
assertion_result operator()( Left const& left, Right const& right )
{
return !equal_impl_frwd()( left, right );
}
};
//____________________________________________________________________________//
struct lt_impl {
template <class Left, class Right>
assertion_result operator()( Left const& left, Right const& right )
{
return left < right;
}
};
//____________________________________________________________________________//
struct le_impl {
template <class Left, class Right>
assertion_result operator()( Left const& left, Right const& right )
{
return left <= right;
}
};
//____________________________________________________________________________//
struct gt_impl {
template <class Left, class Right>
assertion_result operator()( Left const& left, Right const& right )
{
return left > right;
}
};
//____________________________________________________________________________//
struct ge_impl {
template <class Left, class Right>
assertion_result operator()( Left const& left, Right const& right )
{
return left >= right;
}
};
//____________________________________________________________________________//
struct equal_coll_impl {
template <typename Left, typename Right>
assertion_result operator()( Left left_begin, Left left_end, Right right_begin, Right right_end )
{
assertion_result pr( 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 ) {
pr = false;
pr.message() << "\nMismatch at position " << pos << ": "
<< ::boost::test_tools::tt_detail::print_helper(*left_begin)
<< " != "
<< ::boost::test_tools::tt_detail::print_helper(*right_begin);
}
}
if( left_begin != left_end ) {
std::size_t r_size = pos;
while( left_begin != left_end ) {
++pos;
++left_begin;
}
pr = false;
pr.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;
}
pr = false;
pr.message() << "\nCollections size mismatch: " << l_size << " != " << pos;
}
return pr;
}
};
//____________________________________________________________________________//
struct bitwise_equal_impl {
template <class Left, class Right>
assertion_result operator()( Left const& left, Right const& right )
{
assertion_result pr( 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 ) ) ) {
pr = false;
pr.message() << "\nMismatch at position " << counter;
}
}
if( left_bit_size != right_bit_size ) {
pr = false;
pr.message() << "\nOperands bit sizes mismatch: " << left_bit_size << " != " << right_bit_size;
}
return pr;
}
};
//____________________________________________________________________________//
template<typename FPT1, typename FPT2>
struct comp_supertype {
// deduce "better" type from types of arguments being compared
// if one type is floating and the second integral we use floating type and
// value of integral type is promoted to the floating. The same for float and double
// But we don't want to compare two values of integral types using this tool.
typedef typename numeric::conversion_traits<FPT1,FPT2>::supertype type;
BOOST_STATIC_ASSERT_MSG( !is_integral<type>::value, "Only floating-point types can be compared!");
};
} // namespace tt_detail
namespace fpc = math::fpc;
// ************************************************************************** //
// ************** check_is_close ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL check_is_close_t {
// Public typedefs
typedef assertion_result result_type;
template<typename FPT1, typename FPT2, typename ToleranceType>
assertion_result
operator()( FPT1 left, FPT2 right, ToleranceType tolerance ) const
{
fpc::close_at_tolerance<typename tt_detail::comp_supertype<FPT1,FPT2>::type> pred( tolerance, fpc::FPC_STRONG );
assertion_result ar( pred( left, right ) );
if( !ar )
ar.message() << pred.tested_rel_diff();
return ar;
}
};
//____________________________________________________________________________//
template<typename FPT1, typename FPT2, typename ToleranceType>
inline assertion_result
check_is_close( FPT1 left, FPT2 right, ToleranceType tolerance )
{
return check_is_close_t()( left, right, tolerance );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** 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 ) const
{
return fpc::is_small( fpv, tolerance );
}
};
//____________________________________________________________________________//
template<typename FPT>
inline bool
check_is_small( FPT fpv, FPT tolerance )
{
return fpc::is_small( fpv, tolerance );
}
//____________________________________________________________________________//
} // namespace test_tools
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_OLD_IMPL_HPP_012705GER

View File

@@ -0,0 +1,282 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 81247 $
//
// Description : contains definition for all test tools in old test toolbox
// ***************************************************************************
#ifndef BOOST_TEST_TOOLS_OLD_INTERFACE_HPP_111712GER
#define BOOST_TEST_TOOLS_OLD_INTERFACE_HPP_111712GER
// Boost
#include <boost/preprocessor/seq/for_each.hpp>
#include <boost/preprocessor/seq/size.hpp>
#include <boost/preprocessor/seq/to_tuple.hpp>
#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 (as PP sequence)
// frwd_type:
// 0 - args exists and need to be forwarded; call check_frwd
// 1 - args exists, but do not need to be forwarded; call report_assertion directly
// 2 - no arguments; call report_assertion directly
#define BOOST_TEST_TOOL_PASS_PRED0( P, ARGS ) P
#define BOOST_TEST_TOOL_PASS_PRED1( P, ARGS ) P BOOST_PP_SEQ_TO_TUPLE(ARGS)
#define BOOST_TEST_TOOL_PASS_PRED2( P, ARGS ) P
#define BOOST_TEST_TOOL_PASS_ARG( r, _, arg ) , arg, BOOST_STRINGIZE( arg )
#define BOOST_TEST_TOOL_PASS_ARG_DSCR( r, _, arg ) , BOOST_STRINGIZE( arg )
#define BOOST_TEST_TOOL_PASS_ARGS0( ARGS ) \
BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_TOOL_PASS_ARG, _, ARGS )
#define BOOST_TEST_TOOL_PASS_ARGS1( ARGS ) \
, BOOST_PP_SEQ_SIZE(ARGS) BOOST_PP_SEQ_FOR_EACH( BOOST_TEST_TOOL_PASS_ARG_DSCR, _, ARGS )
#define BOOST_TEST_TOOL_PASS_ARGS2( ARGS ) \
, 0
#define BOOST_TEST_TOOL_IMPL( frwd_type, P, assertion_descr, TL, CT, ARGS ) \
do { \
BOOST_TEST_PASSPOINT(); \
::boost::test_tools::tt_detail:: \
BOOST_PP_IF( frwd_type, report_assertion, check_frwd ) ( \
BOOST_JOIN( BOOST_TEST_TOOL_PASS_PRED, frwd_type )( P, ARGS ), \
BOOST_TEST_LAZY_MSG( assertion_descr ), \
BOOST_TEST_L(__FILE__), \
static_cast<std::size_t>(__LINE__), \
::boost::test_tools::tt_detail::TL, \
::boost::test_tools::tt_detail::CT \
BOOST_JOIN( BOOST_TEST_TOOL_PASS_ARGS, frwd_type )( ARGS ) ); \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN( P ) BOOST_TEST_TOOL_IMPL( 2, \
(P), BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED, _ )
#define BOOST_CHECK( P ) BOOST_TEST_TOOL_IMPL( 2, \
(P), BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED, _ )
#define BOOST_REQUIRE( P ) BOOST_TEST_TOOL_IMPL( 2, \
(P), BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED, _ )
//____________________________________________________________________________//
#define BOOST_WARN_MESSAGE( P, M ) BOOST_TEST_TOOL_IMPL( 2, (P), M, WARN, CHECK_MSG, _ )
#define BOOST_CHECK_MESSAGE( P, M ) BOOST_TEST_TOOL_IMPL( 2, (P), M, CHECK, CHECK_MSG, _ )
#define BOOST_REQUIRE_MESSAGE( P, M ) BOOST_TEST_TOOL_IMPL( 2, (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, postfix, TL ) \
do { \
try { \
BOOST_TEST_PASSPOINT(); \
S; \
BOOST_TEST_TOOL_IMPL( 2, false, "exception " BOOST_STRINGIZE(E) " expected but not raised", \
TL, CHECK_MSG, _ ); \
} catch( E const& ex ) { \
::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \
BOOST_TEST_TOOL_IMPL( 2, P, \
"exception \"" BOOST_STRINGIZE( E )"\" raised as expected" postfix, \
TL, CHECK_MSG, _ ); \
} \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "", WARN )
#define BOOST_CHECK_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "", CHECK )
#define BOOST_REQUIRE_THROW( S, E ) BOOST_CHECK_THROW_IMPL( S, E, true, "", REQUIRE )
//____________________________________________________________________________//
#define BOOST_WARN_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), \
": validation on the raised exception through predicate \"" BOOST_STRINGIZE(P) "\"", WARN )
#define BOOST_CHECK_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), \
": validation on the raised exception through predicate \"" BOOST_STRINGIZE(P) "\"", CHECK )
#define BOOST_REQUIRE_EXCEPTION( S, E, P ) BOOST_CHECK_THROW_IMPL( S, E, P( ex ), \
": validation on the raised exception through predicate \"" BOOST_STRINGIZE(P) "\"", REQUIRE )
//____________________________________________________________________________//
#define BOOST_CHECK_NO_THROW_IMPL( S, TL ) \
do { \
try { \
S; \
BOOST_TEST_TOOL_IMPL( 2, true, "no exceptions thrown by " BOOST_STRINGIZE( S ), \
TL, CHECK_MSG, _ ); \
} catch( ... ) { \
BOOST_TEST_TOOL_IMPL( 2, false, "unexpected exception thrown by " BOOST_STRINGIZE( S ), \
TL, CHECK_MSG, _ ); \
} \
} while( ::boost::test_tools::tt_detail::dummy_cond() ) \
/**/
#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_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::equal_impl_frwd(), "", WARN, CHECK_EQUAL, (L)(R) )
#define BOOST_CHECK_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::equal_impl_frwd(), "", CHECK, CHECK_EQUAL, (L)(R) )
#define BOOST_REQUIRE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::equal_impl_frwd(), "", REQUIRE, CHECK_EQUAL, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_NE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::ne_impl(), "", WARN, CHECK_NE, (L)(R) )
#define BOOST_CHECK_NE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::ne_impl(), "", CHECK, CHECK_NE, (L)(R) )
#define BOOST_REQUIRE_NE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::ne_impl(), "", REQUIRE, CHECK_NE, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_LT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::lt_impl(), "", WARN, CHECK_LT, (L)(R) )
#define BOOST_CHECK_LT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::lt_impl(), "", CHECK, CHECK_LT, (L)(R) )
#define BOOST_REQUIRE_LT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::lt_impl(), "", REQUIRE, CHECK_LT, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_LE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::le_impl(), "", WARN, CHECK_LE, (L)(R) )
#define BOOST_CHECK_LE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::le_impl(), "", CHECK, CHECK_LE, (L)(R) )
#define BOOST_REQUIRE_LE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::le_impl(), "", REQUIRE, CHECK_LE, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_GT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::gt_impl(), "", WARN, CHECK_GT, (L)(R) )
#define BOOST_CHECK_GT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::gt_impl(), "", CHECK, CHECK_GT, (L)(R) )
#define BOOST_REQUIRE_GT( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::gt_impl(), "", REQUIRE, CHECK_GT, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_GE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::ge_impl(), "", WARN, CHECK_GE, (L)(R) )
#define BOOST_CHECK_GE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::ge_impl(), "", CHECK, CHECK_GE, (L)(R) )
#define BOOST_REQUIRE_GE( L, R ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::tt_detail::ge_impl(), "", REQUIRE, CHECK_GE, (L)(R) )
//____________________________________________________________________________//
#define BOOST_WARN_CLOSE( L, R, T ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_close_t(), "", WARN, CHECK_CLOSE, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
#define BOOST_CHECK_CLOSE( L, R, T ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_close_t(), "", CHECK, CHECK_CLOSE, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
#define BOOST_REQUIRE_CLOSE( L, R, T ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_close_t(), "", REQUIRE, CHECK_CLOSE, (L)(R)(::boost::math::fpc::percent_tolerance(T)) )
//____________________________________________________________________________//
#define BOOST_WARN_CLOSE_FRACTION(L, R, T) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_close_t(), "", WARN, CHECK_CLOSE_FRACTION, (L)(R)(T) )
#define BOOST_CHECK_CLOSE_FRACTION(L, R, T) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_close_t(), "", CHECK, CHECK_CLOSE_FRACTION, (L)(R)(T) )
#define BOOST_REQUIRE_CLOSE_FRACTION(L,R,T) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_close_t(), "", REQUIRE, CHECK_CLOSE_FRACTION, (L)(R)(T) )
//____________________________________________________________________________//
#define BOOST_WARN_SMALL( FPV, T ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_small_t(), "", WARN, CHECK_SMALL, (FPV)(T) )
#define BOOST_CHECK_SMALL( FPV, T ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_small_t(), "", CHECK, CHECK_SMALL, (FPV)(T) )
#define BOOST_REQUIRE_SMALL( FPV, T ) BOOST_TEST_TOOL_IMPL( 0, \
::boost::test_tools::check_is_small_t(), "", REQUIRE, CHECK_SMALL, (FPV)(T) )
//____________________________________________________________________________//
#define BOOST_WARN_PREDICATE( P, ARGS ) BOOST_TEST_TOOL_IMPL( 0, \
P, BOOST_TEST_STRINGIZE( P ), WARN, CHECK_PRED_WITH_ARGS, ARGS )
#define BOOST_CHECK_PREDICATE( P, ARGS ) BOOST_TEST_TOOL_IMPL( 0, \
P, BOOST_TEST_STRINGIZE( P ), CHECK, CHECK_PRED_WITH_ARGS, ARGS )
#define BOOST_REQUIRE_PREDICATE( P, ARGS ) BOOST_TEST_TOOL_IMPL( 0, \
P, BOOST_TEST_STRINGIZE( P ), REQUIRE, CHECK_PRED_WITH_ARGS, ARGS )
//____________________________________________________________________________//
#define BOOST_WARN_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_TEST_TOOL_IMPL( 1, ::boost::test_tools::tt_detail::equal_coll_impl(), \
"", WARN, CHECK_EQUAL_COLL, (L_begin)(L_end)(R_begin)(R_end) ) \
/**/
#define BOOST_CHECK_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_TEST_TOOL_IMPL( 1, ::boost::test_tools::tt_detail::equal_coll_impl(), \
"", CHECK, CHECK_EQUAL_COLL, (L_begin)(L_end)(R_begin)(R_end) ) \
/**/
#define BOOST_REQUIRE_EQUAL_COLLECTIONS( L_begin, L_end, R_begin, R_end ) \
BOOST_TEST_TOOL_IMPL( 1, ::boost::test_tools::tt_detail::equal_coll_impl(), \
"", REQUIRE, CHECK_EQUAL_COLL, (L_begin)(L_end)(R_begin)(R_end) ) \
/**/
//____________________________________________________________________________//
#define BOOST_WARN_BITWISE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 1, \
::boost::test_tools::tt_detail::bitwise_equal_impl(), "", WARN, CHECK_BITWISE_EQUAL, (L)(R) )
#define BOOST_CHECK_BITWISE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 1, \
::boost::test_tools::tt_detail::bitwise_equal_impl(), "", CHECK, CHECK_BITWISE_EQUAL, (L)(R) )
#define BOOST_REQUIRE_BITWISE_EQUAL( L, R ) BOOST_TEST_TOOL_IMPL( 1, \
::boost::test_tools::tt_detail::bitwise_equal_impl(), "", REQUIRE, CHECK_BITWISE_EQUAL, (L)(R) )
//____________________________________________________________________________//
#define BOOST_IS_DEFINED( symb ) ::boost::test_tools::tt_detail::is_defined_impl( #symb, BOOST_STRINGIZE(= symb) )
//____________________________________________________________________________//
#ifdef BOOST_TEST_NO_NEW_TOOLS
#define BOOST_TEST_WARN( P ) BOOST_WARN( P )
#define BOOST_TEST_CHECK( P ) BOOST_CHECK( P )
#define BOOST_TEST_REQUIRE( P ) BOOST_REQUIRE( P )
#define BOOST_TEST( P ) BOOST_CHECK( P )
#endif
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TOOLS_OLD_INTERFACE_HPP_111712GER

View File

@@ -0,0 +1,96 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief 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/tools/assertion_result.hpp>
// STL
#include <cstddef> // for std::size_t
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** output_test_stream ************** //
// ************************************************************************** //
namespace boost {
namespace test_tools {
//! Class to be used to simplify testing of ostream-based output operations
class BOOST_TEST_DECL output_test_stream : public wrap_stringstream::wrapped_stream {
typedef unit_test::const_string const_string;
public:
//! Constructor
//!
//!@param[in] pattern_file_name indicates the name of the file for matching. If the
//! string is empty, the standard input or output streams are used instead
//! (depending on match_or_save)
//!@param[in] match_or_save if true, the pattern file will be read, otherwise it will be
//! written
//!@param[in] text_or_binary if false, opens the stream in binary mode. Otherwise the stream
//! is opened with default flags and the carriage returns are ignored.
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();
//! Checks if the stream is empty
//!
//!@param[in] flush_stream if true, flushes the stream after the call
assertion_result is_empty( bool flush_stream = true );
//! Checks the length of the stream
//!
//!@param[in] length target length
//!@param[in] flush_stream if true, flushes the stream after the call. Set to false to call
//! additional checks on the same content.
assertion_result check_length( std::size_t length, bool flush_stream = true );
//! Checks the content of the stream against a string
//!
//!@param[in] arg_ the target stream
//!@param[in] flush_stream if true, flushes the stream after the call.
assertion_result is_equal( const_string arg_, bool flush_stream = true );
//! Checks the content of the stream against a pattern file
//!
//!@param[in] flush_stream if true, flushes the stream after the call.
assertion_result match_pattern( bool flush_stream = true );
//! Flushes the stream
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,53 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74640 $
//
// Description : defines auto_test_unit_registrar
// ***************************************************************************
#ifndef BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER
#define BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/test_unit.hpp>
// STL
#include <list>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace ut_detail {
// ************************************************************************** //
// ************** auto_test_unit_registrar ************** //
// ************************************************************************** //
struct BOOST_TEST_DECL auto_test_unit_registrar {
// Constructors
auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail = 0 );
explicit auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators );
explicit auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators );
explicit auto_test_unit_registrar( int );
};
} // namespace ut_detail
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_AUTO_REGISTRATION_HPP_100211GER

View File

@@ -0,0 +1,277 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 62016 $
//
// Description : defines decorators to be using with auto registered test units
// ***************************************************************************
#ifndef BOOST_TEST_TREE_DECORATOR_HPP_091911GER
#define BOOST_TEST_TREE_DECORATOR_HPP_091911GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/tree/fixture.hpp>
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
#include <boost/test/utils/trivial_singleton.hpp>
// Boost
#include <boost/shared_ptr.hpp>
#include <boost/function/function0.hpp>
#include <boost/function/function1.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// STL
#include <vector>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
class test_unit;
namespace decorator {
// ************************************************************************** //
// ************** decorator::collector ************** //
// ************************************************************************** //
class base;
typedef boost::shared_ptr<base> base_ptr;
class BOOST_TEST_DECL collector : public singleton<collector> {
public:
collector& operator*( base const& d );
void store_in( test_unit& tu );
void reset();
private:
BOOST_TEST_SINGLETON_CONS( collector )
// Data members
std::vector<base_ptr> m_tu_decorators;
};
// ************************************************************************** //
// ************** decorator::base ************** //
// ************************************************************************** //
class BOOST_TEST_DECL base {
public:
// composition interface
collector& operator*() const;
// application interface
virtual void apply( test_unit& tu ) = 0;
// deep cloning interface
virtual base_ptr clone() const = 0;
protected:
virtual ~base() {}
};
// ************************************************************************** //
// ************** decorator::label ************** //
// ************************************************************************** //
class BOOST_TEST_DECL label : public decorator::base {
public:
explicit label( const_string l ) : m_label( l ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new label( m_label )); }
// Data members
const_string m_label;
};
// ************************************************************************** //
// ************** decorator::expected_failures ************** //
// ************************************************************************** //
class BOOST_TEST_DECL expected_failures : public decorator::base {
public:
explicit expected_failures( counter_t ef ) : m_exp_fail( ef ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new expected_failures( m_exp_fail )); }
// Data members
counter_t m_exp_fail;
};
// ************************************************************************** //
// ************** decorator::timeout ************** //
// ************************************************************************** //
class BOOST_TEST_DECL timeout : public decorator::base {
public:
explicit timeout( unsigned t ) : m_timeout( t ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new timeout( m_timeout )); }
// Data members
unsigned m_timeout;
};
// ************************************************************************** //
// ************** decorator::description ************** //
// ************************************************************************** //
class BOOST_TEST_DECL description : public decorator::base {
public:
explicit description( const_string descr ) : m_description( descr ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new description( m_description )); }
// Data members
const_string m_description;
};
// ************************************************************************** //
// ************** decorator::depends_on ************** //
// ************************************************************************** //
class BOOST_TEST_DECL depends_on : public decorator::base {
public:
explicit depends_on( const_string dependency ) : m_dependency( dependency ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new depends_on( m_dependency )); }
// Data members
const_string m_dependency;
};
// ************************************************************************** //
// ************** decorator::enable_if/enabled/disabled ************** //
// ************************************************************************** //
class BOOST_TEST_DECL enable_if_impl : public decorator::base {
protected:
void apply_impl( test_unit& tu, bool condition );
};
template<bool condition>
class enable_if : public enable_if_impl {
private:
// decorator::base interface
virtual void apply( test_unit& tu ) { this->apply_impl( tu, condition ); }
virtual base_ptr clone() const { return base_ptr(new enable_if<condition>()); }
};
typedef enable_if<true> enabled;
typedef enable_if<false> disabled;
// ************************************************************************** //
// ************** decorator::fixture ************** //
// ************************************************************************** //
class BOOST_TEST_DECL fixture_t : public decorator::base {
public:
// Constructor
explicit fixture_t( test_unit_fixture_ptr impl ) : m_impl( impl ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new fixture_t( m_impl )); }
// Data members
test_unit_fixture_ptr m_impl;
};
//____________________________________________________________________________//
template<typename F>
inline fixture_t
fixture()
{
return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F>() ) );
}
//____________________________________________________________________________//
template<typename F, typename Arg>
inline fixture_t
fixture( Arg const& arg )
{
return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F,Arg>( arg ) ) );
}
//____________________________________________________________________________//
inline fixture_t
fixture( boost::function<void()> const& setup, boost::function<void()> const& teardown = boost::function<void()>() )
{
return fixture_t( test_unit_fixture_ptr( new unit_test::function_based_fixture( setup, teardown ) ) );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** decorator::depends_on ************** //
// ************************************************************************** //
class BOOST_TEST_DECL precondition : public decorator::base {
public:
typedef boost::function<test_tools::assertion_result (test_unit_id)> predicate_t;
explicit precondition( predicate_t p ) : m_precondition( p ) {}
private:
// decorator::base interface
virtual void apply( test_unit& tu );
virtual base_ptr clone() const { return base_ptr(new precondition( m_precondition )); }
// Data members
predicate_t m_precondition;
};
} // namespace decorator
using decorator::label;
using decorator::expected_failures;
using decorator::timeout;
using decorator::description;
using decorator::depends_on;
using decorator::enable_if;
using decorator::enabled;
using decorator::disabled;
using decorator::fixture;
using decorator::precondition;
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_DECORATOR_HPP_091911GER

View File

@@ -0,0 +1,116 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74640 $
//
// Description : defines fixture interface and object makers
// ***************************************************************************
#ifndef BOOST_TEST_TREE_FIXTURE_HPP_100311GER
#define BOOST_TEST_TREE_FIXTURE_HPP_100311GER
// Boost.Test
#include <boost/test/detail/config.hpp>
// Boost
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/function/function0.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_unit_fixture ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_unit_fixture {
public:
virtual ~test_unit_fixture() {}
// Fixture interface
virtual void setup() = 0;
virtual void teardown() = 0;
};
typedef shared_ptr<test_unit_fixture> test_unit_fixture_ptr;
// ************************************************************************** //
// ************** class_based_fixture ************** //
// ************************************************************************** //
template<typename F, typename Arg=void>
class class_based_fixture : public test_unit_fixture {
public:
// Constructor
explicit class_based_fixture( Arg const& arg ) : m_inst(), m_arg( arg ) {}
private:
// Fixture interface
virtual void setup() { m_inst.reset( new F( m_arg ) ); }
virtual void teardown() { m_inst.reset(); }
// Data members
scoped_ptr<F> m_inst;
Arg m_arg;
};
//____________________________________________________________________________//
template<typename F>
class class_based_fixture<F,void> : public test_unit_fixture {
public:
// Constructor
class_based_fixture() : m_inst( 0 ) {}
private:
// Fixture interface
virtual void setup() { m_inst.reset( new F ); }
virtual void teardown() { m_inst.reset(); }
// Data members
scoped_ptr<F> m_inst;
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** function_based_fixture ************** //
// ************************************************************************** //
class function_based_fixture : public test_unit_fixture {
public:
// Constructor
function_based_fixture( boost::function<void ()> const& setup_, boost::function<void ()> const& teardown_ )
: m_setup( setup_ )
, m_teardown( teardown_ )
{
}
private:
// Fixture interface
virtual void setup() { if( m_setup ) m_setup(); }
virtual void teardown() { if( m_teardown ) m_teardown(); }
// Data members
boost::function<void ()> m_setup;
boost::function<void ()> m_teardown;
};
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_FIXTURE_HPP_100311GER

View File

@@ -0,0 +1,68 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74640 $
//
// Description : defines global_fixture
// ***************************************************************************
#ifndef BOOST_TEST_TREE_GLOBAL_FIXTURE_HPP_091911GER
#define BOOST_TEST_TREE_GLOBAL_FIXTURE_HPP_091911GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/tree/observer.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** 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_fixture( 0 ) {}
// test observer interface
virtual void test_start( counter_t ) { m_fixture = new F; }
virtual void test_finish() { delete m_fixture; m_fixture = 0; }
virtual void test_aborted() { delete m_fixture; m_fixture = 0; }
private:
// Data members
F* m_fixture;
};
} // namespace ut_detail
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_GLOBAL_FIXTURE_HPP_091911GER

View File

@@ -0,0 +1,70 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//!@brief 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& tu, const_string ) { test_unit_skipped( tu ); }
virtual void test_unit_skipped( test_unit const& ) {} ///< backward compatibility
virtual void test_unit_aborted( test_unit const& ) {}
virtual void assertion_result( unit_test::assertion_result ar )
{
switch( ar ) {
case AR_PASSED: assertion_result( true ); break;
case AR_FAILED: assertion_result( false ); break;
case AR_TRIGGERED: break;
default: break;
}
}
virtual void exception_caught( execution_exception const& ) {}
virtual int priority() { return 0; }
protected:
// depracated now
virtual void assertion_result( bool /* passed */ ) {}
BOOST_TEST_PROTECTED_VIRTUAL ~test_observer() {}
};
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TEST_OBSERVER_HPP_021005GER

View File

@@ -0,0 +1,54 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: 74640 $
//
// Description : defines test_case_counter
// ***************************************************************************
#ifndef BOOST_TEST_TREE_TEST_CASE_COUNTER_HPP_100211GER
#define BOOST_TEST_TREE_TEST_CASE_COUNTER_HPP_100211GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** 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& tc ) { if( tc.is_enabled() ) ++p_count.value; }
virtual bool test_suite_start( test_suite const& ts ) { return ts.is_enabled(); }
};
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_TEST_CASE_COUNTER_HPP_100211GER

View File

@@ -0,0 +1,144 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: -1 $
//
// Description : defines template_test_case_gen
// ***************************************************************************
#ifndef BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
#define BOOST_TEST_TREE_TEST_CASE_TEMPLATE_HPP_091911GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/detail/workaround.hpp>
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/tree/observer.hpp>
// Boost
#include <boost/shared_ptr.hpp>
#include <boost/mpl/for_each.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/type.hpp>
#include <boost/type_traits/is_const.hpp>
#include <boost/function/function0.hpp>
#ifndef BOOST_NO_RTTI
#include <typeinfo> // for typeid
#else
#include <boost/current_function.hpp>
#endif
// STL
#include <string> // for std::string
#include <list> // for std::list
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
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, const_string tc_file, std::size_t tc_line, Generator& G )
: m_test_case_name( tc_name )
, m_test_case_file( tc_file )
, m_test_case_line( tc_line )
, 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 += '<';
#ifndef BOOST_NO_RTTI
full_name += typeid(TestType).name();
#else
full_name += BOOST_CURRENT_FUNCTION;
#endif
if( boost::is_const<TestType>::value )
full_name += "_const";
full_name += '>';
m_holder.m_test_cases.push_back( new test_case( ut_detail::normalize_test_case_name( full_name ),
m_test_case_file,
m_test_case_line,
test_case_template_invoker<TestCaseTemplate,TestType>() ) );
}
private:
// Data members
const_string m_test_case_name;
const_string m_test_case_file;
std::size_t m_test_case_line;
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, const_string tc_file, std::size_t tc_line )
{
typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
}
virtual test_unit* next() const
{
if( m_test_cases.empty() )
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_TREE_TEST_CASE_TEMPLATE_HPP_091911GER

View File

@@ -0,0 +1,275 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Defines @ref boost::unit_test::test_unit "test_unit", @ref boost::unit_test::test_case "test_case",
/// @ref boost::unit_test::test_suite "test_suite" and @ref boost::unit_test::master_test_suite_t "master_test_suite_t"
// ***************************************************************************
#ifndef BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
#define BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/detail/fwd_decl.hpp>
#include <boost/test/tree/decorator.hpp>
#include <boost/test/tree/fixture.hpp>
#include <boost/test/tools/assertion_result.hpp>
#include <boost/test/utils/class_properties.hpp>
// Boost
#include <boost/function/function0.hpp>
#include <boost/function/function1.hpp>
// STL
#include <vector>
#include <string>
#include <map>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace framework {
class state;
}
// ************************************************************************** //
// ************** test_unit ************** //
// ************************************************************************** //
typedef std::vector<test_unit_id> test_unit_id_list;
class BOOST_TEST_DECL test_unit {
public:
enum { type = TUT_ANY };
enum run_status { RS_DISABLED, RS_ENABLED, RS_INHERIT, RS_INVALID };
typedef std::vector<test_unit_id> id_list;
typedef std::vector<test_unit_fixture_ptr> fixture_list_t;
typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework::state)) id_t;
typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite)) parent_id_t;
typedef BOOST_READONLY_PROPERTY(id_list,(test_unit)) id_list_t;
typedef std::vector<decorator::base_ptr> decor_list_t;
typedef BOOST_READONLY_PROPERTY(std::vector<std::string>,(test_unit)) label_list_t;
typedef boost::function<test_tools::assertion_result (test_unit_id)> precondition_t;
typedef BOOST_READONLY_PROPERTY(std::vector<precondition_t>,(test_unit)) precond_list_t;
// preconditions management
void depends_on( test_unit* tu );
void add_precondition( precondition_t const& );
test_tools::assertion_result check_preconditions() const;
// labels management
void add_label( const_string l );
bool has_label( const_string l ) const;
// helper access methods
void increase_exp_fail( counter_t num );
bool is_enabled() const { return p_run_status == RS_ENABLED; }
std::string full_name() const;
// Public r/o properties
test_unit_type const p_type; ///< type for this test unit
const_string const p_type_name; ///< "case"/"suite"/"module"
const_string const p_file_name;
std::size_t const p_line_num;
id_t p_id; ///< unique id for this test unit
parent_id_t p_parent_id; ///< parent test suite id
label_list_t p_labels; ///< list of labels associated with this test unit
id_list_t p_dependencies; ///< list of test units this one depends on
precond_list_t p_preconditions; ///< user supplied preconditions for this test unit;
// Public r/w properties
readwrite_property<std::string> p_name; ///< name for this test unit
readwrite_property<std::string> p_description; ///< description for this test unit
readwrite_property<unsigned> p_timeout; ///< timeout for the test unit execution in seconds
readwrite_property<counter_t> p_expected_failures; ///< number of expected failures in this test unit
readwrite_property<run_status> p_default_status; ///< run status obtained by this unit during setup phase
readwrite_property<run_status> p_run_status; ///< run status assigned to this unit before execution phase after applying all filters
readwrite_property<counter_t> p_sibling_rank; ///< rank of this test unit amoung siblings of the same parent
readwrite_property<decor_list_t> p_decorators; ///< automatically assigned decorators; execution is delayed till framework::finalize_setup_phase function
readwrite_property<fixture_list_t> p_fixtures; ///< fixtures associated with this test unit
protected:
~test_unit();
// Constructor
test_unit( const_string tu_name, const_string tc_file, std::size_t tc_line, test_unit_type t );
// Master test suite constructor
explicit test_unit( const_string module_name );
private:
};
// ************************************************************************** //
// ************** test_unit_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, boost::function<void ()> const& test_func );
test_case( const_string tc_name, const_string tc_file, std::size_t tc_line, boost::function<void ()> const& test_func );
// Public property
typedef BOOST_READONLY_PROPERTY(boost::function<void ()>,(test_case)) test_func;
test_func p_test_func;
private:
friend class framework::state;
~test_case() {}
};
// ************************************************************************** //
// ************** test_suite ************** //
// ************************************************************************** //
//! Class representing test suites
class BOOST_TEST_DECL test_suite : public test_unit {
public:
enum { type = TUT_SUITE };
// Constructor
explicit test_suite( const_string ts_name, const_string ts_file, std::size_t ts_line );
// test unit list management
/*!@brief Adds a test unit to a test suite.
*
* It is possible to specify the timeout and the expected failures.
*/
void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
/// @overload
void add( test_unit_generator const& gen, unsigned timeout = 0 );
/// @overload
void add( test_unit_generator const& gen, decorator::collector& decorators );
//! Removes a test from the test suite.
void remove( test_unit_id id );
// access methods
test_unit_id get( const_string tu_name ) const;
std::size_t size() const { return m_children.size(); }
protected:
// Master test suite constructor
explicit test_suite( const_string module_name );
friend BOOST_TEST_DECL
void traverse_test_tree( test_suite const&, test_tree_visitor&, bool );
friend class framework::state;
virtual ~test_suite() {}
typedef std::multimap<counter_t,test_unit_id> children_per_rank;
// Data members
test_unit_id_list m_children;
children_per_rank m_ranked_children; ///< maps child sibling rank to list of children with that rank
};
// ************************************************************************** //
// ************** master_test_suite ************** //
// ************************************************************************** //
class BOOST_TEST_DECL master_test_suite_t : public test_suite {
public:
master_test_suite_t();
// Data members
int argc;
char** argv;
};
// ************************************************************************** //
// ************** user_tc_method_invoker ************** //
// ************************************************************************** //
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
// ************************************************************************** //
// ************** make_test_case ************** //
// ************************************************************************** //
inline test_case*
make_test_case( boost::function<void ()> const& test_func, const_string tc_name, const_string tc_file, std::size_t tc_line )
{
return new test_case( ut_detail::normalize_test_case_name( tc_name ), tc_file, tc_line, test_func );
}
//____________________________________________________________________________//
template<typename UserTestCase, typename InstanceType>
inline test_case*
make_test_case( void (UserTestCase::* test_method )(),
const_string tc_name,
const_string tc_file,
std::size_t tc_line,
boost::shared_ptr<InstanceType> user_test_case )
{
return new test_case( ut_detail::normalize_test_case_name( tc_name ),
tc_file,
tc_line,
ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_TEST_UNIT_HPP_100211GER

View File

@@ -0,0 +1,58 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: -1 $
//
// Description : defines traverse_test_tree algorithm
// ***************************************************************************
#ifndef BOOST_TEST_TREE_TRAVERSE_HPP_100211GER
#define BOOST_TEST_TREE_TRAVERSE_HPP_100211GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/tree/visitor.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** traverse_test_tree ************** //
// ************************************************************************** //
BOOST_TEST_DECL void traverse_test_tree( test_case const&, test_tree_visitor&, bool ignore_status = false );
BOOST_TEST_DECL void traverse_test_tree( test_suite const&, test_tree_visitor&, bool ignore_status = false );
BOOST_TEST_DECL void traverse_test_tree( test_unit_id , test_tree_visitor&, bool ignore_status = false );
//____________________________________________________________________________//
inline void
traverse_test_tree( test_unit const& tu, test_tree_visitor& V, bool ignore_status = false )
{
if( tu.p_type == TUT_CASE )
traverse_test_tree( static_cast<test_case const&>( tu ), V, ignore_status );
else
traverse_test_tree( static_cast<test_suite const&>( tu ), V, ignore_status );
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_TRAVERSE_HPP_100211GER

View File

@@ -0,0 +1,52 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision: -1 $
//
// Description : defines test_tree_visitor
// ***************************************************************************
#ifndef BOOST_TEST_TREE_VISITOR_HPP_100211GER
#define BOOST_TEST_TREE_VISITOR_HPP_100211GER
// Boost.Test
#include <boost/test/detail/config.hpp>
#include <boost/test/tree/test_unit.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** test_tree_visitor ************** //
// ************************************************************************** //
class BOOST_TEST_DECL test_tree_visitor {
public:
// test tree visitor interface
virtual bool visit( test_unit const& ) { return true; }
virtual void visit( test_case const& tc ) { visit( (test_unit const&)tc ); }
virtual bool test_suite_start( test_suite const& ts ){ return visit( (test_unit const&)ts ); }
virtual void test_suite_finish( test_suite const& ) {}
protected:
BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
};
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_TREE_VISITOR_HPP_100211GER

View File

@@ -0,0 +1,70 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Entry point into the Unit Test Framework
///
/// This header should be the only header necessary to include to start using the 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[] );
}
// !! ?? to remove
namespace unit_test_framework=unit_test;
}
#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,172 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief 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/tree/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
// 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
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&, const_string );
virtual void exception_caught( execution_exception const& ex );
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:
// Implementation helpers
bool log_entry_start();
void log_entry_context( log_level l );
void clear_entry_context();
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_TEST_LAZY_MSG( M ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_PASSPOINT() \
::boost::unit_test::unit_test_log.set_checkpoint( \
BOOST_TEST_L(__FILE__), \
static_cast<std::size_t>(__LINE__) ) \
/**/
//____________________________________________________________________________//
#define BOOST_TEST_CHECKPOINT( M ) \
::boost::unit_test::unit_test_log.set_checkpoint( \
BOOST_TEST_L(__FILE__), \
static_cast<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,248 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Defines unit test log formatter interface
///
/// You can define a class with implements this interface and use an instance of it
/// as a Unit Test Framework log formatter
// ***************************************************************************
#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 {
// ************************************************************************** //
/// Collection of log entry attributes
// ************************************************************************** //
struct BOOST_TEST_DECL log_entry_data {
log_entry_data()
{
m_file_name.reserve( 200 );
}
std::string m_file_name; ///< log entry file name
std::size_t m_line_num; ///< log entry line number
log_level m_level; ///< log entry level
void clear()
{
m_file_name.erase();
m_line_num = 0;
m_level = log_nothing;
}
};
// ************************************************************************** //
/// Collection of log checkpoint attributes
// ************************************************************************** //
struct BOOST_TEST_DECL log_checkpoint_data
{
const_string m_file_name; ///< log checkpoint file name
std::size_t m_line_num; ///< log checkpoint file name
std::string m_message; ///< log checkpoint message
void clear()
{
m_file_name.clear();
m_line_num = 0;
m_message = std::string();
}
};
// ************************************************************************** //
/// Abstract Unit Test Framework log formatter interface
/// During the test module execution Unit Test Framework can report messages about success or failure of assertions,
/// which test suites are being run and more (specifically which messages are reported depends on log level threshold selected by the user).
/// All these messages constitute Unit Test Framework log. There are many ways (formats) to present these messages to the user. Boost.Test comes with
/// two formats: "Compiler-like log format" and "XML based log format". Former is intended for human consumption and later is intended for processing
/// by automated regression test systems. If you want to produce some other format you need to implement class with specific interface and use
/// method unit_test_log_t::set_formatter during a test module initialization to set an active formatter. The class unit_test_log_formatter defines this
/// interface.
///
/// This interface requires you to format all possible messages being produced in the log. These includes error messages about failed assertions, messages
/// about caught exceptions and information messages about test units being started/ended. All the methods in this interface takes a reference to standard
/// stream as a first argument. This is where final messages needs to be directed to. Also you are given all the information necessary to produce a message.
class BOOST_TEST_DECL unit_test_log_formatter {
public:
/// Types of log entries (messages written into a log)
enum log_entry_types { BOOST_UTL_ET_INFO, ///< Information message from the framework
BOOST_UTL_ET_MESSAGE, ///< Information message from the user
BOOST_UTL_ET_WARNING, ///< Warning (non error) condition notification message
BOOST_UTL_ET_ERROR, ///< Non fatal error notification message
BOOST_UTL_ET_FATAL_ERROR ///< Fatal error notification message
};
// Destructor
virtual ~unit_test_log_formatter() {}
// @name Test start/finish
/// Invoked at the beginning of test module execution
/// @param[in] os output stream to write a messages to
/// @param[in] test_cases_amount total test case amount to be run
/// @see log_finish
virtual void log_start( std::ostream& os, counter_t test_cases_amount ) = 0;
/// Invoked at the end of test module execution
/// @param[in] os output stream to write a messages into
/// @see log_start
virtual void log_finish( std::ostream& os ) = 0;
/// Invoked when Unit Test Framework build information is requested
/// @param[in] os output stream to write a messages into
virtual void log_build_info( std::ostream& os ) = 0;
// @}
// @name Test unit start/finish
/// Invoked when test unit starts (either test suite or test case)
/// @param[in] os output stream to write a messages into
/// @param[in] tu test unit being started
/// @see test_unit_finish
virtual void test_unit_start( std::ostream& os, test_unit const& tu ) = 0;
/// Invoked when test unit finishes
/// @param[in] os output stream to write a messages into
/// @param[in] tu test unit being finished
/// @param[in] elapsed time in milliseconds spend executing this test unit
/// @see test_unit_start
virtual void test_unit_finish( std::ostream& os, test_unit const& tu, unsigned long elapsed ) = 0;
/// Invoked if test unit skipped for any reason
/// @param[in] os output stream to write a messages into
/// @param[in] tu skipped test unit
/// @param[in] reason explanation why was it skipped
virtual void test_unit_skipped( std::ostream& os, test_unit const& tu, const_string reason )
{
test_unit_skipped( os, tu );
}
/// Deprecated version of this interface
virtual void test_unit_skipped( std::ostream& os, test_unit const& tu ) {}
// @}
// @name Uncaught exception report
/// Invoked when Unit Test Framework detects uncaught exception
/// Call to this function starts uncaught exception report. It is going to followed by context information. Report is finalized by call to
/// log_exception_finish.
/// @param[in] os output stream to write a messages into
/// @param[in] lcd information about the last checkpoint before the exception was triggered
/// @param[in] ex information about the caught exception
/// @see log_exception_finish
virtual void log_exception_start( std::ostream& os, log_checkpoint_data const& lcd, execution_exception const& ex ) = 0;
/// Invoked when Unit Test Framework detects uncaught exception
/// Call to this function finishes uncaught exception report.
/// @param[in] os output stream to write a messages into
/// @see log_exception_start
virtual void log_exception_finish( std::ostream& os ) = 0;
// @}
// @name Regular log entry
/// Invoked by Unit Test Framework to start new log entry
/// Call to this function starts new log entry. It is followed by series of log_entry_value calls and finally call to log_entry_finish.
/// A log entry may consist of one or more values being reported. Some of these values will be plain strings, while others can be complicated
/// expressions in a form of "lazy" expression template lazy_ostream.
/// @param[in] os output stream to write a messages into
/// @param[in] led log entry attributes
/// @param[in] let log entry type log_entry_finish
/// @see log_entry_value, log_entry_finish
virtual void log_entry_start( std::ostream& os, log_entry_data const& led, log_entry_types let ) = 0;
/// Invoked by Unit Test Framework to report a log entry content
/// This is one of two overloaded methods to report log entry content. This one is used to report plain string value.
/// @param[in] os output stream to write a messages into.
/// @param[in] value log entry string value
/// @see log_entry_start, log_entry_finish
virtual void log_entry_value( std::ostream& os, const_string value ) = 0;
/// Invoked by Unit Test Framework to report a log entry content
/// This is one of two overloaded methods to report log entry content. This one is used to report some complicated expression passed as
/// an expression template lazy_ostream. In most cases default implementation provided by the framework should work as is (it just converts
/// the lazy expression into a string.
/// @param[in] os output stream to write a messages into
/// @param[in] value log entry "lazy" value
/// @see log_entry_start, log_entry_finish
virtual void log_entry_value( std::ostream& os, lazy_ostream const& value ); // there is a default impl
/// Invoked by Unit Test Framework to finish a log entry report
/// @param[in] os output stream to write a messages into
/// @see log_entry_start, log_entry_start
virtual void log_entry_finish( std::ostream& os ) = 0;
// @}
// @name Log entry context report
/// Invoked by Unit Test Framework to start log entry context report
/// Unit Test Framework logs for failed assertions and uncaught exceptions context if one was defined by a test module.
/// Context consists of multiple "scopes" identified by description messages assigned by the test module using
/// BOOST_TEST_INFO/BOOST_TEST_CONTEXT statements.
/// @param[in] os output stream to write a messages into
/// @param[in] l entry log_leveg, to be used to fine tune the message
/// @see log_entry_context, entry_context_finish
virtual void entry_context_start( std::ostream& os, log_level l ) = 0;
/// Invoked by Unit Test Framework to report log entry context "scope" description
/// Each "scope" description is reported by separate call to log_entry_context.
/// @param[in] os output stream to write a messages into
/// @param[in] value context "scope" description
/// @see log_entry_start, entry_context_finish
virtual void log_entry_context( std::ostream& os, const_string value ) = 0;
/// Invoked by Unit Test Framework to finish log entry context report
/// @param[in] os output stream to write a messages into
/// @see log_entry_start, entry_context_context
virtual void entry_context_finish( std::ostream& os ) = 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,60 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief 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/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_ok = 0,
precondition_failure = -1,
unexpected_exception = -2,
os_exception = -3,
os_timeout = -4,
fatal_error = -5 // includes both system and user
};
static bool is_critical_error( error_level e ) { return e <= fatal_error; }
// monitor method
error_level execute_and_translate( boost::function<void ()> const& func, unsigned timeout = 0 );
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,128 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief Provides access to various Unit Test Framework runtime parameters
///
/// Primarily for use by the framework itself
// ***************************************************************************
#ifndef BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
#define BOOST_TEST_UNIT_TEST_PARAMETERS_HPP_071894GER
// Boost.Test
#include <boost/test/detail/global_typedef.hpp>
#include <boost/test/utils/runtime/argument.hpp>
// STL
#include <iostream>
#include <fstream>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace runtime_config {
// ************************************************************************** //
// ************** runtime_config ************** //
// ************************************************************************** //
// UTF parameters
BOOST_TEST_DECL extern std::string AUTO_START_DBG;
BOOST_TEST_DECL extern std::string BREAK_EXEC_PATH;
BOOST_TEST_DECL extern std::string BUILD_INFO;
BOOST_TEST_DECL extern std::string CATCH_SYS_ERRORS;
BOOST_TEST_DECL extern std::string COLOR_OUTPUT;
BOOST_TEST_DECL extern std::string DETECT_FP_EXCEPT;
BOOST_TEST_DECL extern std::string DETECT_MEM_LEAKS;
BOOST_TEST_DECL extern std::string LIST_CONTENT;
BOOST_TEST_DECL extern std::string LIST_LABELS;
BOOST_TEST_DECL extern std::string LOG_FORMAT;
BOOST_TEST_DECL extern std::string LOG_LEVEL;
BOOST_TEST_DECL extern std::string LOG_SINK;
BOOST_TEST_DECL extern std::string OUTPUT_FORMAT;
BOOST_TEST_DECL extern std::string RANDOM_SEED;
BOOST_TEST_DECL extern std::string REPORT_FORMAT;
BOOST_TEST_DECL extern std::string REPORT_LEVEL;
BOOST_TEST_DECL extern std::string REPORT_MEM_LEAKS;
BOOST_TEST_DECL extern std::string REPORT_SINK;
BOOST_TEST_DECL extern std::string RESULT_CODE;
BOOST_TEST_DECL extern std::string RUN_FILTERS;
BOOST_TEST_DECL extern std::string SAVE_TEST_PATTERN;
BOOST_TEST_DECL extern std::string SHOW_PROGRESS;
BOOST_TEST_DECL extern std::string USE_ALT_STACK;
BOOST_TEST_DECL extern std::string WAIT_FOR_DEBUGGER;
BOOST_TEST_DECL void init( int& argc, char** argv );
// ************************************************************************** //
// ************** runtime_param::get ************** //
// ************************************************************************** //
/// Access to arguments
BOOST_TEST_DECL runtime::arguments_store const& argument_store();
template<typename T>
inline T const&
get( runtime::cstring parameter_name )
{
return argument_store().get<T>( parameter_name );
}
/// For public access
BOOST_TEST_DECL bool save_pattern();
// ************************************************************************** //
// ************** stream_holder ************** //
// ************************************************************************** //
class stream_holder {
public:
// Constructor
explicit stream_holder( std::ostream& default_stream )
: m_stream( &default_stream )
{
}
void setup( runtime::cstring param_name )
{
if( !runtime_config::argument_store().has( param_name ) )
return;
std::string const& file_name = runtime_config::get<std::string>( param_name );
if( file_name == "stderr" )
m_stream = &std::cerr;
else if( file_name == "stdout" )
m_stream = &std::cout;
else {
m_file.open( file_name.c_str() );
m_stream = &m_file;
}
}
// Access methods
std::ostream& ref() const { return *m_stream; }
private:
// Data members
std::ofstream m_file;
std::ostream* m_stream;
};
} // 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,366 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// @brief 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/framework.hpp>
#include <boost/test/tree/auto_registration.hpp>
#include <boost/test/tree/test_case_template.hpp>
#include <boost/test/tree/global_fixture.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
#include <boost/test/detail/pp_variadic.hpp>
//____________________________________________________________________________//
// ************************************************************************** //
// ************** Non-auto (explicit) test case interface ************** //
// ************************************************************************** //
#define BOOST_TEST_CASE( test_function ) \
boost::unit_test::make_test_case( boost::function<void ()>(test_function), \
BOOST_TEST_STRINGIZE( test_function ), \
__FILE__, __LINE__ )
#define BOOST_CLASS_TEST_CASE( test_function, tc_instance ) \
boost::unit_test::make_test_case( (test_function), \
BOOST_TEST_STRINGIZE( test_function ), \
__FILE__, __LINE__, tc_instance )
// ************************************************************************** //
// ************** BOOST_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_TEST_SUITE( testsuite_name ) \
( new boost::unit_test::test_suite( testsuite_name, __FILE__, __LINE__ ) )
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators ) \
namespace suite_name { \
BOOST_AUTO_TU_REGISTRAR( suite_name )( \
BOOST_STRINGIZE( suite_name ), \
__FILE__, __LINE__, \
decorators ); \
/**/
#define BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
BOOST_AUTO_TEST_SUITE_WITH_DECOR( \
suite_name, \
boost::unit_test::decorator::collector::instance() ) \
/**/
#if BOOST_PP_VARIADICS
#define BOOST_AUTO_TEST_SUITE( ... ) \
BOOST_TEST_INVOKE_IF_N_ARGS( 1, \
BOOST_AUTO_TEST_SUITE_NO_DECOR, \
BOOST_AUTO_TEST_SUITE_WITH_DECOR, \
__VA_ARGS__) \
/**/
#else /* BOOST_PP_VARIADICS */
#define BOOST_AUTO_TEST_SUITE( suite_name ) \
BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
/**/
#endif /* BOOST_PP_VARIADICS */
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_SUITE ************** //
// ************************************************************************** //
#define BOOST_FIXTURE_TEST_SUITE_WITH_DECOR(suite_name, F, decorators) \
BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators ) \
typedef F BOOST_AUTO_TEST_CASE_FIXTURE; \
/**/
#define BOOST_FIXTURE_TEST_SUITE_NO_DECOR( suite_name, F ) \
BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
typedef F BOOST_AUTO_TEST_CASE_FIXTURE; \
/**/
#if BOOST_PP_VARIADICS
#define BOOST_FIXTURE_TEST_SUITE( ... ) \
BOOST_TEST_INVOKE_IF_N_ARGS( 2, \
BOOST_FIXTURE_TEST_SUITE_NO_DECOR, \
BOOST_FIXTURE_TEST_SUITE_WITH_DECOR, \
__VA_ARGS__) \
/**/
#else /* BOOST_PP_VARIADICS */
#define BOOST_FIXTURE_TEST_SUITE( suite_name, F ) \
BOOST_FIXTURE_TEST_SUITE_NO_DECOR( suite_name, F ) \
/**/
#endif /* BOOST_PP_VARIADICS */
// ************************************************************************** //
// ************** 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 ************** //
// ************************************************************************** //
/// @deprecated use decorator instead
#define BOOST_AUTO_TEST_CASE_EXPECTED_FAILURES( test_name, n ) \
BOOST_TEST_DECORATOR( * boost::unit_test::expected_failures( n ) ) \
/**/
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_CASE ************** //
// ************************************************************************** //
#define BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F, decorators ) \
struct test_name : public F { void test_method(); }; \
\
static void BOOST_AUTO_TC_INVOKER( test_name )() \
{ \
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry."); \
test_name t; \
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
t.test_method(); \
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
} \
\
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, __FILE__, __LINE__ ), \
decorators ); \
\
void test_name::test_method() \
/**/
#define BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name, F ) \
BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F, \
boost::unit_test::decorator::collector::instance() ) \
/**/
#if BOOST_PP_VARIADICS
#define BOOST_FIXTURE_TEST_CASE( ... ) \
BOOST_TEST_INVOKE_IF_N_ARGS( 2, \
BOOST_FIXTURE_TEST_CASE_NO_DECOR, \
BOOST_FIXTURE_TEST_CASE_WITH_DECOR, \
__VA_ARGS__) \
/**/
#else /* BOOST_PP_VARIADICS */
#define BOOST_FIXTURE_TEST_CASE( test_name, F ) \
BOOST_FIXTURE_TEST_CASE_NO_DECOR(test_name, F) \
/**/
#endif /* BOOST_PP_VARIADICS */
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_CASE_NO_DECOR( test_name ) \
BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name, \
BOOST_AUTO_TEST_CASE_FIXTURE ) \
/**/
#define BOOST_AUTO_TEST_CASE_WITH_DECOR( test_name, decorators ) \
BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, \
BOOST_AUTO_TEST_CASE_FIXTURE, decorators ) \
/**/
#if BOOST_PP_VARIADICS
#define BOOST_AUTO_TEST_CASE( ... ) \
BOOST_TEST_INVOKE_IF_N_ARGS( 1, \
BOOST_AUTO_TEST_CASE_NO_DECOR, \
BOOST_AUTO_TEST_CASE_WITH_DECOR, \
__VA_ARGS__) \
/**/
#else /* BOOST_PP_VARIADICS */
#define BOOST_AUTO_TEST_CASE( test_name ) \
BOOST_AUTO_TEST_CASE_NO_DECOR( test_name ) \
/**/
#endif /* BOOST_PP_VARIADICS */
// ************************************************************************** //
// ************** BOOST_FIXTURE_TEST_CASE_TEMPLATE ************** //
// ************************************************************************** //
#define BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_name, type_name, TL, F ) \
template<typename type_name> \
struct test_name : public F \
{ void test_method(); }; \
\
struct BOOST_AUTO_TC_INVOKER( test_name ) { \
template<typename TestType> \
static void run( boost::type<TestType>* = 0 ) \
{ \
BOOST_TEST_CHECKPOINT('"' << #test_name <<"\" fixture entry."); \
test_name<TestType> t; \
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
t.test_method(); \
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
} \
}; \
\
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 ), __FILE__, __LINE__ ), \
boost::unit_test::decorator::collector::instance() ); \
\
template<typename type_name> \
void test_name<type_name>::test_method() \
/**/
// ************************************************************************** //
// ************** BOOST_AUTO_TEST_CASE_TEMPLATE ************** //
// ************************************************************************** //
#define BOOST_AUTO_TEST_CASE_TEMPLATE( test_name, type_name, TL ) \
BOOST_FIXTURE_TEST_CASE_TEMPLATE( test_name, type_name, TL, \
BOOST_AUTO_TEST_CASE_FIXTURE ) \
/**/
// ************************************************************************** //
// ************** BOOST_TEST_CASE_TEMPLATE ************** //
// ************************************************************************** //
#define BOOST_TEST_CASE_TEMPLATE( name, typelist ) \
boost::unit_test::ut_detail::template_test_case_gen<name,typelist>( \
BOOST_TEST_STRINGIZE( name ), __FILE__, __LINE__ ) \
/**/
// ************************************************************************** //
// ************** BOOST_TEST_CASE_TEMPLATE_FUNCTION ************** //
// ************************************************************************** //
#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>* ) \
/**/
// ************************************************************************** //
// ************** BOOST_GLOBAL_FIXTURE ************** //
// ************************************************************************** //
#define BOOST_GLOBAL_FIXTURE( F ) \
static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F ) \
/**/
// ************************************************************************** //
// ************** BOOST_TEST_DECORATOR ************** //
// ************************************************************************** //
#define BOOST_TEST_DECORATOR( D ) \
static boost::unit_test::decorator::collector const& \
BOOST_JOIN(decorator_collector,__LINE__) = D; \
/**/
// ************************************************************************** //
// ************** 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 FIXTURE_TEST_SUITE can 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
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER

View File

@@ -0,0 +1,222 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
/// @file
/// Addition to STL algorithms
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_ALGORITHM_HPP
#define BOOST_TEST_UTILS_ALGORITHM_HPP
// STL
#include <utility>
#include <algorithm> // std::find
#include <functional> // std::bind1st
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
/// @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 utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_ALGORITHM_HPP

View File

@@ -0,0 +1,39 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : overloadable assignment
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_ASSIGN_OP_HPP
#define BOOST_TEST_UTILS_ASSIGN_OP_HPP
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_UTILS_ASSIGN_OP_HPP

View File

@@ -0,0 +1,738 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : class basic_cstring wraps C string and provide std_string like
// interface
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_HPP
// Boost.Test
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
#include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>
// Boost
#include <boost/type_traits/remove_cv.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 typename remove_cv<value_type>::type value_ret_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 = static_cast<size_type>(-1) };
#else
// IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
// But size_type is 8 bytes in 64bit mode.
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 );
template<typename LenType>
basic_cstring( pointer s, LenType len ) : m_begin( s ), m_end( m_begin + len ) {}
basic_cstring( pointer first, pointer last );
// data access methods
value_ret_type operator[]( size_type index ) const;
value_ret_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 );
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(800))
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
// VA C++/XL C++ v6 and v8 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() { return trim_left( self_type() ); }
self_type& trim_right() { return trim_right( self_type() ); }
self_type& trim() { return 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 )
{
return *this = basic_cstring<CharT>( s.begin(), s.end() );
}
template<typename PosType, typename LenType>
basic_cstring& assign( self_type const& s, PosType pos, LenType len )
{
return *this = self_type( s.m_begin + pos, len );
}
basic_cstring& assign( std_string const& s );
template<typename PosType, typename LenType>
basic_cstring& assign( std_string const& s, PosType pos, LenType len )
{
return *this = self_type( s.c_str() + pos, len );
}
basic_cstring& assign( pointer s );
template<typename LenType>
basic_cstring& assign( pointer s, LenType len )
{
return *this = self_type( s, 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 first, pointer last )
: m_begin( first )
, m_end( last )
{
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::operator[]( size_type index ) const
{
return m_begin[index];
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
basic_cstring<CharT>::at( size_type index ) const
{
if( m_begin + index >= m_end )
return static_cast<value_type>(0);
return m_begin[index];
}
//____________________________________________________________________________//
template<typename CharT>
inline typename basic_cstring<CharT>::size_type
basic_cstring<CharT>::size() const
{
return static_cast<size_type>(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 ) == reinterpret_cast<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 ) == reinterpret_cast<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( std_string const& s )
{
return *this = self_type( s );
}
//____________________________________________________________________________//
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 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 static_cast<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 ? npos : static_cast<size_type>(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 static_cast<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 ? static_cast<size_type>(npos) : static_cast<size_type>(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_ret_type
first_char( basic_cstring<CharT> source )
{
typedef typename basic_cstring<CharT>::value_ret_type res_type;
return source.is_empty() ? static_cast<res_type>(0) : *source.begin();
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** last_char ************** //
// ************************************************************************** //
template<typename CharT>
inline typename basic_cstring<CharT>::value_ret_type
last_char( basic_cstring<CharT> source )
{
typedef typename basic_cstring<CharT>::value_ret_type res_type;
return source.is_empty() ? static_cast<res_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() );
}
//____________________________________________________________________________//
template<typename CharT1, typename CharT2>
inline std::basic_string<CharT1>&
operator+=( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& str )
{
target.append( str.begin(), str.end() );
return target;
}
//____________________________________________________________________________//
template<typename CharT1, typename CharT2>
inline std::basic_string<CharT1>
operator+( std::basic_string<CharT1> const& lhs, basic_cstring<CharT2> const& rhs )
{
std::basic_string<CharT1> res( lhs );
res.append( rhs.begin(), rhs.end() );
return res;
}
//____________________________________________________________________________//
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_BASIC_CSTRING_HPP

View File

@@ -0,0 +1,40 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : basic_cstring class wrap C string and provide std_string like
// interface
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
#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_UTILS_BASIC_CSTRING_FWD_HPP

View File

@@ -0,0 +1,150 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : generic char traits class; wraps std::char_traits
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
#define BOOST_TEST_UTILS_BCS_CHAR_TRAITS_HPP
// 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> : public char_traits_with_find<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : public char_traits_with_find<wchar_t> {};
#else
template<> struct bcs_char_traits_impl<char> : public std::char_traits<char> {};
template<> struct bcs_char_traits_impl<wchar_t> : public 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_UTILS_BCS_CHAR_TRAITS_HPP

View File

@@ -0,0 +1,147 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : class basic_cstring comparisons implementation
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_COMPARE_HPP
// 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;
}
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** operators <,> ************** //
// ************************************************************************** //
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;
}
//____________________________________________________________________________//
template<class CharT>
inline bool
operator <=( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
return !(y < x);
}
//____________________________________________________________________________//
template<class CharT>
inline bool
operator >( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
return y < x;
}
//____________________________________________________________________________//
template<class CharT>
inline bool
operator >=( boost::unit_test::basic_cstring<CharT> const& x,
boost::unit_test::basic_cstring<CharT> const& y )
{
return !(x < y);
}
//____________________________________________________________________________//
} // 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 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : basic_cstring i/o implementation
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
#define BOOST_TEST_UTILS_BASIC_CSTRING_IO_HPP
// 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,195 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple facility that mimmic notion of read-only read-write
// properties in C++ classes. Original idea by Henrik Ravn.
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
#define BOOST_TEST_UTILS_CLASS_PROPERTIES_HPP
// 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;
typedef typename add_pointer<typename add_const<PropertyType>::type>::type address_res_t;
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
// ************************************************************************** //
// ************** 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_UTILS_CLASS_PROPERTIES_HPP

View File

@@ -0,0 +1,61 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple helpers for creating cusom output manipulators
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
#define BOOST_TEST_UTILS_CUSTOM_MANIP_HPP
// STL
#include <iosfwd>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** 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 utils
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_CUSTOM_MANIP_HPP

View File

@@ -0,0 +1,316 @@
// (C) Copyright Eric Niebler 2004-2005
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : this is an abridged version of an excelent BOOST_FOREACH facility
// presented by Eric Niebler. I am so fond of it so I can'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_UTILS_FOREACH_HPP
#define BOOST_TEST_UTILS_FOREACH_HPP
// 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 );
}
//____________________________________________________________________________//
// ************************************************************************** //
// ************** prev ************** //
// ************************************************************************** //
template<typename C>
inline void
prev( static_any_t cur, C&, mpl::false_ )
{
--static_any_cast<BOOST_DEDUCED_TYPENAME C::iterator>( cur );
}
//____________________________________________________________________________//
template<typename C>
inline void
prev( 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_TEST_FE_PREV( COL ) \
::boost::unit_test::for_each::prev( \
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 ) \
/**/
#define BOOST_TEST_REVERSE_FOREACH( RefType, var, COL ) \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_CUR_VAR = BOOST_TEST_FE_END( COL ) ) {} else \
if( BOOST_TEST_FE_ANY BOOST_TEST_FE_END_VAR = BOOST_TEST_FE_BEG( COL ) ) {} else \
for( bool BOOST_TEST_FE_CON_VAR = true; \
BOOST_TEST_FE_CON_VAR && !BOOST_TEST_FE_DONE( COL ); ) \
\
if( (BOOST_TEST_FE_CON_VAR = false, false) ) {} else \
if( (BOOST_TEST_FE_PREV( COL ), 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_UTILS_FOREACH_HPP

View File

@@ -0,0 +1,58 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : defines the is_cstring type trait
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_IS_CSTRING_HPP
#define BOOST_TEST_UTILS_IS_CSTRING_HPP
// Boost
#include <boost/mpl/bool.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/decay.hpp>
#include <boost/type_traits/remove_pointer.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** is_cstring ************** //
// ************************************************************************** //
namespace ut_detail {
template<typename T>
struct is_cstring_impl : public mpl::false_ {};
template<typename T>
struct is_cstring_impl<T const*> : public is_cstring_impl<T*> {};
template<typename T>
struct is_cstring_impl<T const* const> : public is_cstring_impl<T*> {};
template<>
struct is_cstring_impl<char*> : public mpl::true_ {};
template<>
struct is_cstring_impl<wchar_t*> : public mpl::true_ {};
} // namespace ut_detail
template<typename T>
struct is_cstring : public ut_detail::is_cstring_impl<typename decay<T>::type> {};
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_IS_CSTRING_HPP

View File

@@ -0,0 +1,166 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//! @file
//! Defines the is_forward_iterable collection type trait
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
#define BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP
#if defined(BOOST_NO_CXX11_DECLTYPE) || \
defined(BOOST_NO_CXX11_NULLPTR) || \
defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
// some issues with boost.config
#if !defined(BOOST_MSVC) || BOOST_MSVC_FULL_VER < 170061030 /* VC2012 upd 5 */
#define BOOST_TEST_FWD_ITERABLE_CXX03
#endif
#endif
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03)
// Boost
#include <boost/mpl/bool.hpp>
// STL
#include <list>
#include <vector>
#include <map>
#include <set>
#else
// Boost
#include <boost/utility/declval.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/test/utils/is_cstring.hpp>
// STL
#include <utility>
#include <type_traits>
#endif
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
// ************************************************************************** //
// ************** is_forward_iterable ************** //
// ************************************************************************** //
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) && !defined(BOOST_TEST_DOXYGEN_DOC__)
template<typename T>
struct is_forward_iterable : public mpl::false_ {};
template<typename T>
struct is_forward_iterable<T const> : public is_forward_iterable<T> {};
template<typename T>
struct is_forward_iterable<T&> : public is_forward_iterable<T> {};
template<typename T, typename A>
struct is_forward_iterable< std::vector<T, A> > : public mpl::true_ {};
template<typename T, typename A>
struct is_forward_iterable< std::list<T, A> > : public mpl::true_ {};
template<typename K, typename V, typename C, typename A>
struct is_forward_iterable< std::map<K, V, C, A> > : public mpl::true_ {};
template<typename K, typename C, typename A>
struct is_forward_iterable< std::set<K, C, A> > : public mpl::true_ {};
#else
namespace ut_detail {
template<typename T>
struct is_present : public mpl::true_ {};
//____________________________________________________________________________//
// some compiler do not implement properly decltype non expression involving members (eg. VS2013)
// a workaround is to use -> decltype syntax.
template <class T>
struct has_member_size {
private:
struct nil_t {};
template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().size());
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
};
//____________________________________________________________________________//
template <class T>
struct has_member_begin {
private:
struct nil_t {};
template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().begin());
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
};
//____________________________________________________________________________//
template <class T>
struct has_member_end {
private:
struct nil_t {};
template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().end());
template<typename> static nil_t test( ... );
public:
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
};
//____________________________________________________________________________//
template <class T, class enabled = void>
struct is_forward_iterable_impl : std::false_type {
};
//____________________________________________________________________________//
template <class T>
struct is_forward_iterable_impl<
T,
typename std::enable_if<
is_present<typename T::const_iterator>::value &&
is_present<typename T::value_type>::value &&
has_member_size<T>::value &&
has_member_begin<T>::value &&
has_member_end<T>::value &&
!is_cstring<T>::value
>::type
> : std::true_type
{};
//____________________________________________________________________________//
} // namespace ut_detail
/*! Indicates that a specific type implements the forward iterable concept. */
template<typename T>
struct is_forward_iterable {
typedef typename std::remove_reference<T>::type T_ref;
typedef ut_detail::is_forward_iterable_impl<T_ref> is_fwd_it_t;
typedef mpl::bool_<is_fwd_it_t::value> type;
enum { value = is_fwd_it_t::value };
};
#endif /* defined(BOOST_TEST_FWD_ITERABLE_CXX03) */
} // namespace unit_test
} // namespace boost
#endif // BOOST_TEST_UTILS_IS_FORWARD_ITERABLE_HPP

View File

@@ -0,0 +1,105 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
//!@file
//! Input iterator facade
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
#define BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP
// Boost
#include <boost/iterator/iterator_facade.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace unit_test {
namespace utils {
// ************************************************************************** //
// ************** 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 utils
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_INPUT_ITERATOR_FACADE_HPP

View File

@@ -0,0 +1,417 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : token iterator for string and range tokenization
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
#define BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP
// 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 {
namespace utils {
// ************************************************************************** //
// ************** 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 type_ = dt_char, cstring delimeters_ = cstring() )
: m_type( type_ )
{
set_delimeters( delimeters_ );
}
void set_delimeters( ti_delimeter_type type_ ) { m_type = type_; }
void set_delimeters( cstring delimeters_ )
{
m_delimeters = delimeters_;
if( !m_delimeters.is_empty() )
m_type = dt_char;
}
void set_delimeters( nfp::nil ) {}
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( static_cast<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::opt_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 utils
} // namespace unit_test
} // namespace boost
//____________________________________________________________________________//
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_TOKEN_ITERATOR_HPP

View File

@@ -0,0 +1,128 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// Description : contains definition for all test tools in test toolbox
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
#define BOOST_TEST_UTILS_LAZY_OSTREAM_HPP
// 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:
virtual ~lazy_ostream() {}
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 p_empty = true ) : m_empty( p_empty ) {}
private:
// Data members
bool m_empty;
};
//____________________________________________________________________________//
template<typename PrevType, typename T, typename StorageT=T const&>
class lazy_ostream_impl : public lazy_ostream {
public:
lazy_ostream_impl( PrevType const& prev, T const& value )
: lazy_ostream( false )
, m_prev( prev )
, m_value( value )
{
}
virtual std::ostream& operator()( std::ostream& ostr ) const
{
return m_prev(ostr) << m_value;
}
private:
// Data members
PrevType const& m_prev;
StorageT m_value;
};
//____________________________________________________________________________//
template<typename T>
inline lazy_ostream_impl<lazy_ostream,T>
operator<<( lazy_ostream const& prev, T const& v )
{
return lazy_ostream_impl<lazy_ostream,T>( prev, v );
}
//____________________________________________________________________________//
template<typename PrevPrevType, typename TPrev, typename T>
inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,T>
operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, T const& v )
{
typedef lazy_ostream_impl<PrevPrevType,TPrev> PrevType;
return lazy_ostream_impl<PrevType,T>( prev, v );
}
//____________________________________________________________________________//
#if BOOST_TEST_USE_STD_LOCALE
template<typename R,typename S>
inline lazy_ostream_impl<lazy_ostream,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
return lazy_ostream_impl<lazy_ostream,ManipType,ManipType>( prev, man );
}
//____________________________________________________________________________//
template<typename PrevPrevType, typename TPrev,typename R,typename S>
inline lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,R& (BOOST_TEST_CALL_DECL *)(S&),R& (BOOST_TEST_CALL_DECL *)(S&)>
operator<<( lazy_ostream_impl<PrevPrevType,TPrev> const& prev, R& (BOOST_TEST_CALL_DECL *man)(S&) )
{
typedef R& (BOOST_TEST_CALL_DECL * ManipType)(S&);
return lazy_ostream_impl<lazy_ostream_impl<PrevPrevType,TPrev>,ManipType,ManipType>( prev, man );
}
//____________________________________________________________________________//
#endif
#define BOOST_TEST_LAZY_MSG( M ) (::boost::unit_test::lazy_ostream::instance() << M)
} // namespace unit_test
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_LAZY_OSTREAM_HPP

View File

@@ -0,0 +1,388 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : named function parameters library
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_NAMED_PARAM
#define BOOST_TEST_UTILS_NAMED_PARAM
// 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/type_traits/remove_reference.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/test/detail/throw_exception.hpp>
// Boost
#include <boost/mpl/if.hpp>
#include <boost/mpl/or.hpp>
#include <boost/type_traits/is_same.hpp>
#include <boost/type_traits/remove_cv.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/mpl/bool.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
namespace boost {
namespace nfp { // named function parameters
// ************************************************************************** //
// ************** forward declarations ************** //
// ************************************************************************** //
template<typename unique_id, bool required> struct keyword;
template<typename T, typename unique_id, bool required = false> struct typed_keyword;
template<typename T, typename unique_id, typename RefType=T&> struct named_parameter;
template<typename NP1,typename NP2> struct named_parameter_combine;
// ************************************************************************** //
// ************** is_named_param_pack ************** //
// ************************************************************************** //
/// is_named_param_pack<T>::value is true if T is parameters pack
template<typename T>
struct is_named_param_pack : public mpl::false_ {};
template<typename T, typename unique_id, typename RefType>
struct is_named_param_pack<named_parameter<T,unique_id,RefType> > : public mpl::true_ {};
template<typename NP, typename Rest>
struct is_named_param_pack<named_parameter_combine<NP,Rest> > : public mpl::true_ {};
// ************************************************************************** //
// ************** param_type ************** //
// ************************************************************************** //
/// param_type<Params,Keyword,Default>::type is is the type of the parameter
/// corresponding to the Keyword (if parameter is present) or Default
template<typename NP, typename Keyword, typename DefaultType=void>
struct param_type
: mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
typename remove_cv<typename NP::data_type>::type,
DefaultType> {};
template<typename NP, typename Rest, typename Keyword, typename DefaultType>
struct param_type<named_parameter_combine<NP,Rest>,Keyword,DefaultType>
: mpl::if_<typename is_same<typename NP::id,typename Keyword::id>::type,
typename remove_cv<typename NP::data_type>::type,
typename param_type<Rest,Keyword,DefaultType>::type> {};
// ************************************************************************** //
// ************** has_param ************** //
// ************************************************************************** //
/// has_param<Params,Keyword>::value is true id Params has parameter corresponding
/// to the Keyword
template<typename NP, typename Keyword>
struct has_param : is_same<typename NP::id,typename Keyword::id> {};
template<typename NP, typename Rest, typename Keyword>
struct has_param<named_parameter_combine<NP,Rest>,Keyword>
: mpl::or_<typename is_same<typename NP::id,typename Keyword::id>::type,
typename has_param<Rest,Keyword>::type> {};
// ************************************************************************** //
// ************** access_to_invalid_parameter ************** //
// ************************************************************************** //
namespace nfp_detail {
struct access_to_invalid_parameter {};
//____________________________________________________________________________//
inline void
report_access_to_invalid_parameter( bool v )
{
BOOST_TEST_I_ASSRT( !v, access_to_invalid_parameter() );
}
} // namespace nfp_detail
// ************************************************************************** //
// ************** nil ************** //
// ************************************************************************** //
struct nil {
template<typename T>
#if defined(__GNUC__) || defined(__HP_aCC) || defined(__EDG__) || defined(__SUNPRO_CC)
operator T() const
#else
operator T const&() const
#endif
{ nfp_detail::report_access_to_invalid_parameter(true); static T* v = 0; return *v; }
template<typename T>
T any_cast() const
{ nfp_detail::report_access_to_invalid_parameter(true); static typename remove_reference<T>::type* v = 0; return *v; }
template<typename Arg1>
nil operator()( Arg1 const& )
{ nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
template<typename Arg1,typename Arg2>
nil operator()( Arg1 const&, Arg2 const& )
{ nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
template<typename Arg1,typename Arg2,typename Arg3>
nil operator()( Arg1 const&, Arg2 const&, Arg3 const& )
{ nfp_detail::report_access_to_invalid_parameter(true); return nil(); }
// Visitation support
template<typename Visitor>
void apply_to( Visitor& /*v*/ ) const {}
static nil& inst() { static nil s_inst; return s_inst; }
private:
nil() {}
};
// ************************************************************************** //
// ************** named_parameter_base ************** //
// ************************************************************************** //
namespace nfp_detail {
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) ); }
};
} // namespace nfp_detail
// ************************************************************************** //
// ************** named_parameter_combine ************** //
// ************************************************************************** //
template<typename NP, typename Rest = nil>
struct named_parameter_combine
: Rest
, nfp_detail::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> kw ) const { return m_param.has( kw ); }
using Rest::has;
void erase( keyword<typename NP::id,false> kw ) const { m_param.erase( kw ); }
using Rest::erase;
using nfp_detail::named_parameter_base<named_parameter_combine<NP,Rest> >::operator,;
// 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;
};
// ************************************************************************** //
// ************** named_parameter ************** //
// ************************************************************************** //
template<typename T, typename unique_id, typename RefType>
struct named_parameter
: nfp_detail::named_parameter_base<named_parameter<T,unique_id,RefType> >
{
typedef T data_type;
typedef RefType ref_type;
typedef unique_id id;
// Constructor
explicit named_parameter( ref_type v )
: m_value( v )
, m_erased( false )
{}
named_parameter( named_parameter const& np )
: m_value( np.m_value )
, m_erased( np.m_erased )
{}
// Access methods
ref_type operator[]( keyword<unique_id,true> ) const { return m_erased ? nil::inst().template any_cast<ref_type>() : m_value; }
ref_type operator[]( keyword<unique_id,false> ) const { return m_erased ? nil::inst().template any_cast<ref_type>() : m_value; }
template<typename UnknownId>
nil operator[]( keyword<UnknownId,false> ) const { return nil::inst(); }
bool has( keyword<unique_id,false> ) const { return !m_erased; }
template<typename UnknownId>
bool has( keyword<UnknownId,false> ) const { return false; }
void erase( keyword<unique_id,false> ) const { m_erased = true; }
template<typename UnknownId>
void erase( keyword<UnknownId,false> ) const {}
// 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;
mutable bool m_erased;
};
// ************************************************************************** //
// ************** no_params ************** //
// ************************************************************************** //
typedef named_parameter<char, struct no_params_type_t,char> no_params_type;
namespace {
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>
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, bool required>
struct typed_keyword<bool,unique_id,required>
: keyword<unique_id,required>
, 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 ); }
};
// ************************************************************************** //
// ************** opt_assign ************** //
// ************************************************************************** //
template<typename T, typename Params, typename Keyword>
inline typename enable_if_c<!has_param<Params,Keyword>::value,void>::type
opt_assign( T& /*target*/, Params const& /*p*/, Keyword /*k*/ )
{
}
//____________________________________________________________________________//
template<typename T, typename Params, typename Keyword>
inline typename enable_if_c<has_param<Params,Keyword>::value,void>::type
opt_assign( T& target, Params const& p, Keyword k )
{
using namespace unit_test;
assign_op( target, p[k], static_cast<int>(0) );
}
// ************************************************************************** //
// ************** opt_get ************** //
// ************************************************************************** //
template<typename T, typename Params, typename Keyword>
inline T
opt_get( Params const& p, Keyword k, T default_val )
{
opt_assign( default_val, p, k );
return default_val;
}
// ************************************************************************** //
// ************** opt_get ************** //
// ************************************************************************** //
template<typename Params, typename NP>
inline typename enable_if_c<!has_param<Params,keyword<typename NP::id> >::value,
named_parameter_combine<NP,Params> >::type
opt_append( Params const& params, NP const& np )
{
return (params,np);
}
//____________________________________________________________________________//
template<typename Params, typename NP>
inline typename enable_if_c<has_param<Params,keyword<typename NP::id> >::value,Params>::type
opt_append( Params const& params, NP const& )
{
return params;
}
} // namespace nfp
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_NAMED_PARAM

View File

@@ -0,0 +1,63 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : simple facilities for accessing type information at runtime
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RTTI_HPP
#define BOOST_TEST_UTILS_RTTI_HPP
// C Runtime
#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_TEST_UTILS_RTTI_HPP

View File

@@ -0,0 +1,131 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : model of actual argument (both typed and abstract interface)
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
#define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/utils/runtime/errors.hpp>
// Boost.Test
#include <boost/test/utils/class_properties.hpp>
#include <boost/test/utils/rtti.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/detail/throw_exception.hpp>
// STL
#include <cassert>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
// ************************************************************************** //
// ************** runtime::argument ************** //
// ************************************************************************** //
class argument {
public:
// Constructor
argument( rtti::id_t value_type )
: p_value_type( value_type )
{}
// Destructor
virtual ~argument() {}
// Public properties
rtti::id_t const p_value_type;
};
// ************************************************************************** //
// ************** runtime::typed_argument ************** //
// ************************************************************************** //
template<typename T>
class typed_argument : public argument {
public:
// Constructor
explicit typed_argument( T const& v )
: argument( rtti::type_id<T>() )
, p_value( v )
{}
unit_test::readwrite_property<T> p_value;
};
// ************************************************************************** //
// ************** runtime::arguments_store ************** //
// ************************************************************************** //
class arguments_store {
public:
typedef std::map<cstring, argument_ptr> storage_type;
/// Returns number of arguments in the store; mostly used for testing
std::size_t size() const { return m_arguments.size(); }
/// Clears the store for reuse
void clear() { m_arguments.clear(); }
/// Returns true if there is an argument corresponding to the specified parameter name
bool has( cstring parameter_name ) const
{
return m_arguments.find( parameter_name ) != m_arguments.end();
}
/// Provides types access to argument value by parameter name
template<typename T>
T const& get( cstring parameter_name ) const {
return const_cast<arguments_store*>(this)->get<T>( parameter_name );
}
template<typename T>
T& get( cstring parameter_name ) {
storage_type::const_iterator found = m_arguments.find( parameter_name );
BOOST_TEST_I_ASSRT( found != m_arguments.end(),
access_to_missing_argument()
<< "There is no argument provided for parameter "
<< parameter_name );
argument_ptr arg = found->second;
BOOST_TEST_I_ASSRT( arg->p_value_type == rtti::type_id<T>(),
arg_type_mismatch()
<< "Access with invalid type for argument corresponding to parameter "
<< parameter_name );
return static_cast<typed_argument<T>&>( *arg ).p_value.value;
}
/// Set's the argument value for specified parameter name
template<typename T>
void set( cstring parameter_name, T const& value )
{
m_arguments[parameter_name] = argument_ptr( new typed_argument<T>( value ) );
}
private:
// Data members
storage_type m_arguments;
};
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_HPP

View File

@@ -0,0 +1,242 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : argument factories for different kinds of parameters
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
#define BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/errors.hpp>
#include <boost/test/utils/runtime/argument.hpp>
// Boost.Test
#include <boost/test/utils/basic_cstring/io.hpp>
#include <boost/test/utils/basic_cstring/compare.hpp>
#include <boost/test/utils/string_cast.hpp>
// Boost
#include <boost/function/function2.hpp>
// STL
#include <vector>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
// ************************************************************************** //
// ************** runtime::value_interpreter ************** //
// ************************************************************************** //
template<typename ValueType, bool is_enum>
struct value_interpreter;
//____________________________________________________________________________//
template<typename ValueType>
struct value_interpreter<ValueType, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
ValueType interpret( cstring param_name, cstring source ) const
{
ValueType res;
if( !unit_test::utils::string_as<ValueType>( source, res ) )
BOOST_TEST_I_THROW( format_error( param_name ) << source <<
" can't be interpreted as value of parameter " << param_name << "." );
return res;
}
};
//____________________________________________________________________________//
template<>
struct value_interpreter<std::string, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
std::string interpret( cstring, cstring source ) const
{
return std::string( source.begin(), source.size() );
}
};
//____________________________________________________________________________//
template<>
struct value_interpreter<cstring, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
cstring interpret( cstring, cstring source ) const
{
return source;
}
};
//____________________________________________________________________________//
template<>
struct value_interpreter<bool, false> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& ) {}
bool interpret( cstring param_name, cstring source ) const
{
static cstring const s_YES( "YES" );
static cstring const s_Y( "Y" );
static cstring const s_NO( "NO" );
static cstring const s_N( "N" );
static cstring const s_TRUE( "TRUE" );
static cstring const s_FALSE( "FALSE" );
static cstring const s_one( "1" );
static cstring const s_zero( "0" );
source.trim();
if( source.is_empty() ||
case_ins_eq( source, s_YES ) ||
case_ins_eq( source, s_Y ) ||
case_ins_eq( source, s_one ) ||
case_ins_eq( source, s_TRUE ) )
return true;
if( case_ins_eq( source, s_NO ) ||
case_ins_eq( source, s_N ) ||
case_ins_eq( source, s_zero ) ||
case_ins_eq( source, s_FALSE ) )
return false;
BOOST_TEST_I_THROW( format_error( param_name ) << source << " can't be interpreted as bool value." );
}
};
//____________________________________________________________________________//
template<typename EnumType>
struct value_interpreter<EnumType, true> {
template<typename Modifiers>
explicit value_interpreter( Modifiers const& m )
#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
: m_name_to_value( m[enum_values<EnumType>::value] )
{
}
#else
{
std::vector<std::pair<cstring,EnumType> > const& values = m[enum_values<EnumType>::value];
m_name_to_value.insert( values.begin(), values.end() );
}
#endif
EnumType interpret( cstring param_name, cstring source ) const
{
typename std::map<cstring,EnumType>::const_iterator found = m_name_to_value.find( source );
BOOST_TEST_I_ASSRT( found != m_name_to_value.end(),
format_error( param_name ) << source <<
" is not a valid enumeration value name for parameter " << param_name << "." );
return found->second;
}
private:
// Data members
std::map<cstring,EnumType> m_name_to_value;
};
//____________________________________________________________________________//
// ************************************************************************** //
// ************** runtime::argument_factory ************** //
// ************************************************************************** //
template<typename ValueType, bool is_enum, bool repeatable>
class argument_factory;
//____________________________________________________________________________//
template<typename ValueType, bool is_enum>
class argument_factory<ValueType, is_enum, false> {
public:
template<typename Modifiers>
explicit argument_factory( Modifiers const& m )
: m_interpreter( m )
, m_optional_value( nfp::opt_get( m, optional_value, ValueType() ) )
, m_default_value( nfp::opt_get( m, default_value, ValueType() ) )
{
}
void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
{
store.set( param_name, source.empty() ? m_optional_value : m_interpreter.interpret( param_name, source ) );
}
void produce_default( cstring param_name, arguments_store& store ) const
{
store.set( param_name, m_default_value );
}
private:
// Data members
typedef value_interpreter<ValueType, is_enum> interp_t;
interp_t m_interpreter;
ValueType m_optional_value;
ValueType m_default_value;
};
//____________________________________________________________________________//
template<typename ValueType, bool is_enum>
class argument_factory<ValueType, is_enum, true> {
public:
template<typename Modifiers>
explicit argument_factory( Modifiers const& m )
: m_interpreter( m )
{
}
void produce_argument( cstring source, cstring param_name, arguments_store& store ) const
{
ValueType value = m_interpreter.interpret( param_name, source );
if( store.has( param_name ) ) {
std::vector<ValueType>& values = store.get<std::vector<ValueType> >( param_name );
values.push_back( value );
}
else {
std::vector<ValueType> values( 1, value );
store.set( param_name, values );
}
}
void produce_default( cstring param_name, arguments_store& store ) const
{
store.set( param_name, std::vector<ValueType>() );
}
private:
// Data members
value_interpreter<ValueType, is_enum> m_interpreter;
};
//____________________________________________________________________________//
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_ARGUMENT_FACTORY_HPP

View File

@@ -0,0 +1,105 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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$
//
// Description : defines facility to hide input traversing details
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
#define BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/fwd.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::argv_traverser ************** //
// ************************************************************************** //
class argv_traverser {
typedef char const** argv_type;
public:
/// Constructs traverser based on argc/argv pair
/// argv is taken "by reference" and later can be
/// updated in remainder method
argv_traverser( int argc, argv_type argv )
: m_argc( argc )
, m_curr_token( 0 )
, m_token_size( 0 )
, m_argv( argv )
{
// save program name
save_token();
}
/// Returns new argc
int remainder()
{
return m_argc;
}
/// Returns true, if we reached end on input
bool eoi() const
{
return m_curr_token == m_argc;
}
/// Returns current token in the input
cstring current_token()
{
if( eoi() )
return cstring();
return cstring( m_argv[m_curr_token], m_token_size );
}
/// Saves current token for remainder
void save_token()
{
++m_curr_token;
if( !eoi() )
m_token_size = ::strlen( m_argv[m_curr_token] );
}
/// Commit current token and iterate to next one
void next_token()
{
if( !eoi() ) {
for( std::size_t i = m_curr_token; i < m_argc-1; ++i )
m_argv[i] = m_argv[i + 1];
--m_argc;
m_token_size = ::strlen( m_argv[m_curr_token] );
}
}
private:
// Data members
std::size_t m_argc; // total number of arguments
std::size_t m_curr_token; // current token index in argv
std::size_t m_token_size; // current token size
argv_type m_argv; // all arguments
};
} // namespace cla
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_CLA_ARGV_TRAVERSER_HPP

View File

@@ -0,0 +1,491 @@
// (C) Copyright Gennadiy Rozental 2001.
// 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
//!@brief CLA parser
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
#define BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/utils/runtime/modifier.hpp>
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/cla/argv_traverser.hpp>
// Boost.Test
#include <boost/test/utils/foreach.hpp>
#include <boost/test/utils/algorithm.hpp>
#include <boost/test/detail/throw_exception.hpp>
#include <boost/algorithm/cxx11/all_of.hpp> // !! ?? unnecessary after cxx11
// STL
// !! ?? #include <unordered_set>
#include <set>
#include <iostream>
#include <boost/test/detail/suppress_warnings.hpp>
namespace boost {
namespace runtime {
namespace cla {
// ************************************************************************** //
// ************** runtime::cla::parameter_trie ************** //
// ************************************************************************** //
namespace rt_cla_detail {
struct parameter_trie;
typedef shared_ptr<parameter_trie> parameter_trie_ptr;
typedef std::map<char,parameter_trie_ptr> trie_per_char;
typedef std::vector<boost::reference_wrapper<parameter_cla_id const> > param_cla_id_list;
struct parameter_trie {
parameter_trie() : m_has_final_candidate( false ) {}
/// If subtrie corresponding to the char c exists returns it otherwise creates new
parameter_trie_ptr make_subtrie( char c )
{
trie_per_char::const_iterator it = m_subtrie.find( c );
if( it == m_subtrie.end() )
it = m_subtrie.insert( std::make_pair( c, parameter_trie_ptr( new parameter_trie ) ) ).first;
return it->second;
}
/// Creates series of sub-tries per characters in a string
parameter_trie_ptr make_subtrie( cstring s )
{
parameter_trie_ptr res;
BOOST_TEST_FOREACH( char, c, s )
res = (res ? res->make_subtrie( c ) : make_subtrie( c ));
return res;
}
/// Registers candidate parameter for this subtrie. If final, it needs to be unique
void add_candidate_id( parameter_cla_id const& param_id, basic_param_ptr param_candidate, bool final )
{
BOOST_TEST_I_ASSRT( !m_has_final_candidate && (!final || m_id_candidates.empty()),
conflicting_param() << "Parameter cla id " << param_id.m_tag << " conflicts with the "
<< "parameter cla id " << m_id_candidates.back().get().m_tag );
m_has_final_candidate = final;
m_id_candidates.push_back( ref(param_id) );
if( m_id_candidates.size() == 1 )
m_param_candidate = param_candidate;
else
m_param_candidate.reset();
}
/// Gets subtrie for specified char if present or nullptr otherwise
parameter_trie_ptr get_subtrie( char c ) const
{
trie_per_char::const_iterator it = m_subtrie.find( c );
return it != m_subtrie.end() ? it->second : parameter_trie_ptr();
}
// Data members
trie_per_char m_subtrie;
param_cla_id_list m_id_candidates;
basic_param_ptr m_param_candidate;
bool m_has_final_candidate;
};
// ************************************************************************** //
// ************** runtime::cla::report_foreing_token ************** //
// ************************************************************************** //
static void
report_foreing_token( cstring program_name, cstring token )
{
std::cerr << "Boost.Test WARNING: token \"" << token << "\" does not correspond to the Boost.Test argument \n"
<< " and should be placed after all Boost.Test arguments and the -- separator.\n"
<< " For example: " << program_name << " --random -- " << token << "\n";
}
} // namespace rt_cla_detail
// ************************************************************************** //
// ************** runtime::cla::parser ************** //
// ************************************************************************** //
class parser {
public:
/// Initializes a parser and builds internal trie representation used for
/// parsing based on the supplied parameters
#ifndef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
template<typename Modifiers=nfp::no_params_type>
parser( parameters_store const& parameters, Modifiers const& m = nfp::no_params )
#else
template<typename Modifiers>
parser( parameters_store const& parameters, Modifiers const& m )
#endif
{
nfp::opt_assign( m_end_of_param_indicator, m, end_of_params );
nfp::opt_assign( m_negation_prefix, m, negation_prefix );
BOOST_TEST_I_ASSRT( algorithm::all_of( m_end_of_param_indicator.begin(),
m_end_of_param_indicator.end(),
parameter_cla_id::valid_prefix_char ),
invalid_cla_id() << "End of parameters indicator can only consist of prefix characters." );
BOOST_TEST_I_ASSRT( algorithm::all_of( m_negation_prefix.begin(),
m_negation_prefix.end(),
parameter_cla_id::valid_name_char ),
invalid_cla_id() << "Negation prefix can only consist of prefix characters." );
build_trie( parameters );
}
// input processing method
int
parse( int argc, char** argv, runtime::arguments_store& res )
{
// save program name for help message
m_program_name = argv[0];
cstring path_sep( "\\/" );
cstring::iterator it = unit_test::utils::find_last_of( m_program_name.begin(), m_program_name.end(),
path_sep.begin(), path_sep.end() );
if( it != m_program_name.end() )
m_program_name.trim_left( it + 1 );
// Set up the traverser
argv_traverser tr( argc, (char const**)argv );
// Loop till we reach end of input
while( !tr.eoi() ) {
cstring curr_token = tr.current_token();
cstring prefix;
cstring name;
cstring value_separator;
bool negative_form = false;
// Perform format validations and split the argument into prefix, name and separator
// False return value indicates end of params indicator is met
if( !validate_token_format( curr_token, prefix, name, value_separator, negative_form ) ) {
// get rid of "end of params" token
tr.next_token();
break;
}
// Locate trie corresponding to found prefix and skip it in the input
trie_ptr curr_trie = m_param_trie[prefix];
if( !curr_trie ) {
// format_error() << "Unrecognized parameter prefix in the argument " << tr.current_token()
rt_cla_detail::report_foreing_token( m_program_name, curr_token );
tr.save_token();
continue;
}
curr_token.trim_left( prefix.size() );
// Locate parameter based on a name and skip it in the input
locate_result locate_res = locate_parameter( curr_trie, name, curr_token );
parameter_cla_id const& found_id = locate_res.first;
basic_param_ptr found_param = locate_res.second;
if( negative_form ) {
BOOST_TEST_I_ASSRT( found_id.m_negatable,
format_error( found_param->p_name )
<< "Parameter tag " << found_id.m_tag << " is not negatable." );
curr_token.trim_left( m_negation_prefix.size() );
}
curr_token.trim_left( name.size() );
cstring value;
// Skip validations if parameter has optional value and we are at the end of token
if( !value_separator.is_empty() || !found_param->p_has_optional_value ) {
// Validate and skip value separator in the input
BOOST_TEST_I_ASSRT( found_id.m_value_separator == value_separator,
format_error( found_param->p_name )
<< "Invalid separator for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
curr_token.trim_left( value_separator.size() );
// Deduce value source
value = curr_token;
if( value.is_empty() ) {
tr.next_token();
value = tr.current_token();
}
BOOST_TEST_I_ASSRT( !value.is_empty(),
format_error( found_param->p_name )
<< "Missing an argument value for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
}
// Validate against argument duplication
BOOST_TEST_I_ASSRT( !res.has( found_param->p_name ) || found_param->p_repeatable,
duplicate_arg( found_param->p_name )
<< "Duplicate argument value for the parameter "
<< found_param->p_name
<< " in the argument " << tr.current_token() );
// Produce argument value
found_param->produce_argument( value, negative_form, res );
tr.next_token();
}
// generate the remainder and return it's size
return tr.remainder();
}
// help/usage
void
usage( std::ostream& ostr, cstring param_name = cstring() )
{
if( !param_name.is_empty() ) {
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
param->usage( ostr, m_negation_prefix );
}
else {
ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
if( !m_end_of_param_indicator.empty() )
ostr << m_end_of_param_indicator << " [custom test module argument]...";
ostr << "\n";
}
ostr << "\nFor detailed help on Boost.Test parameters use:\n"
<< " " << m_program_name << " --help\n"
<< "or\n"
<< " " << m_program_name << " --help=<parameter name>\n";
}
void
help( std::ostream& ostr, parameters_store const& parameters, cstring param_name )
{
if( !param_name.is_empty() ) {
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
param->help( ostr, m_negation_prefix );
return;
}
ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
if( !m_end_of_param_indicator.empty() )
ostr << m_end_of_param_indicator << " [custom test module argument]...";
ostr << "\n\nBoost.Test arguments correspond to parameters listed below. "
"All parameters are optional. You can use specify parameter value either "
"as a command line argument or as a value of corresponding environment "
"variable. In case if argument for the same parameter is specified in both "
"places, command line is taking precedence. Command line argument format "
"supports parameter name guessing, so you can use any unambiguous "
"prefix to identify a parameter.";
if( !m_end_of_param_indicator.empty() )
ostr << " All the arguments after the " << m_end_of_param_indicator << " are ignored by the Boost.Test.";
ostr << "\n\nBoost.Test supports following parameters:\n";
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
basic_param_ptr param = v.second;
param->usage( ostr, m_negation_prefix );
}
ostr << "\nUse --help=<parameter name> to display detailed help for specific parameter.\n";
}
private:
typedef rt_cla_detail::parameter_trie_ptr trie_ptr;
typedef rt_cla_detail::trie_per_char trie_per_char;
typedef std::map<cstring,trie_ptr> str_to_trie;
void
build_trie( parameters_store const& parameters )
{
// Iterate over all parameters
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
basic_param_ptr param = v.second;
// Register all parameter's ids in trie.
BOOST_TEST_FOREACH( parameter_cla_id const&, id, param->cla_ids() ) {
// This is the trie corresponding to the prefix.
trie_ptr next_trie = m_param_trie[id.m_prefix];
if( !next_trie )
next_trie = m_param_trie[id.m_prefix] = trie_ptr( new rt_cla_detail::parameter_trie );
// Build the trie, by following name's characters
// and register this parameter as candidate on each level
for( size_t index = 0; index < id.m_tag.size(); ++index ) {
next_trie = next_trie->make_subtrie( id.m_tag[index] );
next_trie->add_candidate_id( id, param, index == (id.m_tag.size() - 1) );
}
}
}
}
bool
validate_token_format( cstring token, cstring& prefix, cstring& name, cstring& separator, bool& negative_form )
{
// Match prefix
cstring::iterator it = token.begin();
while( it != token.end() && parameter_cla_id::valid_prefix_char( *it ) )
++it;
prefix.assign( token.begin(), it );
if( prefix.empty() )
return true;
// Match name
while( it != token.end() && parameter_cla_id::valid_name_char( *it ) )
++it;
name.assign( prefix.end(), it );
if( name.empty() ) {
if( prefix == m_end_of_param_indicator )
return false;
BOOST_TEST_I_THROW( format_error() << "Invalid format for an actual argument " << token );
}
// Match value separator
while( it != token.end() && parameter_cla_id::valid_separator_char( *it ) )
++it;
separator.assign( name.end(), it );
// Match negation prefix
negative_form = !m_negation_prefix.empty() && ( name.substr( 0, m_negation_prefix.size() ) == m_negation_prefix );
if( negative_form )
name.trim_left( m_negation_prefix.size() );
return true;
}
// C++03: cannot have references as types
typedef std::pair<parameter_cla_id, basic_param_ptr> locate_result;
locate_result
locate_parameter( trie_ptr curr_trie, cstring name, cstring token )
{
std::vector<trie_ptr> typo_candidates;
std::vector<trie_ptr> next_typo_candidates;
trie_ptr next_trie;
BOOST_TEST_FOREACH( char, c, name ) {
if( curr_trie ) {
// locate next subtrie corresponding to the char
next_trie = curr_trie->get_subtrie( c );
if( next_trie )
curr_trie = next_trie;
else {
// Initiate search for typo candicates. We will account for 'wrong char' typo
// 'missing char' typo and 'extra char' typo
BOOST_TEST_FOREACH( trie_per_char::value_type const&, typo_cand, curr_trie->m_subtrie ) {
// 'wrong char' typo
typo_candidates.push_back( typo_cand.second );
// 'missing char' typo
if( (next_trie = typo_cand.second->get_subtrie( c )) )
typo_candidates.push_back( next_trie );
}
// 'extra char' typo
typo_candidates.push_back( curr_trie );
curr_trie.reset();
}
}
else {
// go over existing typo candidates and see if they are still viable
BOOST_TEST_FOREACH( trie_ptr, typo_cand, typo_candidates ) {
trie_ptr next_typo_cand = typo_cand->get_subtrie( c );
if( next_typo_cand )
next_typo_candidates.push_back( next_typo_cand );
}
next_typo_candidates.swap( typo_candidates );
next_typo_candidates.clear();
}
}
if( !curr_trie ) {
std::vector<cstring> typo_candidate_names;
std::set<parameter_cla_id const*> unique_typo_candidate; // !! ?? unordered_set
typo_candidate_names.reserve( typo_candidates.size() );
// !! ?? unique_typo_candidate.reserve( typo_candidates.size() );
BOOST_TEST_FOREACH( trie_ptr, trie_cand, typo_candidates ) {
// avoid ambiguos candidate trie
if( trie_cand->m_id_candidates.size() > 1 )
continue;
BOOST_TEST_FOREACH( parameter_cla_id const&, param_cand, trie_cand->m_id_candidates ) {
if( !unique_typo_candidate.insert( &param_cand ).second )
continue;
typo_candidate_names.push_back( param_cand.m_tag );
}
}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_TEST_I_THROW( unrecognized_param( std::move(typo_candidate_names) )
<< "An unrecognized parameter in the argument "
<< token );
#else
BOOST_TEST_I_THROW( unrecognized_param( typo_candidate_names )
<< "An unrecognized parameter in the argument "
<< token );
#endif
}
if( curr_trie->m_id_candidates.size() > 1 ) {
std::vector<cstring> amb_names;
BOOST_TEST_FOREACH( parameter_cla_id const&, param_id, curr_trie->m_id_candidates )
amb_names.push_back( param_id.m_tag );
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
BOOST_TEST_I_THROW( ambiguous_param( std::move( amb_names ) )
<< "An ambiguous parameter name in the argument " << token );
#else
BOOST_TEST_I_THROW( ambiguous_param( amb_names )
<< "An ambiguous parameter name in the argument " << token );
#endif
}
return locate_result( curr_trie->m_id_candidates.back().get(), curr_trie->m_param_candidate );
}
// Data members
cstring m_program_name;
std::string m_end_of_param_indicator;
std::string m_negation_prefix;
str_to_trie m_param_trie;
};
} // namespace cla
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_CLA_PARSER_HPP

View File

@@ -0,0 +1,108 @@
// (C) Copyright Gennadiy Rozental 2001.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
// See http://www.boost.org/libs/test for the library home page.
//
// File : $RCSfile$
//
// Version : $Revision$
//
// Description : implements fetching absent parameter athuments from environment
// ***************************************************************************
#ifndef BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP
#define BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP
// Boost.Test Runtime parameters
#include <boost/test/utils/runtime/parameter.hpp>
#include <boost/test/utils/runtime/argument.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
// C Runtime
#include <stdlib.h>
namespace boost {
namespace runtime {
namespace env {
namespace env_detail {
#ifndef UNDER_CE
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4996) // getenv
#endif
inline std::pair<cstring,bool>
sys_read_var( cstring var_name )
{
using namespace std;
char const* res = getenv( var_name.begin() );
return std::make_pair( cstring(res), res != NULL );
}
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
#else
inline std::pair<cstring,bool>
sys_read_var( cstring var_name )
{
return std::make_pair( cstring(), false );
}
#endif
//____________________________________________________________________________//
template<typename ReadFunc>
inline void
fetch_absent( parameters_store const& params, runtime::arguments_store& args, ReadFunc read_func )
{
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, params.all() ) {
basic_param_ptr param = v.second;
if( args.has( param->p_name ) || param->p_env_var.empty() )
continue;
std::pair<cstring,bool> value = read_func( param->p_env_var );
if( !value.second )
continue;
// Validate against unexpected empty value
BOOST_TEST_I_ASSRT( !value.first.is_empty() || param->p_has_optional_value,
format_error( param->p_name )
<< "Missing an argument value for the parameter " << param->p_name
<< " in the environment." );
// Produce argument value
param->produce_argument( value.first, false, args );
}
}
//____________________________________________________________________________//
} // namespace env_detail
inline void
fetch_absent( parameters_store const& params, runtime::arguments_store& args )
{
env_detail::fetch_absent( params, args, &env_detail::sys_read_var );
}
} // namespace env
} // namespace runtime
} // namespace boost
#include <boost/test/detail/enable_warnings.hpp>
#endif // BOOST_TEST_UTILS_RUNTIME_ENV_FETCH_HPP

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