stabilize build system: depends, installer, boost/bdb fixes, cross targets groundwork
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
// (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 header.
|
||||
//! @deprecated Use @c boost/test/unit_test.hpp instead.
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
|
||||
#define BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#endif // BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
|
||||
@@ -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 common dataset macros
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_CONFIG_HPP_112611GER
|
||||
#define BOOST_TEST_DATA_CONFIG_HPP_112611GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
|
||||
// STL
|
||||
#include <stdexcept> // for std::logic_error
|
||||
|
||||
// availability on features: preprocessed by doxygen
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_RANDOM) || defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
//! Defined when the random dataset feature is not available
|
||||
#define BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_NO_CXX11_HDR_TUPLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
|
||||
//! Defined when grid composition of datasets is not available
|
||||
#define BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE
|
||||
|
||||
//! Defined when zip composition of datasets is not available
|
||||
#define BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE
|
||||
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#define BOOST_TEST_DS_ERROR( msg ) BOOST_TEST_I_THROW( std::logic_error( msg ) )
|
||||
#define BOOST_TEST_DS_ASSERT( cond, msg ) BOOST_TEST_I_ASSRT( cond, std::logic_error( msg ) )
|
||||
|
||||
#endif // BOOST_TEST_DATA_CONFIG_HPP_112611GER
|
||||
@@ -0,0 +1,19 @@
|
||||
// (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 dataset interfaces
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_DATASET_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_DATASET_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/monomorphic.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_DATASET_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
// (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 for_each_sample algorithm
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_FOR_EACH_SAMPLE_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_FOR_EACH_SAMPLE_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/size.hpp>
|
||||
#include <boost/test/data/index_sequence.hpp>
|
||||
#include <boost/test/data/monomorphic/sample_merge.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
// STL
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
// needed for std::min
|
||||
#include <algorithm>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** data::invoke_action ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename Action, typename T>
|
||||
inline void
|
||||
invoke_action( Action const& action, T && arg, std::false_type /* is_tuple */ )
|
||||
{
|
||||
action( std::forward<T>(arg) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename Action, typename T, std::size_t ...I>
|
||||
inline void
|
||||
invoke_action_impl( Action const& action,
|
||||
T && args,
|
||||
index_sequence<I...> const& )
|
||||
{
|
||||
action( std::get<I>(std::forward<T>(args))... );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename Action, typename T>
|
||||
inline void
|
||||
invoke_action( Action const& action, T&& args, std::true_type /* is_tuple */ )
|
||||
{
|
||||
invoke_action_impl( action,
|
||||
std::forward<T>(args),
|
||||
typename make_index_sequence< 0,
|
||||
std::tuple_size<typename std::decay<T>::type>::value
|
||||
>::type{} );
|
||||
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** for_each_sample ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename DataSet, typename Action>
|
||||
inline typename std::enable_if<monomorphic::is_dataset<DataSet>::value,void>::type
|
||||
for_each_sample( DataSet && samples,
|
||||
Action const& act,
|
||||
data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE )
|
||||
{
|
||||
data::size_t size = (std::min)( samples.size(), number_of_samples );
|
||||
BOOST_TEST_DS_ASSERT( !size.is_inf(), "Dataset has infinite size. Please specify the number of samples" );
|
||||
|
||||
auto it = samples.begin();
|
||||
|
||||
while( size-- > 0 ) {
|
||||
invoke_action( act,
|
||||
*it,
|
||||
typename monomorphic::ds_detail::is_tuple<decltype(*it)>::type());
|
||||
++it;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename DataSet, typename Action>
|
||||
inline typename std::enable_if<!monomorphic::is_dataset<DataSet>::value,void>::type
|
||||
for_each_sample( DataSet && samples,
|
||||
Action const& act,
|
||||
data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE )
|
||||
{
|
||||
data::for_each_sample( data::make( std::forward<DataSet>(samples) ),
|
||||
act,
|
||||
number_of_samples );
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_FOR_EACH_SAMPLE_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
// (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 specific generators
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/monomorphic/generators/xrange.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
// (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 c++14 index_sequence implementation
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_INDEX_SEQUENCE_HPP
|
||||
#define BOOST_TEST_DATA_INDEX_SEQUENCE_HPP
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** data::index_sequence ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template <std::size_t... Ns>
|
||||
struct index_sequence {};
|
||||
|
||||
template<typename IS1, typename IS2>
|
||||
struct merge_index_sequence;
|
||||
|
||||
template <std::size_t... Ns1, std::size_t... Ns2>
|
||||
struct merge_index_sequence<index_sequence<Ns1...>, index_sequence<Ns2...>> {
|
||||
typedef index_sequence<Ns1..., Ns2...> type;
|
||||
};
|
||||
|
||||
template <std::size_t B, std::size_t E, typename Enabler = void>
|
||||
struct make_index_sequence {
|
||||
typedef typename merge_index_sequence<typename make_index_sequence<B,(B+E)/2>::type,
|
||||
typename make_index_sequence<(B+E)/2,E>::type>::type type;
|
||||
};
|
||||
|
||||
template <std::size_t B, std::size_t E>
|
||||
struct make_index_sequence<B,E,typename std::enable_if<E==B+1,void>::type> {
|
||||
typedef index_sequence<B> type;
|
||||
};
|
||||
|
||||
template <typename... T>
|
||||
using index_sequence_for = typename make_index_sequence<0, sizeof...(T)>::type;
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_INDEX_SEQUENCE_HPP
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// (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 Monomorphic dataset interfaces
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/monomorphic/array.hpp>
|
||||
#include <boost/test/data/monomorphic/collection.hpp>
|
||||
#include <boost/test/data/monomorphic/initializer_list.hpp>
|
||||
#include <boost/test/data/monomorphic/generate.hpp>
|
||||
#include <boost/test/data/monomorphic/generators.hpp>
|
||||
#include <boost/test/data/monomorphic/grid.hpp>
|
||||
#include <boost/test/data/monomorphic/join.hpp>
|
||||
#include <boost/test/data/monomorphic/singleton.hpp>
|
||||
#include <boost/test/data/monomorphic/zip.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,83 @@
|
||||
// (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 monomorphic dataset based on C type arrays
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** array ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// Dataset view of a C array
|
||||
template<typename T>
|
||||
class array {
|
||||
public:
|
||||
typedef T sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
typedef T const* iterator;
|
||||
|
||||
// Constructor
|
||||
array( T const* arr_, std::size_t size_ )
|
||||
: m_arr( arr_ )
|
||||
, m_size( size_ )
|
||||
{}
|
||||
|
||||
// dataset interface
|
||||
data::size_t size() const { return m_size; }
|
||||
iterator begin() const { return m_arr; }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
T const* m_arr;
|
||||
std::size_t m_size;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! An array dataset is a dataset
|
||||
template<typename T>
|
||||
struct is_dataset<array<T>> : mpl::true_ {};
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename T, std::size_t size>
|
||||
inline monomorphic::array<typename boost::remove_const<T>::type>
|
||||
make( T (&a)[size] )
|
||||
{
|
||||
return monomorphic::array<typename boost::remove_const<T>::type>( a, size );
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_ARRAY_HPP_121411GER
|
||||
|
||||
@@ -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
|
||||
///Defines monomorphic dataset based on forward iterable sequence
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** collection ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
|
||||
//!@brief Dataset from a forward iterable container (collection)
|
||||
//!
|
||||
//! This dataset is applicable to any container implementing a forward iterator. Note that
|
||||
//! container with one element will be considered as singletons.
|
||||
//! This dataset is constructible with the @ref boost::unit_test::data::make function.
|
||||
template<typename C>
|
||||
class collection {
|
||||
typedef typename boost::decay<C>::type col_type;
|
||||
public:
|
||||
typedef typename col_type::value_type sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
typedef typename col_type::const_iterator iterator;
|
||||
|
||||
//! Constructor consumed a temporary collection or stores a reference
|
||||
explicit collection( C&& col ) : m_col( std::forward<C>(col) ) {}
|
||||
|
||||
//! Move constructor
|
||||
collection( collection&& c ) : m_col( std::forward<C>( c.m_col ) ) {}
|
||||
|
||||
//! Returns the underlying collection
|
||||
C const& col() const { return m_col; }
|
||||
|
||||
//! dataset interface
|
||||
data::size_t size() const { return m_col.size(); }
|
||||
iterator begin() const { return m_col.begin(); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
C m_col;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! A collection from a forward iterable container is a dataset.
|
||||
template<typename C>
|
||||
struct is_dataset<collection<C>> : mpl::true_ {};
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename C>
|
||||
inline typename std::enable_if<is_forward_iterable<C>::value,monomorphic::collection<C>>::type
|
||||
make( C&& c )
|
||||
{
|
||||
return monomorphic::collection<C>( std::forward<C>(c) );
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_COLLECTION_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,180 @@
|
||||
// (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
|
||||
/// Forward declares monomorphic datasets interfaces
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/size.hpp>
|
||||
|
||||
#include <boost/test/utils/is_forward_iterable.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
|
||||
// STL
|
||||
#include <tuple>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
// STL
|
||||
#include <initializer_list>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
namespace monomorphic {
|
||||
|
||||
|
||||
#if !defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
|
||||
template<typename T, typename Specific>
|
||||
class dataset;
|
||||
|
||||
template<typename T>
|
||||
class singleton;
|
||||
|
||||
template<typename C>
|
||||
class collection;
|
||||
|
||||
template<typename T>
|
||||
class array;
|
||||
|
||||
template<typename T>
|
||||
class init_list;
|
||||
|
||||
#endif
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** monomorphic::is_dataset ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Helper metafunction indicating if the specified type is a dataset.
|
||||
template<typename DataSet>
|
||||
struct is_dataset : mpl::false_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! A reference to a dataset is a dataset
|
||||
template<typename DataSet>
|
||||
struct is_dataset<DataSet&> : is_dataset<DataSet> {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! A const dataset is a dataset
|
||||
template<typename DataSet>
|
||||
struct is_dataset<DataSet const> : is_dataset<DataSet> {};
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** data::make ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! @brief Creates a dataset from a value, a collection or an array
|
||||
//!
|
||||
//! This function has several overloads:
|
||||
//! @code
|
||||
//! // returns ds if ds is already a dataset
|
||||
//! template <typename DataSet> DataSet make(DataSet&& ds);
|
||||
//!
|
||||
//! // creates a singleton dataset, for non forward iterable and non dataset type T
|
||||
//! // (a C string is not considered as a sequence).
|
||||
//! template <typename T> monomorphic::singleton<T> make(T&& v);
|
||||
//! monomorphic::singleton<char*> make( char* str );
|
||||
//! monomorphic::singleton<char const*> make( char const* str );
|
||||
//!
|
||||
//! // creates a collection dataset, for forward iterable and non dataset type C
|
||||
//! template <typename C> monomorphic::collection<C> make(C && c);
|
||||
//!
|
||||
//! // creates an array dataset
|
||||
//! template<typename T, std::size_t size> monomorphic::array<T> make( T (&a)[size] );
|
||||
//! @endcode
|
||||
template<typename DataSet>
|
||||
inline typename std::enable_if<monomorphic::is_dataset<DataSet>::value,DataSet>::type
|
||||
make(DataSet&& ds)
|
||||
{
|
||||
return std::forward<DataSet>( ds );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// warning: doxygen is apparently unable to handle @overload from different files, so if the overloads
|
||||
// below are not declared with @overload in THIS file, they do not appear in the documentation.
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename T>
|
||||
inline typename std::enable_if<!is_forward_iterable<T>::value &&
|
||||
!monomorphic::is_dataset<T>::value &&
|
||||
!is_array<typename remove_reference<T>::type>::value,
|
||||
monomorphic::singleton<T>>::type
|
||||
make( T&& v );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename C>
|
||||
inline typename std::enable_if<is_forward_iterable<C>::value,monomorphic::collection<C>>::type
|
||||
make( C&& c );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename T, std::size_t size>
|
||||
inline monomorphic::array< typename boost::remove_const<T>::type >
|
||||
make( T (&a)[size] );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
inline monomorphic::singleton<char*>
|
||||
make( char* str );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
inline monomorphic::singleton<char const*>
|
||||
make( char const* str );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename T>
|
||||
inline monomorphic::init_list<T>
|
||||
make( std::initializer_list<T>&& );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace result_of {
|
||||
|
||||
//! Result of the make call.
|
||||
template<typename DataSet>
|
||||
struct make {
|
||||
typedef decltype( data::make( declval<DataSet>() ) ) type;
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_FWD_HPP_102212GER
|
||||
|
||||
@@ -0,0 +1,109 @@
|
||||
// (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 generic interface for monomorphic dataset based on generator
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** generated_by ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/*!@brief Generators interface
|
||||
*
|
||||
* This class implements the dataset concept over a generator. Examples of generators are:
|
||||
* - xrange_t
|
||||
* - random_t
|
||||
*
|
||||
* The generator concept is the following:
|
||||
* - the type of the generated samples is given by field @c sample
|
||||
* - the member function @c capacity should return the size of the collection being generated (potentially infinite)
|
||||
* - the member function @c next should change the state of the generator to the next generated value
|
||||
* - the member function @c reset should put the state of the object in the same state as right after its instanciation
|
||||
*/
|
||||
template<typename Generator>
|
||||
class generated_by {
|
||||
public:
|
||||
typedef typename Generator::sample sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
struct iterator {
|
||||
// Constructor
|
||||
explicit iterator( Generator& gen )
|
||||
: m_gen( &gen )
|
||||
{
|
||||
if(m_gen->capacity() > 0) {
|
||||
m_gen->reset();
|
||||
++*this;
|
||||
}
|
||||
}
|
||||
|
||||
// forward iterator interface
|
||||
sample const& operator*() const { return m_curr_sample; }
|
||||
void operator++() { m_curr_sample = m_gen->next(); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
Generator* m_gen;
|
||||
sample m_curr_sample;
|
||||
};
|
||||
|
||||
typedef Generator generator_type;
|
||||
|
||||
// Constructor
|
||||
explicit generated_by( Generator&& G )
|
||||
: m_generator( std::forward<Generator>(G) )
|
||||
{}
|
||||
|
||||
// Move constructor
|
||||
generated_by( generated_by&& rhs )
|
||||
: m_generator( std::forward<Generator>(rhs.m_generator) )
|
||||
{}
|
||||
|
||||
//! Size of the underlying dataset
|
||||
data::size_t size() const { return m_generator.capacity(); }
|
||||
|
||||
//! Iterator on the beginning of the dataset
|
||||
iterator begin() const { return iterator( boost::ref(const_cast<Generator&>(m_generator)) ); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
Generator m_generator;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! A generated dataset is a dataset.
|
||||
template<typename Generator>
|
||||
struct is_dataset<generated_by<Generator>> : mpl::true_ {};
|
||||
|
||||
} // namespace monomorphic
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATE_HPP_112011GER
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
// (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 specific generators
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/monomorphic/generators/xrange.hpp>
|
||||
#include <boost/test/data/monomorphic/generators/random.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
|
||||
+39
@@ -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
|
||||
/// Keywords used in generator interfaces
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/utils/named_params.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
namespace {
|
||||
nfp::keyword<struct begin_t> begin;
|
||||
nfp::keyword<struct end_t> end;
|
||||
nfp::keyword<struct step_t> step;
|
||||
} // local namespace
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_KEYWORDS_HPP_101512GER
|
||||
+198
@@ -0,0 +1,198 @@
|
||||
// (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 Random generator
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
|
||||
|
||||
|
||||
|
||||
#if !defined(BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
|
||||
#include <boost/test/data/monomorphic/generate.hpp>
|
||||
#include <boost/test/data/monomorphic/generators/keywords.hpp>
|
||||
|
||||
// STL
|
||||
#include <random>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
namespace {
|
||||
nfp::keyword<struct seed_t> seed;
|
||||
nfp::keyword<struct distribution_t> distribution;
|
||||
nfp::keyword<struct engine_t> engine;
|
||||
} // local namespace
|
||||
|
||||
namespace monomorphic {
|
||||
|
||||
namespace ds_detail {
|
||||
template<typename SampleType>
|
||||
struct default_distribution {
|
||||
typedef typename mpl::if_<std::is_integral<SampleType>,
|
||||
std::uniform_int_distribution<SampleType>,
|
||||
std::uniform_real_distribution<SampleType>>::type type;
|
||||
};
|
||||
|
||||
} // namespace ds_detail
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** random_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/*!@brief Generator for the random sequences
|
||||
*
|
||||
* This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
|
||||
* a random number generator.
|
||||
*/
|
||||
template<typename SampleType = double,
|
||||
typename DistributionType = typename ds_detail::default_distribution<SampleType>::type,
|
||||
typename EngineType = std::default_random_engine>
|
||||
class random_t {
|
||||
public:
|
||||
typedef SampleType sample;
|
||||
typedef DistributionType distr_type;
|
||||
typedef EngineType engine_type;
|
||||
|
||||
random_t()
|
||||
: m_distribution()
|
||||
, m_engine( std::random_device()() )
|
||||
{}
|
||||
explicit random_t( distr_type&& d )
|
||||
: m_distribution( std::forward<distr_type>(d) )
|
||||
, m_engine( std::random_device()() ){}
|
||||
random_t( engine_type&& e, distr_type&& d )
|
||||
: m_distribution( std::forward<distr_type>(d) )
|
||||
, m_engine( std::forward<engine_type>(e) ){}
|
||||
|
||||
// Generator interface
|
||||
data::size_t capacity() const { return BOOST_TEST_DS_INFINITE_SIZE; }
|
||||
SampleType next()
|
||||
{
|
||||
return m_distribution( m_engine );
|
||||
}
|
||||
void reset() {}
|
||||
|
||||
//! Sets the seed of the pseudo-random number engine.
|
||||
template<typename SeedType>
|
||||
void seed( SeedType&& seed ) { m_engine.seed( std::forward<SeedType>( seed ) ); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
DistributionType m_distribution;
|
||||
EngineType m_engine;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
|
||||
//! @brief Returns an infinite sequence of random numbers.
|
||||
//!
|
||||
//! The following overloads are available:
|
||||
//! @code
|
||||
//! auto d = random();
|
||||
//! auto d = random(begin, end);
|
||||
//! auto d = random(params);
|
||||
//! @endcode
|
||||
//!
|
||||
//!
|
||||
//! - The first overload uses the default distribution, which is uniform and which elements
|
||||
//! are @c double type (the values are in [0, 1) ).
|
||||
//! - The second overload generates numbers in the given interval. The distribution is uniform (in [begin, end)
|
||||
//! for real numbers, and in [begin, end] for integers). The type of the distribution is deduced from the type
|
||||
//! of the @c begin and @c end parameters.
|
||||
//! - The third overload generates numbers using the named parameter inside @c params , which are:
|
||||
//! - @c distribution: the distribution used. In this overload, since the type of the samples cannot be deduced,
|
||||
//! the samples are of type @c double and the distribution is uniform real in [0, 1).
|
||||
//! - @c seed: the seed for generating the values
|
||||
//! - @c engine: the random number generator engine
|
||||
//!
|
||||
//! The function returns an object that implements the dataset API.
|
||||
//! @note This function is available only for C++11 capable compilers.
|
||||
inline monomorphic::generated_by< monomorphic::random_t<>> random()
|
||||
{
|
||||
return monomorphic::generated_by<monomorphic::random_t<>>( monomorphic::random_t<>() );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// @overload boost::unit_test::data::random()
|
||||
template<typename SampleType>
|
||||
inline monomorphic::generated_by< monomorphic::random_t<SampleType>>
|
||||
random( SampleType begin, SampleType end )
|
||||
{
|
||||
typedef monomorphic::random_t<SampleType> Gen;
|
||||
typedef typename Gen::distr_type distr_type;
|
||||
return monomorphic::generated_by<Gen>( Gen( distr_type(begin,end) ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace ds_detail {
|
||||
template<typename Params>
|
||||
struct random_gen_type {
|
||||
typedef typename nfp::param_type<Params,decltype(distribution),std::uniform_real_distribution<>>::type distr_type;
|
||||
typedef typename nfp::param_type<Params,decltype(engine),std::default_random_engine>::type engine_type;
|
||||
typedef typename distr_type::result_type sample_type;
|
||||
|
||||
typedef monomorphic::random_t<sample_type,distr_type,engine_type> type;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
/// @overload boost::unit_test::data::random()
|
||||
template<typename Params>
|
||||
inline monomorphic::generated_by<typename ds_detail::random_gen_type<Params>::type>
|
||||
random( Params const& params )
|
||||
{
|
||||
typedef typename ds_detail::random_gen_type<Params>::type Gen;
|
||||
typedef typename Gen::distr_type distr_type;
|
||||
typedef typename Gen::engine_type engine_type;
|
||||
|
||||
std::random_device rd;
|
||||
engine_type E;
|
||||
// engine_type E( rd );
|
||||
if( params.has(engine) )
|
||||
E = params[engine];
|
||||
|
||||
distr_type D;
|
||||
if( params.has(distribution) )
|
||||
D = params[distribution];
|
||||
|
||||
Gen G( std::move(E), std::move(D) );
|
||||
|
||||
if( params.has(seed) )
|
||||
G.seed( params[seed] );
|
||||
|
||||
return monomorphic::generated_by<Gen>( std::move(G) );
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_NO_RANDOM_DATASET_AVAILABLE
|
||||
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_RANDOM_HPP_101512GER
|
||||
+224
@@ -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
|
||||
///Defines range generator
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
|
||||
#include <boost/test/data/monomorphic/generators/keywords.hpp>
|
||||
#include <boost/test/data/monomorphic/generate.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/is_unsigned.hpp>
|
||||
|
||||
// STL
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** monomorphic::xrange_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
|
||||
/*!@brief Generator for the range sequences
|
||||
*
|
||||
* This class implements the generator concept (see @ref boost::unit_test::data::monomorphic::generated_by) for implementing
|
||||
* a range like sequence of numbers.
|
||||
*/
|
||||
template<typename SampleType, typename StepType=SampleType>
|
||||
class xrange_t {
|
||||
public:
|
||||
typedef SampleType sample;
|
||||
|
||||
xrange_t( SampleType const& begin_, StepType const& step_, data::size_t size_ )
|
||||
: m_begin( begin_ )
|
||||
, m_curr( begin_ )
|
||||
, m_step( step_ )
|
||||
, m_index( 0 )
|
||||
, m_size( size_ )
|
||||
{}
|
||||
|
||||
// Generator interface
|
||||
data::size_t capacity() const { return m_size; }
|
||||
SampleType next()
|
||||
{
|
||||
if( m_index == m_size )
|
||||
return m_curr;
|
||||
|
||||
SampleType res = m_curr;
|
||||
|
||||
m_curr += m_step;
|
||||
++m_index;
|
||||
|
||||
return res;
|
||||
}
|
||||
void reset()
|
||||
{
|
||||
m_curr = m_begin;
|
||||
m_index = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
SampleType m_begin;
|
||||
SampleType m_curr;
|
||||
StepType m_step;
|
||||
data::size_t m_index;
|
||||
data::size_t m_size;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace ds_detail {
|
||||
|
||||
template<typename SampleType, typename StepType=SampleType>
|
||||
struct make_xrange {
|
||||
static StepType abs( StepType s, boost::true_type* ) { return s; }
|
||||
static StepType abs( StepType s, boost::false_type* ) { return std::abs(s); }
|
||||
|
||||
typedef xrange_t<SampleType, StepType> range_gen;
|
||||
|
||||
template<typename Params>
|
||||
static generated_by<range_gen>
|
||||
_( Params const& params )
|
||||
{
|
||||
SampleType begin_val = params.has( data::begin ) ? params[data::begin] : SampleType();
|
||||
optional<SampleType> end_val = params.has( data::end ) ? params[data::end] : optional<SampleType>();
|
||||
StepType step_val = params.has( data::step ) ? params[data::step] : 1;
|
||||
|
||||
BOOST_TEST_DS_ASSERT( step_val != 0, "Range step can't be zero" );
|
||||
|
||||
data::size_t size;
|
||||
if( !end_val.is_initialized() )
|
||||
size = BOOST_TEST_DS_INFINITE_SIZE;
|
||||
else {
|
||||
BOOST_TEST_DS_ASSERT( (step_val < 0) ^ (begin_val < *end_val), "Invalid step direction" );
|
||||
|
||||
SampleType abs_distance = step_val < 0 ? begin_val - *end_val : *end_val-begin_val;
|
||||
StepType abs_step = make_xrange::abs(step_val, (typename boost::is_unsigned<StepType>::type*)0 );
|
||||
std::size_t s = static_cast<std::size_t>(abs_distance/abs_step);
|
||||
|
||||
if( static_cast<SampleType>(s*abs_step) < abs_distance )
|
||||
s++;
|
||||
|
||||
size = s;
|
||||
}
|
||||
|
||||
return generated_by<range_gen>( range_gen( begin_val, step_val, size ) );
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace ds_detail
|
||||
} // namespace monomorphic
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! Creates a range (sequence) dataset.
|
||||
//!
|
||||
//! The following overloads are available:
|
||||
//! @code
|
||||
//! auto d = xrange();
|
||||
//! auto d = xrange(end_val);
|
||||
//! auto d = xrange(end_val, param);
|
||||
//! auto d = xrange(begin_val, end_val);
|
||||
//! auto d = xrange(begin_val, end_val, step_val);
|
||||
//! auto d = xrange(param);
|
||||
//! @endcode
|
||||
//!
|
||||
//! - @c begin_val indicates the start of the sequence (default to 0).
|
||||
//! - @c end_val is the end of the sequence. If ommited, the dataset has infinite size.\n
|
||||
//! - @c step_val is the step between two consecutive elements of the sequence, and defaults to 1.\n
|
||||
//! - @c param is the named parameters that describe the sequence. The following parameters are accepted:
|
||||
//! - @c begin: same meaning @c begin_val
|
||||
//! - @c end: same meaning as @c end_val
|
||||
//! - @c step: same meaning as @c step_val
|
||||
//!
|
||||
//!
|
||||
//! The returned value is an object that implements the dataset API.
|
||||
//!
|
||||
//! @note the step size cannot be null, and it should be positive if @c begin_val < @c end_val, negative otherwise.
|
||||
template<typename SampleType, typename Params>
|
||||
inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
|
||||
xrange( Params const& params )
|
||||
{
|
||||
return monomorphic::ds_detail::make_xrange<SampleType>::_( params );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// @overload boost::unit_test::data::xrange()
|
||||
template<typename SampleType>
|
||||
inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
|
||||
xrange( SampleType const& end_val )
|
||||
{
|
||||
return monomorphic::ds_detail::make_xrange<SampleType>::_( data::end=end_val );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// @overload boost::unit_test::data::xrange()
|
||||
template<typename SampleType, typename Params>
|
||||
inline typename enable_if_c<nfp::is_named_param_pack<Params>::value,
|
||||
monomorphic::generated_by<monomorphic::xrange_t<SampleType>>>::type
|
||||
xrange( SampleType const& end_val, Params const& params )
|
||||
{
|
||||
return monomorphic::ds_detail::make_xrange<SampleType>::_(( params, data::end=end_val ));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// @overload boost::unit_test::data::xrange()
|
||||
template<typename SampleType>
|
||||
inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
|
||||
xrange( SampleType const& begin_val, SampleType const& end_val )
|
||||
{
|
||||
return monomorphic::ds_detail::make_xrange<SampleType>::_((
|
||||
data::begin=begin_val,
|
||||
data::end=end_val ));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
|
||||
|
||||
/// @overload boost::unit_test::data::xrange()
|
||||
template<typename SampleType,typename StepType>
|
||||
inline monomorphic::generated_by<monomorphic::xrange_t<SampleType>>
|
||||
xrange( SampleType const& begin_val, SampleType const& end_val, StepType const& step_val )
|
||||
{
|
||||
return monomorphic::ds_detail::make_xrange<SampleType,StepType>::_((
|
||||
data::begin=begin_val,
|
||||
data::end=end_val,
|
||||
data::step=step_val ));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_XRANGE_HPP_112011GER
|
||||
@@ -0,0 +1,181 @@
|
||||
// (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 monomorphic dataset n+m dimentional *. Samples in this
|
||||
/// dataset is grid of elements in DataSet1 and DataSet2. There will be total
|
||||
/// |DataSet1| * |DataSet2| samples
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
|
||||
#if !defined(BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
#include <boost/test/data/monomorphic/sample_merge.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** grid ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
|
||||
//! Implements the dataset resulting from a cartesian product/grid operation on datasets.
|
||||
//!
|
||||
//! The arity of the resulting dataset is the sum of the arity of its operands.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
class grid {
|
||||
typedef typename boost::decay<DataSet1>::type dataset1_decay;
|
||||
typedef typename boost::decay<DataSet2>::type dataset2_decay;
|
||||
|
||||
typedef typename dataset1_decay::iterator dataset1_iter;
|
||||
typedef typename dataset2_decay::iterator dataset2_iter;
|
||||
|
||||
public:
|
||||
|
||||
struct iterator {
|
||||
// Constructor
|
||||
explicit iterator( dataset1_iter iter1, DataSet2 const& ds2 )
|
||||
: m_iter1( std::move( iter1 ) )
|
||||
, m_iter2( std::move( ds2.begin() ) )
|
||||
, m_ds2( &ds2 )
|
||||
, m_ds2_pos( 0 )
|
||||
{}
|
||||
|
||||
using iterator_sample = decltype(
|
||||
sample_merge( *std::declval<dataset1_iter>(),
|
||||
*std::declval<dataset2_iter>()) );
|
||||
|
||||
// forward iterator interface
|
||||
auto operator*() const -> iterator_sample {
|
||||
return sample_merge( *m_iter1, *m_iter2 );
|
||||
}
|
||||
void operator++()
|
||||
{
|
||||
++m_ds2_pos;
|
||||
if( m_ds2_pos != m_ds2->size() )
|
||||
++m_iter2;
|
||||
else {
|
||||
m_ds2_pos = 0;
|
||||
++m_iter1;
|
||||
m_iter2 = std::move( m_ds2->begin() );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
dataset1_iter m_iter1;
|
||||
dataset2_iter m_iter2;
|
||||
dataset2_decay const* m_ds2;
|
||||
data::size_t m_ds2_pos;
|
||||
};
|
||||
|
||||
public:
|
||||
enum { arity = boost::decay<DataSet1>::type::arity + boost::decay<DataSet2>::type::arity };
|
||||
|
||||
//! Constructor
|
||||
grid( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
: m_ds1( std::forward<DataSet1>( ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( ds2 ) )
|
||||
{}
|
||||
|
||||
//! Move constructor
|
||||
grid( grid&& j )
|
||||
: m_ds1( std::forward<DataSet1>( j.m_ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( j.m_ds2 ) )
|
||||
{}
|
||||
|
||||
// dataset interface
|
||||
data::size_t size() const { return m_ds1.size() * m_ds2.size(); }
|
||||
iterator begin() const { return iterator( m_ds1.begin(), m_ds2 ); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
DataSet1 m_ds1;
|
||||
DataSet2 m_ds2;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// A grid dataset is a dataset
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
struct is_dataset<grid<DataSet1,DataSet2>> : mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace result_of {
|
||||
|
||||
/// Result type of the grid operation on dataset.
|
||||
template<typename DS1Gen, typename DS2Gen>
|
||||
struct grid {
|
||||
typedef monomorphic::grid<typename DS1Gen::type,typename DS2Gen::type> type;
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! Grid operation
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
|
||||
result_of::grid<mpl::identity<DataSet1>,mpl::identity<DataSet2>>
|
||||
>::type
|
||||
operator*( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
BOOST_TEST_DS_ASSERT( !ds1.size().is_inf() && !ds2.size().is_inf(), "Grid axes can't have infinite size" );
|
||||
|
||||
return grid<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ), std::forward<DataSet2>( ds2 ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::operator*
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && !is_dataset<DataSet2>::value,
|
||||
result_of::grid<mpl::identity<DataSet1>,data::result_of::make<DataSet2>>
|
||||
>::type
|
||||
operator*( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return std::forward<DataSet1>(ds1) * data::make(std::forward<DataSet2>(ds2));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::operator*
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<!is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
|
||||
result_of::grid<data::result_of::make<DataSet1>,mpl::identity<DataSet2>>
|
||||
>::type
|
||||
operator*( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return data::make(std::forward<DataSet1>(ds1)) * std::forward<DataSet2>(ds2);
|
||||
}
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_NO_GRID_COMPOSITION_AVAILABLE
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GRID_HPP_101512GER
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
// (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 monomorphic dataset based on C++11 initializer_list template
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_INITIALIZATION_LIST_HPP_091515GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_INITIALIZATION_LIST_HPP_091515GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** array ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// Dataset view of a C array
|
||||
template<typename T>
|
||||
class init_list {
|
||||
public:
|
||||
typedef T sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
typedef T const* iterator;
|
||||
|
||||
//! Constructor swallows initializer_list
|
||||
init_list( std::initializer_list<T>&& il )
|
||||
: m_data( std::forward<std::initializer_list<T>>( il ) )
|
||||
{}
|
||||
|
||||
//! dataset interface
|
||||
data::size_t size() const { return m_data.size(); }
|
||||
iterator begin() const { return m_data.begin(); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::initializer_list<T> m_data;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! An array dataset is a dataset
|
||||
template<typename T>
|
||||
struct is_dataset<init_list<T>> : mpl::true_ {};
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename T>
|
||||
inline monomorphic::init_list<T>
|
||||
make( std::initializer_list<T>&& il )
|
||||
{
|
||||
return monomorphic::init_list<T>( std::forward<std::initializer_list<T>>( il ) );
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_INITIALIZATION_LIST_HPP_091515GER
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
// (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 dataset join operation
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** join ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Defines a new dataset from the concatenation of two datasets
|
||||
//!
|
||||
//! The size of the resulting dataset is the sum of the two underlying datasets. The arity of the datasets
|
||||
//! should match.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
class join {
|
||||
typedef typename boost::decay<DataSet1>::type dataset1_decay;
|
||||
typedef typename boost::decay<DataSet2>::type dataset2_decay;
|
||||
|
||||
typedef typename dataset1_decay::iterator dataset1_iter;
|
||||
typedef typename dataset2_decay::iterator dataset2_iter;
|
||||
public:
|
||||
typedef typename dataset1_decay::sample sample;
|
||||
|
||||
enum { arity = dataset1_decay::arity };
|
||||
|
||||
struct iterator {
|
||||
// Constructor
|
||||
explicit iterator( dataset1_iter it1, dataset2_iter it2, data::size_t first_size )
|
||||
: m_it1( std::move( it1 ) )
|
||||
, m_it2( std::move( it2 ) )
|
||||
, m_first_size( first_size )
|
||||
{}
|
||||
|
||||
// forward iterator interface
|
||||
sample const& operator*() const { return m_first_size > 0 ? *m_it1 : *m_it2; }
|
||||
void operator++() { if( m_first_size > 0 ) { --m_first_size; ++m_it1; } else ++m_it2; }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
dataset1_iter m_it1;
|
||||
dataset2_iter m_it2;
|
||||
data::size_t m_first_size;
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
join( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
: m_ds1( std::forward<DataSet1>( ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( ds2 ) )
|
||||
{}
|
||||
|
||||
//! Move constructor
|
||||
join( join&& j )
|
||||
: m_ds1( std::forward<DataSet1>( j.m_ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( j.m_ds2 ) )
|
||||
{}
|
||||
|
||||
//! dataset interface
|
||||
data::size_t size() const { return m_ds1.size() + m_ds2.size(); }
|
||||
iterator begin() const { return iterator( m_ds1.begin(), m_ds2.begin(), m_ds1.size() ); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
DataSet1 m_ds1;
|
||||
DataSet2 m_ds2;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// A joined dataset is a dataset.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
struct is_dataset<join<DataSet1,DataSet2>> : mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace result_of {
|
||||
|
||||
//! Result type of the join operation on datasets.
|
||||
template<typename DataSet1Gen, typename DataSet2Gen>
|
||||
struct join {
|
||||
typedef monomorphic::join<typename DataSet1Gen::type,typename DataSet2Gen::type> type;
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
|
||||
result_of::join<mpl::identity<DataSet1>,mpl::identity<DataSet2>>
|
||||
>::type
|
||||
operator+( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return join<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ), std::forward<DataSet2>( ds2 ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && !is_dataset<DataSet2>::value,
|
||||
result_of::join<mpl::identity<DataSet1>,data::result_of::make<DataSet2>>
|
||||
>::type
|
||||
operator+( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return std::forward<DataSet1>( ds1 ) + data::make( std::forward<DataSet2>( ds2 ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<!is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
|
||||
result_of::join<data::result_of::make<DataSet1>,mpl::identity<DataSet2>>
|
||||
>::type
|
||||
operator+( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return data::make( std::forward<DataSet1>(ds1) ) + std::forward<DataSet2>( ds2 );
|
||||
}
|
||||
|
||||
} // namespace monomorphic
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_JOIN_HPP_112711GER
|
||||
|
||||
@@ -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
|
||||
/// Defines helper routines and types for merging monomorphic samples
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_SAMPLE_MERGE_HPP
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_SAMPLE_MERGE_HPP
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/index_sequence.hpp>
|
||||
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace ds_detail {
|
||||
|
||||
template <class T>
|
||||
struct is_tuple : std::false_type {};
|
||||
|
||||
template <class ...T>
|
||||
struct is_tuple<std::tuple<T...>> : std::true_type {};
|
||||
|
||||
template <class T>
|
||||
struct is_tuple<T&&> : is_tuple<typename std::decay<T>::type> {};
|
||||
|
||||
template <class T>
|
||||
struct is_tuple<T&> : is_tuple<typename std::decay<T>::type> {};
|
||||
|
||||
template<typename T>
|
||||
inline auto as_tuple_impl_xvalues( T const & arg, std::false_type /* is_rvalue_ref */ )
|
||||
-> decltype(std::tuple<T const&>(arg)) {
|
||||
//return std::tuple<T const&>(arg);
|
||||
return std::forward_as_tuple(arg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline auto as_tuple_impl_xvalues( T && arg, std::true_type /* is_rvalue_ref */ )
|
||||
-> decltype(std::make_tuple(std::forward<T>(arg))) {
|
||||
return std::make_tuple(std::forward<T>(arg));
|
||||
}
|
||||
|
||||
|
||||
template<typename T>
|
||||
inline auto as_tuple_impl( T && arg, std::false_type /* is_tuple = nullptr */ )
|
||||
-> decltype(as_tuple_impl_xvalues(std::forward<T>(arg),
|
||||
typename std::is_rvalue_reference<T&&>::type())) {
|
||||
return as_tuple_impl_xvalues(std::forward<T>(arg),
|
||||
typename std::is_rvalue_reference<T&&>::type());
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename T>
|
||||
inline T &&
|
||||
as_tuple_impl(T && arg, std::true_type /* is_tuple */ ) {
|
||||
return std::forward<T>(arg);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline auto as_tuple( T && arg )
|
||||
-> decltype( as_tuple_impl(std::forward<T>(arg),
|
||||
typename ds_detail::is_tuple<T>::type()) ) {
|
||||
return as_tuple_impl(std::forward<T>(arg),
|
||||
typename ds_detail::is_tuple<T>::type());
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace ds_detail
|
||||
|
||||
template<typename T1, typename T2>
|
||||
inline auto
|
||||
sample_merge( T1 && a1, T2 && a2 )
|
||||
-> decltype( std::tuple_cat(ds_detail::as_tuple(std::forward<T1>(a1)),
|
||||
ds_detail::as_tuple(std::forward<T2>(a2)) ) ) {
|
||||
return std::tuple_cat(ds_detail::as_tuple(std::forward<T1>(a1)),
|
||||
ds_detail::as_tuple(std::forward<T2>(a2)));
|
||||
}
|
||||
|
||||
} // namespace monomorphic
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_SAMPLE_MERGE_HPP
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
// (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 single element monomorphic dataset
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** singleton ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// Models a single element data set
|
||||
template<typename T>
|
||||
class singleton {
|
||||
public:
|
||||
typedef typename boost::decay<T>::type sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
struct iterator {
|
||||
// Constructor
|
||||
explicit iterator( singleton<T> const* owner )
|
||||
: m_owner( owner )
|
||||
{}
|
||||
|
||||
// forward iterator interface
|
||||
sample const& operator*() const { return m_owner->value(); }
|
||||
void operator++() {}
|
||||
|
||||
private:
|
||||
singleton<T> const* m_owner;
|
||||
};
|
||||
|
||||
//! Constructor
|
||||
explicit singleton( T&& value ) : m_value( std::forward<T>( value ) ) {}
|
||||
|
||||
//! Move constructor
|
||||
singleton( singleton&& s ) : m_value( std::forward<T>( s.m_value ) ) {}
|
||||
|
||||
//! Value access method
|
||||
T const& value() const { return m_value; }
|
||||
|
||||
//! dataset interface
|
||||
data::size_t size() const { return 1; }
|
||||
iterator begin() const { return iterator( this ); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
T m_value;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// a singleton is a dataset
|
||||
template<typename T>
|
||||
struct is_dataset<singleton<T>> : mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
/// @overload boost::unit_test::data::make()
|
||||
template<typename T>
|
||||
inline typename std::enable_if<!is_forward_iterable<T>::value &&
|
||||
!monomorphic::is_dataset<T>::value &&
|
||||
!boost::is_array<typename boost::remove_reference<T>::type>::value,
|
||||
monomorphic::singleton<T>
|
||||
>::type
|
||||
make( T&& v )
|
||||
{
|
||||
return monomorphic::singleton<T>( std::forward<T>( v ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// @overload boost::unit_test::data::make
|
||||
inline monomorphic::singleton<char*>
|
||||
make( char* str )
|
||||
{
|
||||
return monomorphic::singleton<char*>( std::move(str) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
/// @overload boost::unit_test::data::make
|
||||
inline monomorphic::singleton<char const*>
|
||||
make( char const* str )
|
||||
{
|
||||
return monomorphic::singleton<char const*>( std::move(str) );
|
||||
}
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_SINGLETON_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,194 @@
|
||||
// (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 monomorphic dataset based on zipping of 2 other monomorphic datasets
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
|
||||
#if !defined(BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE) || defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
#include <boost/test/data/monomorphic/sample_merge.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** zip ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Zip datasets
|
||||
//!
|
||||
//! A zip of two datasets is a dataset whose arity is the sum of the operand datasets arity. The size is given by
|
||||
//! the function creating the instance (see @c operator^ on datasets).
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
class zip {
|
||||
typedef typename boost::decay<DataSet1>::type dataset1_decay;
|
||||
typedef typename boost::decay<DataSet2>::type dataset2_decay;
|
||||
|
||||
typedef typename dataset1_decay::iterator dataset1_iter;
|
||||
typedef typename dataset2_decay::iterator dataset2_iter;
|
||||
|
||||
public:
|
||||
enum { arity = dataset1_decay::arity + dataset2_decay::arity };
|
||||
|
||||
struct iterator {
|
||||
// Constructor
|
||||
explicit iterator( dataset1_iter iter1, dataset2_iter iter2 )
|
||||
: m_iter1( std::move( iter1 ) )
|
||||
, m_iter2( std::move( iter2 ) )
|
||||
{}
|
||||
|
||||
using iterator_sample = decltype(
|
||||
sample_merge( *std::declval<dataset1_iter>(),
|
||||
*std::declval<dataset2_iter>()) );
|
||||
|
||||
// forward iterator interface
|
||||
auto operator*() const -> iterator_sample {
|
||||
return sample_merge( *m_iter1, *m_iter2 );
|
||||
}
|
||||
void operator++() { ++m_iter1; ++m_iter2; }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
dataset1_iter m_iter1;
|
||||
dataset2_iter m_iter2;
|
||||
};
|
||||
|
||||
typedef typename iterator::iterator_sample sample;
|
||||
|
||||
//! Constructor
|
||||
//!
|
||||
//! The datasets are moved and not copied.
|
||||
zip( DataSet1&& ds1, DataSet2&& ds2, data::size_t size )
|
||||
: m_ds1( std::forward<DataSet1>( ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( ds2 ) )
|
||||
, m_size( size )
|
||||
{}
|
||||
|
||||
//! Move constructor
|
||||
zip( zip&& j )
|
||||
: m_ds1( std::forward<DataSet1>( j.m_ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( j.m_ds2 ) )
|
||||
, m_size( j.m_size )
|
||||
{}
|
||||
|
||||
// dataset interface
|
||||
data::size_t size() const { return m_size; }
|
||||
iterator begin() const { return iterator( m_ds1.begin(), m_ds2.begin() ); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
DataSet1 m_ds1;
|
||||
DataSet2 m_ds2;
|
||||
data::size_t m_size;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! Zipped datasets results in a dataset.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
struct is_dataset<zip<DataSet1,DataSet2>> : mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace ds_detail {
|
||||
|
||||
//! Handles the sise of the resulting zipped dataset.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline data::size_t
|
||||
zip_size( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
data::size_t ds1_size = ds1.size();
|
||||
data::size_t ds2_size = ds2.size();
|
||||
|
||||
if( ds1_size == ds2_size )
|
||||
return ds1_size;
|
||||
|
||||
if( ds1_size == 1 || ds1_size.is_inf() )
|
||||
return ds2_size;
|
||||
|
||||
if( ds2_size == 1 || ds2_size.is_inf() )
|
||||
return ds1_size;
|
||||
|
||||
BOOST_TEST_DS_ERROR( "Can't zip datasets of different sizes" );
|
||||
}
|
||||
|
||||
} // namespace ds_detail
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace result_of {
|
||||
|
||||
//! Result type of the zip operator.
|
||||
template<typename DS1Gen, typename DS2Gen>
|
||||
struct zip {
|
||||
typedef monomorphic::zip<typename DS1Gen::type,typename DS2Gen::type> type;
|
||||
};
|
||||
|
||||
} // namespace result_of
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! Overload operator for zip support
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
|
||||
result_of::zip<mpl::identity<DataSet1>,mpl::identity<DataSet2>>
|
||||
>::type
|
||||
operator^( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return zip<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ),
|
||||
std::forward<DataSet2>( ds2 ),
|
||||
ds_detail::zip_size( ds1, ds2 ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::monomorphic::operator^()
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && !is_dataset<DataSet2>::value,
|
||||
result_of::zip<mpl::identity<DataSet1>,data::result_of::make<DataSet2>>
|
||||
>::type
|
||||
operator^( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return std::forward<DataSet1>( ds1 ) ^ data::make( std::forward<DataSet2>( ds2 ) );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! @overload boost::unit_test::data::monomorphic::operator^()
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline typename boost::lazy_enable_if_c<!is_dataset<DataSet1>::value && is_dataset<DataSet2>::value,
|
||||
result_of::zip<data::result_of::make<DataSet1>,mpl::identity<DataSet2>>
|
||||
>::type
|
||||
operator^( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return data::make( std::forward<DataSet1>( ds1 ) ) ^ std::forward<DataSet2>( ds2 );
|
||||
}
|
||||
|
||||
} // namespace monomorphic
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_NO_ZIP_COMPOSITION_AVAILABLE
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_ZIP_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,145 @@
|
||||
// (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 simple dataset size abstraction (can be infinite)
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_SIZE_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_SIZE_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
|
||||
// STL
|
||||
#include <iosfwd>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** size_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Utility for handling the size of a datasets
|
||||
class size_t {
|
||||
struct dummy { void nonnull() {} };
|
||||
typedef void (dummy::*safe_bool)();
|
||||
public:
|
||||
// Constructors
|
||||
size_t( std::size_t s = 0 ) : m_value( s ), m_infinity( false ) {}
|
||||
explicit size_t( bool ) : m_value( 0 ), m_infinity( true ) {}
|
||||
template<typename T>
|
||||
size_t( T v ) : m_value( static_cast<std::size_t>(v) ), m_infinity( false ) {}
|
||||
|
||||
// Access methods
|
||||
std::size_t value() const { return m_value; }
|
||||
bool is_inf() const { return m_infinity; }
|
||||
operator safe_bool() const { return is_inf() || m_value != 0 ? &dummy::nonnull : 0; }
|
||||
|
||||
// Unary operators
|
||||
data::size_t operator--() { if( !is_inf() ) m_value--; return *this; }
|
||||
data::size_t operator--(int) { data::size_t res(*this); if( !is_inf() ) m_value--; return res; }
|
||||
data::size_t operator++() { if( !is_inf() ) m_value++; return *this; }
|
||||
data::size_t operator++(int) { data::size_t res(*this); if( !is_inf() ) m_value++; return res; }
|
||||
|
||||
// Binary operators
|
||||
data::size_t& operator+=( std::size_t rhs ) { if( !is_inf() ) m_value += rhs; return *this; }
|
||||
data::size_t& operator+=( data::size_t rhs )
|
||||
{
|
||||
if( !is_inf() ) {
|
||||
if( rhs.is_inf() )
|
||||
*this = rhs;
|
||||
else
|
||||
m_value += rhs.value();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
data::size_t& operator-=( std::size_t rhs ) { if( !is_inf() ) m_value -= rhs; return *this; }
|
||||
data::size_t& operator-=( data::size_t rhs )
|
||||
{
|
||||
if( !is_inf() ) {
|
||||
if( value() < rhs.value() )
|
||||
m_value = 0;
|
||||
else
|
||||
m_value -= rhs.value();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::size_t m_value;
|
||||
bool m_infinity;
|
||||
};
|
||||
|
||||
namespace { const data::size_t BOOST_TEST_DS_INFINITE_SIZE( true ); }
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// Binary operators
|
||||
inline bool operator>(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() || (lhs.value() > rhs); }
|
||||
inline bool operator>(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs > rhs.value()); }
|
||||
inline bool operator>(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() > rhs.value(); }
|
||||
|
||||
inline bool operator>=(data::size_t lhs, std::size_t rhs ) { return lhs.is_inf() || (lhs.value() >= rhs); }
|
||||
inline bool operator>=(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs >= rhs.value()); }
|
||||
inline bool operator>=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? lhs.is_inf() : lhs.value() >= rhs.value(); }
|
||||
|
||||
inline bool operator<(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() < rhs); }
|
||||
inline bool operator<(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs < rhs.value()); }
|
||||
inline bool operator<(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() < rhs.value(); }
|
||||
|
||||
inline bool operator<=(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() <= rhs); }
|
||||
inline bool operator<=(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs <= rhs.value()); }
|
||||
inline bool operator<=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() ? rhs.is_inf() : lhs.value() <= rhs.value(); }
|
||||
|
||||
inline bool operator==(data::size_t lhs, std::size_t rhs) { return !lhs.is_inf() && (lhs.value() == rhs); }
|
||||
inline bool operator==(std::size_t lhs, data::size_t rhs) { return !rhs.is_inf() && (lhs == rhs.value()); }
|
||||
inline bool operator==(data::size_t lhs, data::size_t rhs) { return !(lhs.is_inf() ^ rhs.is_inf()) && lhs.value() == rhs.value(); }
|
||||
|
||||
inline bool operator!=(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() || (lhs.value() != rhs); }
|
||||
inline bool operator!=(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() || (lhs != rhs.value()); }
|
||||
inline bool operator!=(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() ^ rhs.is_inf() || lhs.value() != rhs.value(); }
|
||||
|
||||
inline data::size_t operator+(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() ? lhs : data::size_t( lhs.value()+rhs ); }
|
||||
inline data::size_t operator+(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() ? rhs : data::size_t( lhs+rhs.value() ); }
|
||||
inline data::size_t operator+(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()+rhs.value() ); }
|
||||
|
||||
inline data::size_t operator*(data::size_t lhs, std::size_t rhs) { return lhs.is_inf() ? lhs : data::size_t( lhs.value()*rhs ); }
|
||||
inline data::size_t operator*(std::size_t lhs, data::size_t rhs) { return rhs.is_inf() ? rhs : data::size_t( lhs*rhs.value() ); }
|
||||
inline data::size_t operator*(data::size_t lhs, data::size_t rhs) { return lhs.is_inf() || rhs.is_inf() ? data::size_t(true) : data::size_t( lhs.value()*rhs.value() ); }
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename CharT1, typename Tr>
|
||||
inline std::basic_ostream<CharT1,Tr>&
|
||||
operator<<( std::basic_ostream<CharT1,Tr>& os, data::size_t const& s )
|
||||
{
|
||||
if( s.is_inf() )
|
||||
os << "infinity";
|
||||
else
|
||||
os << s.value();
|
||||
|
||||
return os;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_SIZE_HPP_102211GER
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
// (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 case family based on data generator
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
|
||||
#define BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/dataset.hpp>
|
||||
#include <boost/test/data/for_each_sample.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
|
||||
#include <boost/preprocessor/variadic/to_seq.hpp>
|
||||
#include <boost/preprocessor/variadic/size.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/seq/for_each_i.hpp>
|
||||
#include <boost/preprocessor/seq/for_each.hpp>
|
||||
#include <boost/preprocessor/seq/enum.hpp>
|
||||
#include <boost/preprocessor/control/iif.hpp>
|
||||
#include <boost/preprocessor/comparison/equal.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
#include <boost/test/tools/detail/print_helper.hpp>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
|
||||
#if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
|
||||
&& !defined(BOOST_TEST_DATASET_MAX_ARITY)
|
||||
# define BOOST_TEST_DATASET_MAX_ARITY 10
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
namespace ds_detail {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** seed ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
struct seed {
|
||||
template<typename DataSet>
|
||||
typename data::result_of::make<DataSet>::type
|
||||
operator->*( DataSet&& ds ) const
|
||||
{
|
||||
return data::make( std::forward<DataSet>( ds ) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
|
||||
!defined(BOOST_NO_CXX11_DECLTYPE) && \
|
||||
!defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
|
||||
!defined(BOOST_NO_CXX11_SMART_PTR)
|
||||
|
||||
#define BOOST_TEST_DATASET_VARIADIC
|
||||
template <class T>
|
||||
struct parameter_holder {
|
||||
std::shared_ptr<T> value;
|
||||
|
||||
parameter_holder(T && value_)
|
||||
: value(std::make_shared<T>(std::move(value_)))
|
||||
{}
|
||||
|
||||
operator T const&() const {
|
||||
return *value;
|
||||
}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
parameter_holder<typename std::remove_reference<T>::type>
|
||||
boost_bind_rvalue_holder_helper_impl(T&& value, boost::false_type /* is copy constructible */) {
|
||||
return parameter_holder<typename std::remove_reference<T>::type>(std::forward<T>(value));
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T&& boost_bind_rvalue_holder_helper_impl(T&& value, boost::true_type /* is copy constructible */) {
|
||||
return std::forward<T>(value);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
auto boost_bind_rvalue_holder_helper(T&& value)
|
||||
-> decltype(boost_bind_rvalue_holder_helper_impl(
|
||||
std::forward<T>(value),
|
||||
typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type()))
|
||||
{
|
||||
// need to use boost::is_copy_constructible because std::is_copy_constructible is broken on MSVC12
|
||||
return boost_bind_rvalue_holder_helper_impl(
|
||||
std::forward<T>(value),
|
||||
typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type());
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** test_case_gen ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename TestCase,typename DataSet>
|
||||
class test_case_gen : public test_unit_generator {
|
||||
public:
|
||||
// Constructor
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
|
||||
: m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
|
||||
, m_tc_file( tc_file )
|
||||
, m_tc_line( tc_line )
|
||||
, m_tc_index( 0 )
|
||||
{
|
||||
data::for_each_sample( std::forward<DataSet>( ds ), *this );
|
||||
}
|
||||
test_case_gen( test_case_gen&& gen )
|
||||
: m_tc_name( gen.m_tc_name )
|
||||
, m_tc_file( gen.m_tc_file )
|
||||
, m_tc_line( gen.m_tc_line )
|
||||
, m_tc_index( gen.m_tc_index )
|
||||
, m_test_cases( std::move(gen.m_test_cases) )
|
||||
{}
|
||||
#else
|
||||
test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
|
||||
: m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
|
||||
, m_tc_file( tc_file )
|
||||
, m_tc_line( tc_line )
|
||||
, m_tc_index( 0 )
|
||||
{
|
||||
data::for_each_sample( ds, *this );
|
||||
}
|
||||
#endif
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
#if !defined(BOOST_TEST_DATASET_VARIADIC)
|
||||
// see BOOST_TEST_DATASET_MAX_ARITY to increase the default supported arity
|
||||
#define TC_MAKE(z,arity,_) \
|
||||
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
|
||||
void operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \
|
||||
{ \
|
||||
m_test_cases.push_back( new test_case( genTestCaseName(), m_tc_file, m_tc_line, \
|
||||
boost::bind( &TestCase::template test_method<BOOST_PP_ENUM_PARAMS(arity,Arg)>,\
|
||||
BOOST_PP_ENUM_PARAMS(arity, arg) ) ) ); \
|
||||
} \
|
||||
|
||||
BOOST_PP_REPEAT_FROM_TO(1, BOOST_TEST_DATASET_MAX_ARITY, TC_MAKE, _)
|
||||
#else
|
||||
template<typename ...Arg>
|
||||
void operator()(Arg&& ... arg) const
|
||||
{
|
||||
m_test_cases.push_back(
|
||||
new test_case( genTestCaseName(),
|
||||
m_tc_file,
|
||||
m_tc_line,
|
||||
boost::bind( &TestCase::template test_method<Arg...>,
|
||||
boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
std::string genTestCaseName() const
|
||||
{
|
||||
return "_" + utils::string_cast(m_tc_index++);
|
||||
}
|
||||
|
||||
// Data members
|
||||
std::string m_tc_name;
|
||||
const_string m_tc_file;
|
||||
std::size_t m_tc_line;
|
||||
mutable std::size_t m_tc_index;
|
||||
mutable std::list<test_unit*> m_test_cases;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template<typename TestCase,typename DataSet>
|
||||
test_case_gen<TestCase,DataSet>
|
||||
make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
|
||||
{
|
||||
return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, std::forward<DataSet>(ds) );
|
||||
}
|
||||
#else
|
||||
template<typename TestCase,typename DataSet>
|
||||
test_case_gen<TestCase,DataSet>
|
||||
make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
|
||||
{
|
||||
return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, ds );
|
||||
}
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace ds_detail
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** BOOST_DATA_TEST_CASE ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#define BOOST_DATA_TEST_CASE_PARAM(r, _, i, param) (BOOST_PP_CAT(Arg, i) const& param)
|
||||
#define BOOST_DATA_TEST_CONTEXT(r, _, param) << BOOST_STRINGIZE(param) << " = " << boost::test_tools::tt_detail::print_helper(param) << "; "
|
||||
|
||||
#define BOOST_DATA_TEST_CASE_PARAMS( params ) \
|
||||
BOOST_PP_SEQ_ENUM( \
|
||||
BOOST_PP_SEQ_FOR_EACH_I(BOOST_DATA_TEST_CASE_PARAM, _, params)) \
|
||||
/**/
|
||||
|
||||
#define BOOST_DATA_TEST_CASE_IMPL(arity, F, test_name, dataset, params) \
|
||||
struct BOOST_PP_CAT(test_name, case) : public F { \
|
||||
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
|
||||
static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
|
||||
{ \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");\
|
||||
BOOST_PP_CAT(test_name, case) t; \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
|
||||
BOOST_TEST_CONTEXT( "" \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
|
||||
t._impl(BOOST_PP_SEQ_ENUM(params)); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
|
||||
} \
|
||||
private: \
|
||||
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
|
||||
void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \
|
||||
}; \
|
||||
\
|
||||
BOOST_AUTO_TEST_SUITE( test_name ) \
|
||||
\
|
||||
BOOST_AUTO_TU_REGISTRAR( BOOST_PP_CAT(test_name, case) )( \
|
||||
boost::unit_test::data::ds_detail::make_test_case_gen< \
|
||||
BOOST_PP_CAT(test_name, case)>( \
|
||||
BOOST_STRINGIZE( test_name ), \
|
||||
__FILE__, __LINE__, \
|
||||
boost::unit_test::data::ds_detail::seed{} ->* dataset ), \
|
||||
boost::unit_test::decorator::collector::instance() ); \
|
||||
\
|
||||
BOOST_AUTO_TEST_SUITE_END() \
|
||||
\
|
||||
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
|
||||
void BOOST_PP_CAT(test_name, case)::_impl( \
|
||||
BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
|
||||
/**/
|
||||
|
||||
#define BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, ... ) \
|
||||
BOOST_DATA_TEST_CASE_IMPL( BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
|
||||
F, test_name, dataset, \
|
||||
BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
|
||||
/**/
|
||||
#define BOOST_DATA_TEST_CASE_NO_PARAMS( F, test_name, dataset ) \
|
||||
BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, sample ) \
|
||||
/**/
|
||||
|
||||
#if BOOST_PP_VARIADICS_MSVC
|
||||
|
||||
#define BOOST_DATA_TEST_CASE( ... ) \
|
||||
BOOST_PP_CAT( \
|
||||
BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
|
||||
BOOST_DATA_TEST_CASE_NO_PARAMS, \
|
||||
BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
|
||||
BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__), ) \
|
||||
/**/
|
||||
|
||||
#define BOOST_DATA_TEST_CASE_F( F, ... ) \
|
||||
BOOST_PP_CAT( \
|
||||
BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
|
||||
BOOST_DATA_TEST_CASE_NO_PARAMS, \
|
||||
BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
|
||||
F, __VA_ARGS__), ) \
|
||||
/**/
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_DATA_TEST_CASE( ... ) \
|
||||
BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
|
||||
BOOST_DATA_TEST_CASE_NO_PARAMS, \
|
||||
BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
|
||||
BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__) \
|
||||
/**/
|
||||
|
||||
#define BOOST_DATA_TEST_CASE_F( F, ... ) \
|
||||
BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
|
||||
BOOST_DATA_TEST_CASE_NO_PARAMS, \
|
||||
BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
|
||||
F, __VA_ARGS__) \
|
||||
/**/
|
||||
#endif
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 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 };
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! Indicates the output format for the loggers or the test tree printing
|
||||
enum output_format { OF_INVALID,
|
||||
OF_CLF, ///< compiler log format
|
||||
OF_XML, ///< XML format for report and log,
|
||||
OF_JUNIT, ///< JUNIT format for report and log,
|
||||
OF_CUSTOM_LOGGER, ///< User specified logger.
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
// (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_EXCEPTIONS
|
||||
|
||||
#ifdef BOOST_NO_EXCEPTIONS
|
||||
// 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_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
|
||||
@@ -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
|
||||
@@ -0,0 +1,578 @@
|
||||
// (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
|
||||
|
||||
#if defined(BOOST_SEH_BASED_SIGNAL_HANDLING) && !defined(UNDER_CE)
|
||||
//! Indicates tha the floating point exception handling is supported
|
||||
//! through SEH
|
||||
#define BOOST_TEST_FPE_SUPPORT_WITH_SEH__
|
||||
#elif !defined(BOOST_SEH_BASED_SIGNAL_HANDLING) && !defined(UNDER_CE)
|
||||
#if !defined(BOOST_NO_FENV_H) && !defined(BOOST_CLANG) && \
|
||||
defined(__GLIBC__) && defined(__USE_GNU) && \
|
||||
!(defined(__UCLIBC__) || defined(__nios2__) || defined(__microblaze__))
|
||||
//! Indicates that floating point exception handling is supported for the
|
||||
//! non SEH version of it, for the GLIBC extensions only
|
||||
// see dicussions on the related topic: https://svn.boost.org/trac/boost/ticket/11756
|
||||
#define BOOST_TEST_FPE_SUPPORT_WITH_GLIBC_EXTENSIONS__
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Additional macro documentations not being generated without this hack
|
||||
#ifdef BOOST_TEST_DOXYGEN_DOC__
|
||||
|
||||
//! Disables the support of the alternative stack
|
||||
//! during the compilation of the Boost.test framework. This is especially useful
|
||||
//! in case it is not possible to detect the lack of alternative stack support for
|
||||
//! your compiler (for instance, ESXi).
|
||||
#define BOOST_TEST_DISABLE_ALT_STACK
|
||||
|
||||
#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
|
||||
|
||||
// ************************************************************************** //
|
||||
/// @brief 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;
|
||||
};
|
||||
|
||||
//!@internal
|
||||
#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,
|
||||
|
||||
#if defined(BOOST_TEST_FPE_SUPPORT_WITH_SEH__) /* *** */
|
||||
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_TEST_FPE_SUPPORT_WITH_GLIBC_EXTENSIONS__)/* *** */
|
||||
BOOST_FPE_ALL = BOOST_FPE_OFF,
|
||||
|
||||
#else /* *** */
|
||||
|
||||
#if defined(FE_DIVBYZERO)
|
||||
BOOST_FPE_DIVBYZERO = FE_DIVBYZERO,
|
||||
#else
|
||||
BOOST_FPE_DIVBYZERO = BOOST_FPE_OFF,
|
||||
#endif
|
||||
|
||||
#if defined(FE_INEXACT)
|
||||
BOOST_FPE_INEXACT = FE_INEXACT,
|
||||
#else
|
||||
BOOST_FPE_INEXACT = BOOST_FPE_OFF,
|
||||
#endif
|
||||
|
||||
#if defined(FE_INVALID)
|
||||
BOOST_FPE_INVALID = FE_INVALID,
|
||||
#else
|
||||
BOOST_FPE_INVALID = BOOST_FPE_OFF,
|
||||
#endif
|
||||
|
||||
#if defined(FE_OVERFLOW)
|
||||
BOOST_FPE_OVERFLOW = FE_OVERFLOW,
|
||||
#else
|
||||
BOOST_FPE_OVERFLOW = BOOST_FPE_OFF,
|
||||
#endif
|
||||
|
||||
#if defined(FE_UNDERFLOW)
|
||||
BOOST_FPE_UNDERFLOW = FE_UNDERFLOW,
|
||||
#else
|
||||
BOOST_FPE_UNDERFLOW = BOOST_FPE_OFF,
|
||||
#endif
|
||||
|
||||
#if defined(FE_ALL_EXCEPT)
|
||||
BOOST_FPE_ALL = FE_ALL_EXCEPT,
|
||||
#else
|
||||
BOOST_FPE_ALL = BOOST_FPE_OFF,
|
||||
#endif
|
||||
|
||||
#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
|
||||
@@ -0,0 +1,14 @@
|
||||
// (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 header
|
||||
//! @deprecated Use boost/test/tools/floating_point_comparison.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/floating_point_comparison.hpp>
|
||||
@@ -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
|
||||
//!@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& );
|
||||
BOOST_TEST_DECL void setup_loggers( );
|
||||
} // 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
|
||||
@@ -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::btrt_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::UNDERLINE, 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::UNDERLINE, 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
|
||||
@@ -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
@@ -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
@@ -0,0 +1,772 @@
|
||||
// (C) Copyright 2016 Raffi Enficiaud.
|
||||
// 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 the implementatoin of the Junit log formatter (OF_JUNIT)
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_JUNIT_LOG_FORMATTER_IPP__
|
||||
#define BOOST_TEST_JUNIT_LOG_FORMATTER_IPP__
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/output/junit_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>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
#include <boost/test/framework.hpp>
|
||||
|
||||
#include <boost/test/tree/visitor.hpp>
|
||||
#include <boost/test/tree/test_case_counter.hpp>
|
||||
#include <boost/test/tree/traverse.hpp>
|
||||
#include <boost/test/results_collector.hpp>
|
||||
|
||||
#include <boost/test/utils/algorithm.hpp>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
|
||||
//#include <boost/test/results_reporter.hpp>
|
||||
|
||||
|
||||
// Boost
|
||||
#include <boost/version.hpp>
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <set>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace output {
|
||||
|
||||
|
||||
struct s_replace_chars {
|
||||
template <class T>
|
||||
void operator()(T& to_replace)
|
||||
{
|
||||
if(to_replace == '/')
|
||||
to_replace = '.';
|
||||
else if(to_replace == ' ')
|
||||
to_replace = '_';
|
||||
}
|
||||
};
|
||||
|
||||
inline std::string tu_name_normalize(std::string full_name)
|
||||
{
|
||||
// maybe directly using normalize_test_case_name instead?
|
||||
std::for_each(full_name.begin(), full_name.end(), s_replace_chars());
|
||||
return full_name;
|
||||
}
|
||||
|
||||
const_string file_basename(const_string filename) {
|
||||
|
||||
const_string path_sep( "\\/" );
|
||||
const_string::iterator it = unit_test::utils::find_last_of( filename.begin(), filename.end(),
|
||||
path_sep.begin(), path_sep.end() );
|
||||
if( it != filename.end() )
|
||||
filename.trim_left( it + 1 );
|
||||
|
||||
return filename;
|
||||
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** junit_log_formatter ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
junit_log_formatter::log_start( std::ostream& ostr, counter_t test_cases_amount)
|
||||
{
|
||||
map_tests.clear();
|
||||
list_path_to_root.clear();
|
||||
runner_log_entry.clear();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
class junit_result_helper : public test_tree_visitor {
|
||||
public:
|
||||
explicit junit_result_helper(
|
||||
std::ostream& stream,
|
||||
test_unit const& ts,
|
||||
junit_log_formatter::map_trace_t const& mt,
|
||||
junit_impl::junit_log_helper const& runner_log_,
|
||||
bool display_build_info )
|
||||
: m_stream(stream)
|
||||
, m_ts( ts )
|
||||
, m_map_test( mt )
|
||||
, runner_log( runner_log_ )
|
||||
, m_id( 0 )
|
||||
, m_display_build_info(display_build_info)
|
||||
{ }
|
||||
|
||||
void add_log_entry(std::string const& entry_type,
|
||||
test_case const& tc,
|
||||
junit_impl::junit_log_helper::assertion_entry const& log) const
|
||||
{
|
||||
m_stream
|
||||
<< "<" << entry_type
|
||||
<< " message" << utils::attr_value() << log.logentry_message
|
||||
<< " type" << utils::attr_value() << log.logentry_type
|
||||
<< ">";
|
||||
|
||||
if(!log.output.empty()) {
|
||||
m_stream << utils::cdata() << "\n" + log.output;
|
||||
}
|
||||
|
||||
m_stream << "</" << entry_type << ">";
|
||||
}
|
||||
|
||||
struct conditional_cdata_helper {
|
||||
std::ostream &ostr;
|
||||
std::string const field;
|
||||
bool empty;
|
||||
|
||||
conditional_cdata_helper(std::ostream &ostr_, std::string field_)
|
||||
: ostr(ostr_)
|
||||
, field(field_)
|
||||
, empty(true)
|
||||
{}
|
||||
|
||||
~conditional_cdata_helper() {
|
||||
if(!empty) {
|
||||
ostr << BOOST_TEST_L( "]]>" ) << "</" << field << '>' << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(const std::string& s) {
|
||||
bool current_empty = s.empty();
|
||||
if(empty) {
|
||||
if(!current_empty) {
|
||||
empty = false;
|
||||
ostr << '<' << field << '>' << BOOST_TEST_L( "<![CDATA[" );
|
||||
}
|
||||
}
|
||||
if(!current_empty) {
|
||||
ostr << s;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
std::list<std::string> build_skipping_chain(test_case const & tc) const
|
||||
{
|
||||
// we enter here because we know that the tc has been skipped.
|
||||
// either junit has not seen this tc, or it is indicated as disabled
|
||||
assert(m_map_test.count(tc.p_id) == 0 || results_collector.results( tc.p_id ).p_skipped);
|
||||
|
||||
std::list<std::string> out;
|
||||
|
||||
test_unit_id id(tc.p_id);
|
||||
while( id != m_ts.p_id && id != INV_TEST_UNIT_ID) {
|
||||
test_unit const& tu = boost::unit_test::framework::get( id, TUT_ANY );
|
||||
out.push_back("- disabled test unit: '" + tu.full_name() + "'\n");
|
||||
if(m_map_test.count(id) > 0)
|
||||
{
|
||||
// junit has seen the reason: this is enough for constructing the chain
|
||||
break;
|
||||
}
|
||||
id = tu.p_parent_id;
|
||||
}
|
||||
junit_log_formatter::map_trace_t::const_iterator it_element_stack(m_map_test.find(id));
|
||||
if( it_element_stack != m_map_test.end() )
|
||||
{
|
||||
out.push_back("- reason: '" + it_element_stack->second.skipping_reason + "'");
|
||||
out.push_front("Test case disabled because of the following chain of decision:\n");
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string get_class_name(test_case const & tc) const {
|
||||
std::string classname;
|
||||
test_unit_id id(tc.p_parent_id);
|
||||
while( id != m_ts.p_id && id != INV_TEST_UNIT_ID ) {
|
||||
test_unit const& tu = boost::unit_test::framework::get( id, TUT_ANY );
|
||||
classname = tu_name_normalize(tu.p_name) + "." + classname;
|
||||
id = tu.p_parent_id;
|
||||
}
|
||||
|
||||
// removes the trailing dot
|
||||
if(!classname.empty() && *classname.rbegin() == '.') {
|
||||
classname.erase(classname.size()-1);
|
||||
}
|
||||
|
||||
return classname;
|
||||
}
|
||||
|
||||
void write_testcase_header(test_case const & tc,
|
||||
test_results const *tr = 0) const
|
||||
{
|
||||
//
|
||||
// test case header
|
||||
|
||||
// total number of assertions
|
||||
m_stream << "<testcase assertions" << utils::attr_value() << tr->p_assertions_passed + tr->p_assertions_failed;
|
||||
|
||||
// class name
|
||||
const std::string classname = get_class_name(tc);
|
||||
if(!classname.empty())
|
||||
m_stream << " classname" << utils::attr_value() << classname;
|
||||
|
||||
// test case name and time taken
|
||||
m_stream
|
||||
<< " name" << utils::attr_value() << tu_name_normalize(tc.p_name)
|
||||
<< " time" << utils::attr_value() << double(tr->p_duration_microseconds) * 1E-6
|
||||
<< ">" << std::endl;
|
||||
}
|
||||
|
||||
void write_testcase_system_out(junit_impl::junit_log_helper const &detailed_log,
|
||||
test_case const * tc,
|
||||
bool skipped,
|
||||
test_results const *tr = 0) const
|
||||
{
|
||||
// system-out + all info/messages, the object skips the empty entries
|
||||
conditional_cdata_helper system_out_helper(m_stream, "system-out");
|
||||
|
||||
// indicate why the test has been skipped first
|
||||
if( skipped ) {
|
||||
std::list<std::string> skipping_decision_chain = build_skipping_chain(*tc);
|
||||
for(std::list<std::string>::const_iterator it(skipping_decision_chain.begin()), ite(skipping_decision_chain.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
system_out_helper(*it);
|
||||
}
|
||||
}
|
||||
|
||||
// stdout
|
||||
for(std::list<std::string>::const_iterator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
system_out_helper(*it);
|
||||
}
|
||||
|
||||
// warning/info message last
|
||||
for(std::vector< junit_impl::junit_log_helper::assertion_entry >::const_iterator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
if(it->log_entry != junit_impl::junit_log_helper::assertion_entry::log_entry_info)
|
||||
continue;
|
||||
system_out_helper(it->output);
|
||||
}
|
||||
}
|
||||
|
||||
void write_testcase_system_err(junit_impl::junit_log_helper const &detailed_log,
|
||||
test_case const * tc,
|
||||
test_results const *tr = 0) const
|
||||
{
|
||||
// system-err output + test case informations
|
||||
bool has_failed = (tr != 0) ? !tr->passed() : false;
|
||||
if(!detailed_log.system_err.empty() || has_failed)
|
||||
{
|
||||
conditional_cdata_helper system_err_helper(m_stream, "system-err");
|
||||
std::ostringstream o;
|
||||
if(has_failed) {
|
||||
o << "Failures detected in:" << std::endl;
|
||||
}
|
||||
else {
|
||||
o << "ERROR STREAM:" << std::endl;
|
||||
}
|
||||
|
||||
o << "- test case: " << tc->full_name() << std::endl;
|
||||
if(!tc->p_description.value.empty())
|
||||
o << " '" << tc->p_description << "'";
|
||||
|
||||
o << std::endl
|
||||
<< "- file: " << file_basename(tc->p_file_name) << std::endl
|
||||
<< "- line: " << tc->p_line_num << std::endl
|
||||
;
|
||||
|
||||
if(!detailed_log.system_err.empty())
|
||||
o << std::endl << "STDERR BEGIN: ------------" << std::endl;
|
||||
|
||||
system_err_helper(o.str());
|
||||
for(std::list<std::string>::const_iterator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
system_err_helper(*it);
|
||||
}
|
||||
|
||||
if(!detailed_log.system_err.empty())
|
||||
o << std::endl << "STDERR END ------------" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void output_detailed_logs(junit_impl::junit_log_helper const &detailed_log,
|
||||
test_case const & tc,
|
||||
bool skipped,
|
||||
test_results const *tr = 0) const
|
||||
{
|
||||
write_testcase_header(tc, tr);
|
||||
|
||||
if( skipped ) {
|
||||
m_stream << "<skipped/>" << std::endl;
|
||||
}
|
||||
else {
|
||||
|
||||
for(std::vector< junit_impl::junit_log_helper::assertion_entry >::const_iterator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
if(it->log_entry == junit_impl::junit_log_helper::assertion_entry::log_entry_failure) {
|
||||
add_log_entry("failure", tc, *it);
|
||||
}
|
||||
else if(it->log_entry == junit_impl::junit_log_helper::assertion_entry::log_entry_error) {
|
||||
add_log_entry("error", tc, *it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
write_testcase_system_out(detailed_log, &tc, skipped, tr);
|
||||
write_testcase_system_err(detailed_log, &tc, tr);
|
||||
m_stream << "</testcase>" << std::endl;
|
||||
}
|
||||
|
||||
void visit( test_case const& tc )
|
||||
{
|
||||
|
||||
test_results const& tr = results_collector.results( tc.p_id );
|
||||
junit_log_formatter::map_trace_t::const_iterator it_find = m_map_test.find(tc.p_id);
|
||||
if(it_find == m_map_test.end())
|
||||
{
|
||||
// test has been skipped and not seen by the logger
|
||||
output_detailed_logs(junit_impl::junit_log_helper(), tc, true, &tr);
|
||||
}
|
||||
else {
|
||||
output_detailed_logs(it_find->second, tc, tr.p_skipped, &tr);
|
||||
}
|
||||
}
|
||||
|
||||
bool test_suite_start( test_suite const& ts )
|
||||
{
|
||||
// unique test suite, without s, nesting not supported in CI
|
||||
if( m_ts.p_id != ts.p_id )
|
||||
return true;
|
||||
|
||||
test_results const& tr = results_collector.results( ts.p_id );
|
||||
m_stream << "<testsuite";
|
||||
|
||||
m_stream
|
||||
// << "disabled=\"" << tr.p_test_cases_skipped << "\" "
|
||||
<< " tests" << utils::attr_value() << tr.p_test_cases_passed
|
||||
<< " skipped" << utils::attr_value() << tr.p_test_cases_skipped
|
||||
<< " errors" << utils::attr_value() << tr.p_test_cases_aborted
|
||||
<< " failures" << utils::attr_value() << tr.p_test_cases_failed
|
||||
<< " id" << utils::attr_value() << m_id++
|
||||
<< " name" << utils::attr_value() << tu_name_normalize(ts.p_name)
|
||||
<< " time" << utils::attr_value() << (tr.p_duration_microseconds * 1E-6)
|
||||
<< ">" << std::endl;
|
||||
|
||||
if(m_display_build_info)
|
||||
{
|
||||
m_stream << "<properties>" << std::endl;
|
||||
m_stream << "<property name=\"platform\" value" << utils::attr_value() << BOOST_PLATFORM << std::endl;
|
||||
m_stream << "<property name=\"compiler\" value" << utils::attr_value() << BOOST_COMPILER << std::endl;
|
||||
m_stream << "<property name=\"stl\" value" << utils::attr_value() << BOOST_STDLIB << std::endl;
|
||||
|
||||
std::ostringstream o;
|
||||
o << BOOST_VERSION/100000 << "." << BOOST_VERSION/100 % 1000 << "." << BOOST_VERSION % 100;
|
||||
m_stream << "<property name=\"boost\" value" << utils::attr_value() << o.str() << std::endl;
|
||||
m_stream << "</properties>" << std::endl;
|
||||
}
|
||||
|
||||
return true; // indicates that the children should also be parsed
|
||||
}
|
||||
|
||||
virtual void test_suite_finish( test_suite const& ts )
|
||||
{
|
||||
if( m_ts.p_id != ts.p_id )
|
||||
return;
|
||||
|
||||
write_testcase_system_out(runner_log, 0, false, 0);
|
||||
write_testcase_system_err(runner_log, 0, 0);
|
||||
|
||||
m_stream << "</testsuite>";
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::ostream& m_stream;
|
||||
test_unit const& m_ts;
|
||||
junit_log_formatter::map_trace_t const& m_map_test;
|
||||
junit_impl::junit_log_helper const& runner_log;
|
||||
size_t m_id;
|
||||
bool m_display_build_info;
|
||||
};
|
||||
|
||||
|
||||
|
||||
void
|
||||
junit_log_formatter::log_finish( std::ostream& ostr )
|
||||
{
|
||||
ostr << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << std::endl;
|
||||
|
||||
// getting the root test suite
|
||||
if(!map_tests.empty()) {
|
||||
test_unit* root = &boost::unit_test::framework::get( map_tests.begin()->first, TUT_ANY );
|
||||
|
||||
// looking for the root of the SUBtree (we stay in the subtree)
|
||||
while(root->p_parent_id != INV_TEST_UNIT_ID && map_tests.count(root->p_parent_id) > 0) {
|
||||
root = &boost::unit_test::framework::get( root->p_parent_id, TUT_ANY );
|
||||
}
|
||||
junit_result_helper ch( ostr, *root, map_tests, this->runner_log_entry, m_display_build_info );
|
||||
traverse_test_tree( root->p_id, ch, true ); // last is to ignore disabled suite special handling
|
||||
}
|
||||
else {
|
||||
ostr << "<testsuites errors=\"1\">";
|
||||
ostr << "<testsuite errors=\"1\" name=\"boost-test-framework\">";
|
||||
ostr << "<testcase assertions=\"1\" name=\"test-setup\">";
|
||||
ostr << "<system-out>Incorrect setup: no test case executed</system-out>";
|
||||
ostr << "</testcase></testsuite></testsuites>";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_build_info( std::ostream& ostr )
|
||||
{
|
||||
m_display_build_info = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu )
|
||||
{
|
||||
list_path_to_root.push_back( tu.p_id );
|
||||
map_tests.insert(std::make_pair(tu.p_id, junit_impl::junit_log_helper())); // current_test_case_id not working here
|
||||
}
|
||||
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_finish( std::ostream& ostr, test_unit const& tu, unsigned long elapsed )
|
||||
{
|
||||
// the time is already stored in the result_reporter
|
||||
assert( tu.p_id == list_path_to_root.back() );
|
||||
list_path_to_root.pop_back();
|
||||
}
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_aborted( std::ostream& os, test_unit const& tu )
|
||||
{
|
||||
assert( tu.p_id == list_path_to_root.back() );
|
||||
//list_path_to_root.pop_back();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu, const_string reason )
|
||||
{
|
||||
// if a test unit is skipped, then the start of this TU has not been called yet.
|
||||
// we cannot use get_current_log_entry here, but the TU id should appear in the map.
|
||||
// The "skip" boolean is given by the boost.test framework
|
||||
junit_impl::junit_log_helper& v = map_tests[tu.p_id]; // not sure if we can use get_current_log_entry()
|
||||
v.skipping_reason.assign(reason.begin(), reason.end());
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
|
||||
{
|
||||
std::ostringstream o;
|
||||
execution_exception::location const& loc = ex.where();
|
||||
|
||||
m_is_last_assertion_or_error = false;
|
||||
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
|
||||
junit_impl::junit_log_helper::assertion_entry entry;
|
||||
|
||||
entry.logentry_message = "unexpected exception";
|
||||
entry.log_entry = junit_impl::junit_log_helper::assertion_entry::log_entry_error;
|
||||
|
||||
switch(ex.code())
|
||||
{
|
||||
case execution_exception::cpp_exception_error:
|
||||
entry.logentry_type = "uncaught exception";
|
||||
break;
|
||||
case execution_exception::timeout_error:
|
||||
entry.logentry_type = "execution timeout";
|
||||
break;
|
||||
case execution_exception::user_error:
|
||||
entry.logentry_type = "user, assert() or CRT error";
|
||||
break;
|
||||
case execution_exception::user_fatal_error:
|
||||
// Looks like never used
|
||||
entry.logentry_type = "user fatal error";
|
||||
break;
|
||||
case execution_exception::system_error:
|
||||
entry.logentry_type = "system error";
|
||||
break;
|
||||
case execution_exception::system_fatal_error:
|
||||
entry.logentry_type = "system fatal error";
|
||||
break;
|
||||
default:
|
||||
entry.logentry_type = "no error"; // not sure how to handle this one
|
||||
break;
|
||||
}
|
||||
|
||||
o << "UNCAUGHT EXCEPTION:" << std::endl;
|
||||
if( !loc.m_function.is_empty() )
|
||||
o << "- function: \"" << loc.m_function << "\"" << std::endl;
|
||||
|
||||
o << "- file: " << file_basename(loc.m_file_name) << std::endl
|
||||
<< "- line: " << loc.m_line_num << std::endl
|
||||
<< std::endl;
|
||||
|
||||
o << "\nEXCEPTION STACK TRACE: --------------\n" << ex.what()
|
||||
<< "\n-------------------------------------";
|
||||
|
||||
if( !checkpoint_data.m_file_name.is_empty() ) {
|
||||
o << std::endl << std::endl
|
||||
<< "Last checkpoint:" << std::endl
|
||||
<< "- message: \"" << checkpoint_data.m_message << "\"" << std::endl
|
||||
<< "- file: " << file_basename(checkpoint_data.m_file_name) << std::endl
|
||||
<< "- line: " << checkpoint_data.m_line_num << std::endl
|
||||
;
|
||||
}
|
||||
|
||||
entry.output = o.str();
|
||||
|
||||
last_entry.assertion_entries.push_back(entry);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_exception_finish( std::ostream& ostr )
|
||||
{
|
||||
// sealing the last entry
|
||||
assert(!get_current_log_entry().assertion_entries.back().sealed);
|
||||
get_current_log_entry().assertion_entries.back().sealed = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& entry_data, log_entry_types let )
|
||||
{
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
last_entry.skipping = false;
|
||||
m_is_last_assertion_or_error = true;
|
||||
switch(let)
|
||||
{
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_INFO:
|
||||
{
|
||||
if(m_log_level_internal > log_successful_tests) {
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
// no break on purpose
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_MESSAGE:
|
||||
{
|
||||
if(m_log_level_internal > log_messages) {
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
// no break on purpose
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_WARNING:
|
||||
{
|
||||
if(m_log_level_internal > log_warnings) {
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
std::ostringstream o;
|
||||
junit_impl::junit_log_helper::assertion_entry entry;
|
||||
|
||||
entry.log_entry = junit_impl::junit_log_helper::assertion_entry::log_entry_info;
|
||||
entry.logentry_message = "info";
|
||||
entry.logentry_type = "message";
|
||||
|
||||
o << (let == unit_test_log_formatter::BOOST_UTL_ET_WARNING ?
|
||||
"WARNING:" : (let == unit_test_log_formatter::BOOST_UTL_ET_MESSAGE ?
|
||||
"MESSAGE:" : "INFO:"))
|
||||
<< std::endl
|
||||
<< "- file : " << file_basename(entry_data.m_file_name) << std::endl
|
||||
<< "- line : " << entry_data.m_line_num << std::endl
|
||||
<< "- message: "; // no CR
|
||||
|
||||
entry.output += o.str();
|
||||
last_entry.assertion_entries.push_back(entry);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_ERROR:
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_FATAL_ERROR:
|
||||
{
|
||||
std::ostringstream o;
|
||||
junit_impl::junit_log_helper::assertion_entry entry;
|
||||
entry.log_entry = junit_impl::junit_log_helper::assertion_entry::log_entry_failure;
|
||||
entry.logentry_message = "failure";
|
||||
entry.logentry_type = (let == unit_test_log_formatter::BOOST_UTL_ET_ERROR ? "assertion error" : "fatal error");
|
||||
|
||||
o << "ASSERTION FAILURE:" << std::endl
|
||||
<< "- file : " << file_basename(entry_data.m_file_name) << std::endl
|
||||
<< "- line : " << entry_data.m_line_num << std::endl
|
||||
<< "- message: " ; // no CR
|
||||
|
||||
entry.output += o.str();
|
||||
last_entry.assertion_entries.push_back(entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
|
||||
{
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
if(last_entry.skipping)
|
||||
return;
|
||||
|
||||
assert(last_entry.assertion_entries.empty() || !last_entry.assertion_entries.back().sealed);
|
||||
|
||||
if(!last_entry.assertion_entries.empty())
|
||||
{
|
||||
junit_impl::junit_log_helper::assertion_entry& log_entry = last_entry.assertion_entries.back();
|
||||
log_entry.output += value;
|
||||
}
|
||||
else
|
||||
{
|
||||
// this may be a message coming from another observer
|
||||
// the prefix is set in the log_entry_start
|
||||
last_entry.system_out.push_back(std::string(value.begin(), value.end()));
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_finish( std::ostream& ostr )
|
||||
{
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
if(!last_entry.skipping)
|
||||
{
|
||||
assert(last_entry.assertion_entries.empty() || !last_entry.assertion_entries.back().sealed);
|
||||
|
||||
if(!last_entry.assertion_entries.empty()) {
|
||||
junit_impl::junit_log_helper::assertion_entry& log_entry = last_entry.assertion_entries.back();
|
||||
log_entry.output += "\n\n"; // quote end, CR
|
||||
log_entry.sealed = true;
|
||||
}
|
||||
else {
|
||||
last_entry.system_out.push_back("\n\n"); // quote end, CR
|
||||
}
|
||||
}
|
||||
|
||||
last_entry.skipping = false;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::entry_context_start( std::ostream& ostr, log_level )
|
||||
{
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
if(last_entry.skipping)
|
||||
return;
|
||||
|
||||
std::vector< junit_impl::junit_log_helper::assertion_entry > &v_failure_or_error = last_entry.assertion_entries;
|
||||
assert(!v_failure_or_error.back().sealed);
|
||||
|
||||
junit_impl::junit_log_helper::assertion_entry& last_log_entry = v_failure_or_error.back();
|
||||
if(m_is_last_assertion_or_error)
|
||||
{
|
||||
last_log_entry.output += "\n- context:\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
last_log_entry.output += "\n\nCONTEXT:\n";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
{
|
||||
// no op, may be removed
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
if(last_entry.skipping)
|
||||
return;
|
||||
assert(!get_current_log_entry().assertion_entries.back().sealed);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr )
|
||||
{
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
if(last_entry.skipping)
|
||||
return;
|
||||
|
||||
assert(!last_entry.assertion_entries.back().sealed);
|
||||
junit_impl::junit_log_helper::assertion_entry& last_log_entry = get_current_log_entry().assertion_entries.back();
|
||||
|
||||
last_log_entry.output +=
|
||||
(m_is_last_assertion_or_error ? " - '": "- '") + std::string(context_descr.begin(), context_descr.end()) + "'\n"; // quote end
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
|
||||
std::string
|
||||
junit_log_formatter::get_default_stream_description() const {
|
||||
std::string name = framework::master_test_suite().p_name.value;
|
||||
|
||||
static const std::string to_replace[] = { " ", "\"", "/", "\\", ":"};
|
||||
static const std::string replacement[] = { "_", "_" , "_", "_" , "_"};
|
||||
|
||||
name = unit_test::utils::replace_all_occurrences_of(
|
||||
name,
|
||||
to_replace, to_replace + sizeof(to_replace)/sizeof(to_replace[0]),
|
||||
replacement, replacement + sizeof(replacement)/sizeof(replacement[0]));
|
||||
|
||||
std::ifstream check_init((name + ".xml").c_str());
|
||||
if(!check_init)
|
||||
return name + ".xml";
|
||||
|
||||
int index = 0;
|
||||
for(; index < 100; index++) {
|
||||
std::string candidate = name + "_" + utils::string_cast(index) + ".xml";
|
||||
std::ifstream file(candidate.c_str());
|
||||
if(!file)
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return name + ".xml";
|
||||
}
|
||||
|
||||
} // namespace output
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_junit_log_formatter_IPP_020105GER
|
||||
@@ -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::btrt_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
|
||||
@@ -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::btrt_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
|
||||
@@ -0,0 +1,279 @@
|
||||
// (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;
|
||||
p_duration_microseconds.value += tr.p_duration_microseconds;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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_duration_microseconds.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 elapsed_in_microseconds )
|
||||
{
|
||||
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 & tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
tr.p_duration_microseconds.value = elapsed_in_microseconds;
|
||||
|
||||
bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
|
||||
if( !num_failures_match )
|
||||
BOOST_TEST_FRAMEWORK_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_FRAMEWORK_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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,808 @@
|
||||
// (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>
|
||||
|
||||
#include <boost/test/utils/algorithm.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<bool>::operator()( std::ostream& ostr, bool t )
|
||||
{
|
||||
ostr << std::boolalpha << t;
|
||||
}
|
||||
|
||||
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" );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
void
|
||||
print_log_value<std::nullptr_t>::operator()( std::ostream& ostr, std::nullptr_t p )
|
||||
{
|
||||
ostr << "nullptr";
|
||||
}
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** 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_FRAMEWORK_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;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
std::string pretty_print_log(std::string str) {
|
||||
|
||||
static const std::string to_replace[] = { "\r", "\n" };
|
||||
static const std::string replacement[] = { "\\r", "\\n" };
|
||||
|
||||
return unit_test::utils::replace_all_occurrences_of(
|
||||
str,
|
||||
to_replace, to_replace + sizeof(to_replace)/sizeof(to_replace[0]),
|
||||
replacement, replacement + sizeof(replacement)/sizeof(replacement[0]));
|
||||
}
|
||||
|
||||
assertion_result
|
||||
output_test_stream::match_pattern( bool flush_stream )
|
||||
{
|
||||
const std::string::size_type n_chars_presuffix = 10;
|
||||
sync();
|
||||
|
||||
assertion_result result( true );
|
||||
|
||||
const std::string stream_string_repr = get_stream_string_representation();
|
||||
|
||||
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 ) {
|
||||
|
||||
int offset = 0;
|
||||
std::vector<char> last_elements;
|
||||
for ( std::string::size_type i = 0; static_cast<int>(i + offset) < static_cast<int>(stream_string_repr.length()); ++i ) {
|
||||
char c = m_pimpl->get_char();
|
||||
|
||||
if( last_elements.size() <= n_chars_presuffix ) {
|
||||
last_elements.push_back( c );
|
||||
}
|
||||
else {
|
||||
last_elements[ i % last_elements.size() ] = c;
|
||||
}
|
||||
|
||||
bool is_same = !m_pimpl->m_pattern.fail() &&
|
||||
!m_pimpl->m_pattern.eof() &&
|
||||
(stream_string_repr[i+offset] == c);
|
||||
|
||||
if( !is_same ) {
|
||||
|
||||
result = false;
|
||||
|
||||
std::string::size_type prefix_size = (std::min)( i + offset, n_chars_presuffix );
|
||||
|
||||
std::string::size_type suffix_size = (std::min)( stream_string_repr.length() - i - offset,
|
||||
n_chars_presuffix );
|
||||
|
||||
// try to log area around the mismatch
|
||||
std::string substr = stream_string_repr.substr(0, i+offset);
|
||||
std::size_t line = std::count(substr.begin(), substr.end(), '\n');
|
||||
std::size_t column = i + offset - substr.rfind('\n');
|
||||
|
||||
result.message()
|
||||
<< "Mismatch at position " << i
|
||||
<< " (line " << line
|
||||
<< ", column " << column
|
||||
<< "): '" << pretty_print_log(std::string(1, stream_string_repr[i+offset])) << "' != '" << pretty_print_log(std::string(1, c)) << "' :\n";
|
||||
|
||||
// we already escape this substring because we need its actual size for the pretty print
|
||||
// of the difference location.
|
||||
std::string sub_str_prefix(pretty_print_log(stream_string_repr.substr( i + offset - prefix_size, prefix_size )));
|
||||
|
||||
// we need this substring as is because we compute the best matching substrings on it.
|
||||
std::string sub_str_suffix(stream_string_repr.substr( i + offset, suffix_size));
|
||||
result.message() << "... " << sub_str_prefix + pretty_print_log(sub_str_suffix) << " ..." << '\n';
|
||||
|
||||
result.message() << "... ";
|
||||
for( std::size_t j = 0; j < last_elements.size() ; j++ )
|
||||
result.message() << pretty_print_log(std::string(1, last_elements[(i + j + 1) % last_elements.size()]));
|
||||
|
||||
std::vector<char> last_elements_ordered;
|
||||
last_elements_ordered.push_back(c);
|
||||
for( std::string::size_type counter = 0; counter < suffix_size - 1 ; counter++ ) {
|
||||
char c2 = m_pimpl->get_char();
|
||||
|
||||
if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
|
||||
break;
|
||||
|
||||
result.message() << pretty_print_log(std::string(1, c2));
|
||||
|
||||
last_elements_ordered.push_back(c2);
|
||||
}
|
||||
|
||||
// tries to find the best substring matching in the remainder of the
|
||||
// two strings
|
||||
std::size_t max_nb_char_in_common = 0;
|
||||
std::size_t best_pattern_start_index = 0;
|
||||
std::size_t best_stream_start_index = 0;
|
||||
for( std::size_t pattern_start_index = best_pattern_start_index;
|
||||
pattern_start_index < last_elements_ordered.size();
|
||||
pattern_start_index++ ) {
|
||||
for( std::size_t stream_start_index = best_stream_start_index;
|
||||
stream_start_index < sub_str_suffix.size();
|
||||
stream_start_index++ ) {
|
||||
|
||||
std::size_t max_size = (std::min)( last_elements_ordered.size() - pattern_start_index, sub_str_suffix.size() - stream_start_index );
|
||||
if( max_nb_char_in_common > max_size )
|
||||
break; // safely break to go to the outer loop
|
||||
|
||||
std::size_t nb_char_in_common = 0;
|
||||
for( std::size_t k = 0; k < max_size; k++) {
|
||||
if( last_elements_ordered[pattern_start_index + k] == sub_str_suffix[stream_start_index + k] )
|
||||
nb_char_in_common ++;
|
||||
else
|
||||
break; // we take fully macthing substring only
|
||||
}
|
||||
|
||||
if( nb_char_in_common > max_nb_char_in_common ) {
|
||||
max_nb_char_in_common = nb_char_in_common;
|
||||
best_pattern_start_index = pattern_start_index;
|
||||
best_stream_start_index = stream_start_index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// indicates with more precision the location of the mismatchs in ascii arts ...
|
||||
result.message() << " ...\n... ";
|
||||
for( std::string::size_type j = 0; j < sub_str_prefix.size(); j++) {
|
||||
result.message() << ' ';
|
||||
}
|
||||
|
||||
for( std::size_t k = 0; k < (std::max)(best_pattern_start_index, best_stream_start_index); k++ ) { // 1 is for the current char c
|
||||
std::string s1(pretty_print_log(std::string(1, last_elements_ordered[(std::min)(k, best_pattern_start_index)])));
|
||||
std::string s2(pretty_print_log(std::string(1, sub_str_suffix[(std::min)(k, best_stream_start_index)])));
|
||||
for( int h = (std::max)(s1.size(), s2.size()); h > 0; h--)
|
||||
result.message() << "~";
|
||||
}
|
||||
result.message() << "\n";
|
||||
|
||||
// first char is a replicat of c, so we do not copy it.
|
||||
for(std::string::size_type counter = 0; counter < last_elements_ordered.size() - 1 ; counter++)
|
||||
last_elements[ (i + 1 + counter) % last_elements.size() ] = last_elements_ordered[counter + 1];
|
||||
|
||||
i += last_elements_ordered.size()-1;
|
||||
offset += best_stream_start_index - best_pattern_start_index;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// not needed anymore
|
||||
/*
|
||||
if(offset > 0 && false) {
|
||||
m_pimpl->m_pattern.ignore(
|
||||
static_cast<std::streamsize>( offset ));
|
||||
}
|
||||
*/
|
||||
}
|
||||
else {
|
||||
m_pimpl->m_pattern.write( stream_string_repr.c_str(),
|
||||
static_cast<std::streamsize>( stream_string_repr.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::string
|
||||
output_test_stream::get_stream_string_representation() const {
|
||||
return m_pimpl->m_synced_string;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
@@ -0,0 +1,461 @@
|
||||
// (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(), ' ', '_');
|
||||
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
|
||||
@@ -0,0 +1,678 @@
|
||||
// (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/utils/foreach.hpp>
|
||||
|
||||
#include <boost/test/output/compiler_log_formatter.hpp>
|
||||
#include <boost/test/output/xml_log_formatter.hpp>
|
||||
#include <boost/test/output/junit_log_formatter.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/shared_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 {
|
||||
|
||||
// log data
|
||||
struct unit_test_log_data_helper_impl {
|
||||
typedef boost::shared_ptr<unit_test_log_formatter> formatter_ptr;
|
||||
typedef boost::shared_ptr<io_saver_type> saver_ptr;
|
||||
|
||||
bool m_enabled;
|
||||
output_format m_format;
|
||||
std::ostream* m_stream;
|
||||
saver_ptr m_stream_state_saver;
|
||||
formatter_ptr m_log_formatter;
|
||||
bool m_entry_in_progress;
|
||||
|
||||
unit_test_log_data_helper_impl(unit_test_log_formatter* p_log_formatter, output_format format, bool enabled = false)
|
||||
: m_enabled( enabled )
|
||||
, m_format( format )
|
||||
, m_stream( &std::cout )
|
||||
, m_stream_state_saver( new io_saver_type( std::cout ) )
|
||||
, m_log_formatter()
|
||||
, m_entry_in_progress( false )
|
||||
{
|
||||
m_log_formatter.reset(p_log_formatter);
|
||||
m_log_formatter->set_log_level(log_all_errors);
|
||||
}
|
||||
|
||||
// helper functions
|
||||
std::ostream& stream()
|
||||
{
|
||||
return *m_stream;
|
||||
}
|
||||
|
||||
log_level get_log_level() const
|
||||
{
|
||||
return m_log_formatter->get_log_level();
|
||||
}
|
||||
};
|
||||
|
||||
struct unit_test_log_impl {
|
||||
// Constructor
|
||||
unit_test_log_impl()
|
||||
{
|
||||
m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::compiler_log_formatter, OF_CLF, true) ); // only this one is active by default,
|
||||
m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::xml_log_formatter, OF_XML, false) );
|
||||
m_log_formatter_data.push_back( unit_test_log_data_helper_impl(new output::junit_log_formatter, OF_JUNIT, false) );
|
||||
}
|
||||
|
||||
typedef std::vector<unit_test_log_data_helper_impl> v_formatter_data_t;
|
||||
v_formatter_data_t m_log_formatter_data;
|
||||
|
||||
// entry data
|
||||
log_entry_data m_entry_data;
|
||||
|
||||
bool has_entry_in_progress() const {
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl const&, current_logger_data, m_log_formatter_data ) {
|
||||
if( current_logger_data.m_entry_in_progress )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// check point data
|
||||
log_checkpoint_data m_checkpoint_data;
|
||||
|
||||
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 )
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() == log_nothing )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->log_start( current_logger_data.stream(), test_cases_amount );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_build_info ) )
|
||||
current_logger_data.m_log_formatter->log_build_info( current_logger_data.stream() );
|
||||
|
||||
current_logger_data.m_entry_in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_finish()
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() == log_nothing )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->log_finish( current_logger_data.stream() );
|
||||
|
||||
current_logger_data.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().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
current_logger_data.m_log_formatter->test_unit_start( current_logger_data.stream(), tu );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_unit_finish( test_unit const& tu, unsigned long elapsed )
|
||||
{
|
||||
s_log_impl().m_checkpoint_data.clear();
|
||||
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->test_unit_finish( current_logger_data.stream(), tu, elapsed );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_unit_skipped( test_unit const& tu, const_string reason )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->test_unit_skipped( current_logger_data.stream(), tu, reason );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unit_test_log_t::test_unit_aborted( test_unit const& tu )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->test_unit_aborted(current_logger_data.stream(), tu );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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( s_log_impl().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
|
||||
if( current_logger_data.m_enabled && l >= current_logger_data.get_log_level() ) {
|
||||
|
||||
current_logger_data.m_log_formatter->log_exception_start( current_logger_data.stream(), s_log_impl().m_checkpoint_data, ex );
|
||||
|
||||
log_entry_context( l );
|
||||
|
||||
current_logger_data.m_log_formatter->log_exception_finish( current_logger_data.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().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.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().has_entry_in_progress() ) {
|
||||
log_entry_context( s_log_impl().m_entry_data.m_level );
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled && current_logger_data.m_entry_in_progress ) {
|
||||
current_logger_data.m_log_formatter->log_entry_finish( current_logger_data.stream() );
|
||||
}
|
||||
current_logger_data.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(output_format log_format)
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
|
||||
if( current_logger_data.m_format != log_format )
|
||||
continue;
|
||||
|
||||
if( current_logger_data.m_entry_in_progress )
|
||||
return true;
|
||||
|
||||
if( !current_logger_data.m_enabled )
|
||||
return false;
|
||||
|
||||
switch( s_log_impl().m_entry_data.m_level ) {
|
||||
case log_successful_tests:
|
||||
current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
|
||||
unit_test_log_formatter::BOOST_UTL_ET_INFO );
|
||||
break;
|
||||
case log_messages:
|
||||
current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
|
||||
unit_test_log_formatter::BOOST_UTL_ET_MESSAGE );
|
||||
break;
|
||||
case log_warnings:
|
||||
current_logger_data.m_log_formatter->log_entry_start( current_logger_data.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:
|
||||
current_logger_data.m_log_formatter->log_entry_start( current_logger_data.stream(), s_log_impl().m_entry_data,
|
||||
unit_test_log_formatter::BOOST_UTL_ET_ERROR );
|
||||
break;
|
||||
case log_fatal_errors:
|
||||
current_logger_data.m_log_formatter->log_entry_start( current_logger_data.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;
|
||||
}
|
||||
|
||||
current_logger_data.m_entry_in_progress = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
unit_test_log_t&
|
||||
unit_test_log_t::operator<<( const_string value )
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled && s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() && !value.empty() && log_entry_start(current_logger_data.m_format) )
|
||||
current_logger_data.m_log_formatter->log_entry_value( current_logger_data.stream(), value );
|
||||
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
unit_test_log_t&
|
||||
unit_test_log_t::operator<<( lazy_ostream const& value )
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled && s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() && !value.empty() ) {
|
||||
if( log_entry_start(current_logger_data.m_format) ) {
|
||||
current_logger_data.m_log_formatter->log_entry_value( current_logger_data.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;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->entry_context_start( current_logger_data.stream(), l );
|
||||
}
|
||||
}
|
||||
|
||||
while( !(frame=context.next()).is_empty() )
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), frame );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.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().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
current_logger_data.m_stream = &str;
|
||||
current_logger_data.m_stream_state_saver.reset( new io_saver_type( str ) );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::set_stream( output_format log_format, std::ostream& str )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
current_logger_data.m_stream = &str;
|
||||
current_logger_data.m_stream_state_saver.reset( new io_saver_type( str ) );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::set_threshold_level( log_level lev )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
|
||||
return;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
current_logger_data.m_log_formatter->set_log_level( lev );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::set_threshold_level( output_format log_format, log_level lev )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
|
||||
return;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
current_logger_data.m_log_formatter->set_log_level( lev );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::set_format( output_format log_format )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
current_logger_data.m_enabled = current_logger_data.m_format == log_format;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::add_format( output_format log_format )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
current_logger_data.m_enabled = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
unit_test_log_formatter*
|
||||
unit_test_log_t::get_formatter( output_format log_format ) {
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
return current_logger_data.m_log_formatter.get();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
unit_test_log_t::add_formatter( unit_test_log_formatter* the_formatter )
|
||||
{
|
||||
// remove only user defined logger
|
||||
for(unit_test_log_impl::v_formatter_data_t::iterator it(s_log_impl().m_log_formatter_data.begin()),
|
||||
ite(s_log_impl().m_log_formatter_data.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
if( it->m_format == OF_CUSTOM_LOGGER) {
|
||||
s_log_impl().m_log_formatter_data.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( the_formatter ) {
|
||||
s_log_impl().m_log_formatter_data.push_back( unit_test_log_data_helper_impl(the_formatter, OF_CUSTOM_LOGGER, true) );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
unit_test_log_t::set_formatter( unit_test_log_formatter* the_formatter )
|
||||
{
|
||||
// remove only user defined logger
|
||||
log_level current_level = invalid_log_level;
|
||||
std::ostream *current_stream = 0;
|
||||
output_format previous_format = OF_INVALID;
|
||||
for(unit_test_log_impl::v_formatter_data_t::iterator it(s_log_impl().m_log_formatter_data.begin()),
|
||||
ite(s_log_impl().m_log_formatter_data.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
if( it->m_enabled ) {
|
||||
if( current_level == invalid_log_level || it->m_format < previous_format || it->m_format == OF_CUSTOM_LOGGER) {
|
||||
current_level = it->get_log_level();
|
||||
current_stream = &(it->stream());
|
||||
previous_format = it->m_format;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( the_formatter ) {
|
||||
add_formatter(the_formatter);
|
||||
set_format(OF_CUSTOM_LOGGER);
|
||||
set_threshold_level(OF_CUSTOM_LOGGER, current_level);
|
||||
set_stream(OF_CUSTOM_LOGGER, *current_stream);
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** 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() );
|
||||
}
|
||||
|
||||
void
|
||||
unit_test_log_formatter::set_log_level(log_level new_log_level)
|
||||
{
|
||||
m_log_level = new_log_level;
|
||||
}
|
||||
|
||||
log_level
|
||||
unit_test_log_formatter::get_log_level() const
|
||||
{
|
||||
return m_log_level;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_UNIT_TEST_LOG_IPP_012205GER
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
// (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::btrt_wait_for_debugger ) ) {
|
||||
results_reporter::get_stream() << "Press any key to continue..." << std::endl;
|
||||
|
||||
// getchar is defined as a macro in uClibc. Use parenthesis to fix
|
||||
// gcc bug 58952 for gcc <= 4.8.2.
|
||||
(std::getchar)();
|
||||
results_reporter::get_stream() << "Continuing..." << std::endl;
|
||||
}
|
||||
|
||||
framework::finalize_setup_phase();
|
||||
|
||||
output_format list_cont = runtime_config::get<output_format>( runtime_config::btrt_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::btrt_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::btrt_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
|
||||
@@ -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::btrt_catch_sys_errors );
|
||||
p_timeout.value = timeout;
|
||||
p_auto_start_dbg.value = runtime_config::get<bool>( runtime_config::btrt_auto_start_dbg );
|
||||
p_use_alt_stack.value = runtime_config::get<bool>( runtime_config::btrt_use_alt_stack );
|
||||
p_detect_fp_exceptions.value = runtime_config::get<bool>( runtime_config::btrt_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
|
||||
@@ -0,0 +1,761 @@
|
||||
// (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/utils/iterator/token_iterator.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 btrt_auto_start_dbg = "auto_start_dbg";
|
||||
std::string btrt_break_exec_path = "break_exec_path";
|
||||
std::string btrt_build_info = "build_info";
|
||||
std::string btrt_catch_sys_errors = "catch_system_errors";
|
||||
std::string btrt_color_output = "color_output";
|
||||
std::string btrt_detect_fp_except = "detect_fp_exceptions";
|
||||
std::string btrt_detect_mem_leaks = "detect_memory_leaks";
|
||||
std::string btrt_list_content = "list_content";
|
||||
std::string btrt_list_labels = "list_labels";
|
||||
std::string btrt_log_format = "log_format";
|
||||
std::string btrt_log_level = "log_level";
|
||||
std::string btrt_log_sink = "log_sink";
|
||||
std::string btrt_combined_logger = "logger";
|
||||
std::string btrt_output_format = "output_format";
|
||||
std::string btrt_random_seed = "random";
|
||||
std::string btrt_report_format = "report_format";
|
||||
std::string btrt_report_level = "report_level";
|
||||
std::string btrt_report_mem_leaks = "report_memory_leaks_to";
|
||||
std::string btrt_report_sink = "report_sink";
|
||||
std::string btrt_result_code = "result_code";
|
||||
std::string btrt_run_filters = "run_test";
|
||||
std::string btrt_save_test_pattern = "save_pattern";
|
||||
std::string btrt_show_progress = "show_progress";
|
||||
std::string btrt_use_alt_stack = "use_alt_stack";
|
||||
std::string btrt_wait_for_debugger = "wait_for_debugger";
|
||||
|
||||
std::string btrt_help = "help";
|
||||
std::string btrt_usage = "usage";
|
||||
std::string btrt_version = "version";
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace {
|
||||
|
||||
void
|
||||
register_parameters( rt::parameters_store& store )
|
||||
{
|
||||
rt::option auto_start_dbg( btrt_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 " + btrt_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( "--", btrt_auto_start_dbg, "=" );
|
||||
auto_start_dbg.add_cla_id( "-", "d", " " );
|
||||
store.add( auto_start_dbg );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> break_exec_path( btrt_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( "--", btrt_break_exec_path, "=" );
|
||||
store.add( break_exec_path );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option build_info( btrt_build_info, (
|
||||
rt::description = "Displays library build information.",
|
||||
rt::env_var = "BOOST_TEST_BUILD_INFO",
|
||||
rt::help = "Option " + btrt_build_info + " displays library build information, including: platform, "
|
||||
"compiler, STL version and Boost version."
|
||||
));
|
||||
|
||||
build_info.add_cla_id( "--", btrt_build_info, "=" );
|
||||
build_info.add_cla_id( "-", "i", " " );
|
||||
store.add( build_info );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option catch_sys_errors( btrt_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 " + btrt_catch_sys_errors + " has value no the frameworks does not attempt to catch "
|
||||
"asynchronous system failure events (signals on *NIX platforms or structured exceptions on Windows). "
|
||||
" Default value is "
|
||||
#ifdef BOOST_TEST_DEFAULTS_TO_CORE_DUMP
|
||||
"no."
|
||||
#else
|
||||
"true."
|
||||
#endif
|
||||
));
|
||||
|
||||
catch_sys_errors.add_cla_id( "--", btrt_catch_sys_errors, "=", true );
|
||||
catch_sys_errors.add_cla_id( "-", "s", " " );
|
||||
store.add( catch_sys_errors );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option color_output( btrt_color_output, (
|
||||
rt::description = "Enables color output of the framework log and report messages.",
|
||||
rt::env_var = "BOOST_TEST_COLOR_OUTPUT",
|
||||
rt::help = "The framework is able to produce color output on systems which supports it. "
|
||||
"To enable this behavior set this option to yes. By default the framework "
|
||||
"does not produces color output."
|
||||
));
|
||||
|
||||
color_output.add_cla_id( "--", btrt_color_output, "=", true );
|
||||
color_output.add_cla_id( "-", "x", " " );
|
||||
store.add( color_output );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option detect_fp_except( btrt_detect_fp_except, (
|
||||
rt::description = "Enables/disables floating point exceptions traps.",
|
||||
rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS",
|
||||
rt::help = "Option " + btrt_detect_fp_except + " enables/disables hardware traps for the floating "
|
||||
"point exceptions (if supported on your platfrom)."
|
||||
));
|
||||
|
||||
detect_fp_except.add_cla_id( "--", btrt_detect_fp_except, "=", true );
|
||||
store.add( detect_fp_except );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<unsigned long> detect_mem_leaks( btrt_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 " + btrt_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( "--", btrt_detect_mem_leaks, "=" );
|
||||
store.add( detect_mem_leaks );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::output_format> list_content( btrt_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_TEST_CLA_NEW_API)
|
||||
{
|
||||
{ "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 " + btrt_list_content + " instructs the framework to list the content "
|
||||
"of the test module instead of executing the test cases. Parameter accepts "
|
||||
"optional string value indicating the format of the output. Currently the "
|
||||
"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( "--", btrt_list_content, "=" );
|
||||
store.add( list_content );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option list_labels( btrt_list_labels, (
|
||||
rt::description = "Lists all available labels.",
|
||||
rt::env_var = "BOOST_TEST_LIST_LABELS",
|
||||
rt::help = "Option " + btrt_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( "--", btrt_list_labels, "=" );
|
||||
store.add( list_labels );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::output_format> log_format( btrt_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_TEST_CLA_NEW_API)
|
||||
{
|
||||
{ "HRF", OF_CLF },
|
||||
{ "CLF", OF_CLF },
|
||||
{ "XML", OF_XML },
|
||||
{ "JUNIT", OF_JUNIT },
|
||||
},
|
||||
#else
|
||||
rt::enum_values_list<unit_test::output_format>()
|
||||
( "HRF", OF_CLF )
|
||||
( "CLF", OF_CLF )
|
||||
( "XML", OF_XML )
|
||||
( "JUNIT", OF_JUNIT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_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 "
|
||||
"or JUNIT as log format, which are easier to process by testing automation tools."
|
||||
));
|
||||
|
||||
log_format.add_cla_id( "--", btrt_log_format, "=" );
|
||||
log_format.add_cla_id( "-", "f", " " );
|
||||
store.add( log_format );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::log_level> log_level( btrt_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_TEST_CLA_NEW_API)
|
||||
{
|
||||
{ "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 " + btrt_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( "--", btrt_log_level, "=" );
|
||||
log_level.add_cla_id( "-", "l", " " );
|
||||
store.add( log_level );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> log_sink( btrt_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 " + btrt_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( "--", btrt_log_sink, "=" );
|
||||
log_sink.add_cla_id( "-", "k", " " );
|
||||
store.add( log_sink );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::output_format> output_format( btrt_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_TEST_CLA_NEW_API)
|
||||
{
|
||||
{ "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 " + btrt_output_format + " combines an effect of " + btrt_report_format +
|
||||
" and " + btrt_log_format + " parameters. This parameter has higher priority "
|
||||
"than either one of them. In other words if this parameter is specified "
|
||||
"it overrides the value of other two parameters. This parameter does not "
|
||||
"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( "--", btrt_output_format, "=" );
|
||||
output_format.add_cla_id( "-", "o", " " );
|
||||
store.add( output_format );
|
||||
|
||||
/////////////////////////////////////////////// combined logger option
|
||||
|
||||
rt::parameter<std::string,rt::REPEATABLE_PARAM> combined_logger( btrt_combined_logger, (
|
||||
rt::description = "Specifies log level and sink for one or several log format",
|
||||
rt::env_var = "BOOST_TEST_LOGGER",
|
||||
rt::value_hint = "log_format:log_level:log_sink",
|
||||
rt::help = "Parameter " + btrt_combined_logger + " allows to specify the logger type, level and sink\n"
|
||||
"in one command."
|
||||
));
|
||||
|
||||
combined_logger.add_cla_id( "--", btrt_combined_logger, "=" );
|
||||
store.add( combined_logger );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<unsigned> random_seed( btrt_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 " + btrt_random_seed + " instructs the framework to execute the "
|
||||
"test cases in random order. This parameter accepts optional unsigned "
|
||||
"integer argument. By default test cases are executed in some specific "
|
||||
"order defined by order of test units in test files and dependency between "
|
||||
"test units. If parameter is specified without the argument value testing "
|
||||
"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( "--", btrt_random_seed, "=" );
|
||||
store.add( random_seed );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::output_format> report_format( btrt_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_TEST_CLA_NEW_API)
|
||||
{
|
||||
{ "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 " + btrt_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( "--", btrt_report_format, "=" );
|
||||
report_format.add_cla_id( "-", "m", " " );
|
||||
store.add( report_format );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::report_level> report_level( btrt_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_TEST_CLA_NEW_API)
|
||||
{
|
||||
{ "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 " + btrt_report_level + " allows to set the verbosity level of the "
|
||||
"testing result report generated by the framework. Use value 'no' to "
|
||||
"eliminate the results report completely."
|
||||
));
|
||||
|
||||
report_level.add_cla_id( "--", btrt_report_level, "=" );
|
||||
report_level.add_cla_id( "-", "r", " " );
|
||||
store.add( report_level );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> report_mem_leaks( btrt_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 " + btrt_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( "--", btrt_report_mem_leaks, "=" );
|
||||
store.add( report_mem_leaks );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> report_sink( btrt_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 " + btrt_report_sink + " allows to set the result report sink - "
|
||||
"the location where the framework writes the result report to, thus it "
|
||||
"allows to easily redirect the result report to a file or a standard "
|
||||
"stream. By default the testing result report is directed to the "
|
||||
"standard error stream."
|
||||
));
|
||||
|
||||
report_sink.add_cla_id( "--", btrt_report_sink, "=" );
|
||||
report_sink.add_cla_id( "-", "e", " " );
|
||||
store.add( report_sink );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option result_code( btrt_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 " + btrt_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( "--", btrt_result_code, "=", true );
|
||||
result_code.add_cla_id( "-", "c", " " );
|
||||
store.add( result_code );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( btrt_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 " + btrt_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 " + btrt_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( "--", btrt_run_filters, "=" );
|
||||
tests_to_run.add_cla_id( "-", "t", " " );
|
||||
store.add( tests_to_run );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option save_test_pattern( btrt_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 " + btrt_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( "--", btrt_save_test_pattern, "=" );
|
||||
store.add( save_test_pattern );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option show_progress( btrt_show_progress, (
|
||||
rt::description = "Turns on progress display.",
|
||||
rt::env_var = "BOOST_TEST_SHOW_PROGRESS",
|
||||
rt::help = "Parameter " + btrt_show_progress + " instructs the framework to display test progress "
|
||||
"information. By default the test progress is not shown."
|
||||
));
|
||||
|
||||
show_progress.add_cla_id( "--", btrt_show_progress, "=" );
|
||||
show_progress.add_cla_id( "-", "p", " " );
|
||||
store.add( show_progress );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option use_alt_stack( btrt_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 " + btrt_use_alt_stack + " instructs the framework to use alternative "
|
||||
"stack for signals processing, on platforms where they are supported. The feature "
|
||||
"is enabled by default, but can be disabled using this parameter."
|
||||
));
|
||||
|
||||
use_alt_stack.add_cla_id( "--", btrt_use_alt_stack, "=", true );
|
||||
store.add( use_alt_stack );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option wait_for_debugger( btrt_wait_for_debugger, (
|
||||
rt::description = "Forces test module to wait for button to be pressed before starting test run.",
|
||||
rt::env_var = "BOOST_TEST_WAIT_FOR_DEBUGGER",
|
||||
rt::help = "Parameter " + btrt_wait_for_debugger + " instructs the framework to pause before starting "
|
||||
"test units execution, so that you can attach a debugger to running test module. By "
|
||||
"default this parameters turned off."
|
||||
));
|
||||
|
||||
wait_for_debugger.add_cla_id( "--", btrt_wait_for_debugger, "=" );
|
||||
wait_for_debugger.add_cla_id( "-", "w", " " );
|
||||
store.add( wait_for_debugger );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> help( btrt_help, (
|
||||
rt::description = "Help for framework parameters.",
|
||||
rt::optional_value = std::string(),
|
||||
rt::value_hint = "<parameter name>",
|
||||
rt::help = "Parameter " + btrt_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( "--", btrt_help, "=" );
|
||||
store.add( help );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option usage( btrt_usage, (
|
||||
rt::description = "Short message explaining usage of Boost.Test parameters."
|
||||
));
|
||||
usage.add_cla_id( "-", "?", " " );
|
||||
store.add( usage );
|
||||
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::option version( btrt_version, (
|
||||
rt::description = "Prints Boost.Test version and exits."
|
||||
));
|
||||
version.add_cla_id( "--", btrt_version, " " );
|
||||
store.add( version );
|
||||
}
|
||||
|
||||
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>( btrt_version ) ) {
|
||||
parser->version( std::cerr );
|
||||
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
|
||||
}
|
||||
else if( runtime_config::get<bool>( btrt_usage ) ) {
|
||||
parser->usage( std::cerr );
|
||||
BOOST_TEST_I_THROW( framework::nothing_to_test( boost::exit_success ) );
|
||||
}
|
||||
else if( s_arguments_store.has( btrt_help ) ) {
|
||||
parser->help( std::cerr, s_parameters_store, runtime_config::get<std::string>( btrt_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( btrt_output_format ) ) {
|
||||
unit_test::output_format of = s_arguments_store.get<unit_test::output_format>( btrt_output_format );
|
||||
s_arguments_store.set( btrt_report_format, of );
|
||||
s_arguments_store.set( btrt_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>( btrt_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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,21 @@
|
||||
// (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 : included variant of Execution Monitor to be used independently
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_INCLUDED_EXECUTION_MONITOR_HPP_051410GER
|
||||
#define BOOST_INCLUDED_EXECUTION_MONITOR_HPP_051410GER
|
||||
|
||||
#include <boost/test/impl/execution_monitor.ipp>
|
||||
#include <boost/test/impl/debug.ipp>
|
||||
|
||||
#endif // BOOST_INCLUDED_EXECUTION_MONITOR_HPP_051410GER
|
||||
@@ -0,0 +1,25 @@
|
||||
// (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 : included (vs. linked ) version of Program Execution Monitor
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_INCLUDED_PRG_EXEC_MONITOR_HPP_071894GER
|
||||
#define BOOST_INCLUDED_PRG_EXEC_MONITOR_HPP_071894GER
|
||||
|
||||
#include <boost/test/impl/execution_monitor.ipp>
|
||||
#include <boost/test/impl/debug.ipp>
|
||||
#include <boost/test/impl/cpp_main.ipp>
|
||||
|
||||
#define BOOST_TEST_INCLUDED
|
||||
#include <boost/test/prg_exec_monitor.hpp>
|
||||
|
||||
#endif // BOOST_INCLUDED_PRG_EXEC_MONITOR_HPP_071894GER
|
||||
@@ -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
|
||||
/// @brief Included (vs. linked) version of Test Execution Monitor
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER
|
||||
#define BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER
|
||||
|
||||
#include <boost/test/impl/compiler_log_formatter.ipp>
|
||||
#include <boost/test/impl/junit_log_formatter.ipp>
|
||||
#include <boost/test/impl/debug.ipp>
|
||||
#include <boost/test/impl/decorator.ipp>
|
||||
#include <boost/test/impl/execution_monitor.ipp>
|
||||
#include <boost/test/impl/framework.ipp>
|
||||
#include <boost/test/impl/plain_report_formatter.ipp>
|
||||
#include <boost/test/impl/progress_monitor.ipp>
|
||||
#include <boost/test/impl/results_collector.ipp>
|
||||
#include <boost/test/impl/results_reporter.ipp>
|
||||
#include <boost/test/impl/test_main.ipp>
|
||||
#include <boost/test/impl/test_tools.ipp>
|
||||
#include <boost/test/impl/test_tree.ipp>
|
||||
#include <boost/test/impl/unit_test_log.ipp>
|
||||
#include <boost/test/impl/unit_test_main.ipp>
|
||||
#include <boost/test/impl/unit_test_monitor.ipp>
|
||||
#include <boost/test/impl/unit_test_parameters.ipp>
|
||||
#include <boost/test/impl/xml_log_formatter.ipp>
|
||||
#include <boost/test/impl/xml_report_formatter.ipp>
|
||||
|
||||
#define BOOST_TEST_INCLUDED
|
||||
#include <boost/test/test_exec_monitor.hpp>
|
||||
|
||||
#endif // BOOST_INCLUDED_TEST_EXEC_MONITOR_HPP_071894GER
|
||||
@@ -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
|
||||
//!@brief Included (vs. linked) version of Unit Test Framework
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
|
||||
#define BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
|
||||
|
||||
#define BOOST_TEST_INCLUDED
|
||||
|
||||
#include <boost/test/impl/compiler_log_formatter.ipp>
|
||||
#include <boost/test/impl/junit_log_formatter.ipp>
|
||||
#include <boost/test/impl/debug.ipp>
|
||||
#include <boost/test/impl/decorator.ipp>
|
||||
#include <boost/test/impl/framework.ipp>
|
||||
#include <boost/test/impl/execution_monitor.ipp>
|
||||
#include <boost/test/impl/plain_report_formatter.ipp>
|
||||
#include <boost/test/impl/progress_monitor.ipp>
|
||||
#include <boost/test/impl/results_collector.ipp>
|
||||
#include <boost/test/impl/results_reporter.ipp>
|
||||
#include <boost/test/impl/test_tools.ipp>
|
||||
#include <boost/test/impl/test_tree.ipp>
|
||||
#include <boost/test/impl/unit_test_log.ipp>
|
||||
#include <boost/test/impl/unit_test_main.ipp>
|
||||
#include <boost/test/impl/unit_test_monitor.ipp>
|
||||
#include <boost/test/impl/unit_test_parameters.ipp>
|
||||
#include <boost/test/impl/xml_log_formatter.ipp>
|
||||
#include <boost/test/impl/junit_log_formatter.ipp>
|
||||
#include <boost/test/impl/xml_report_formatter.ipp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#endif // BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
|
||||
@@ -0,0 +1,12 @@
|
||||
// (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
|
||||
/// @deprecated
|
||||
// ***************************************************************************
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
@@ -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
|
||||
@@ -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 Contains the formatter for the Human Readable Format (HRF)
|
||||
// ***************************************************************************
|
||||
|
||||
#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 ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//!@brief Log formatter for the Human Readable Format (HRF) log format
|
||||
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
|
||||
@@ -0,0 +1,167 @@
|
||||
// (C) Copyright 2016 Raffi Enficiaud.
|
||||
// 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 the definition of the Junit log formatter (OF_JUNIT)
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_JUNIT_LOG_FORMATTER__
|
||||
#define BOOST_TEST_JUNIT_LOG_FORMATTER__
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
#include <boost/test/unit_test_log_formatter.hpp>
|
||||
#include <boost/test/tree/test_unit.hpp>
|
||||
|
||||
//#include <boost/test/results_collector.hpp>
|
||||
|
||||
// STL
|
||||
#include <cstddef> // std::size_t
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace output {
|
||||
|
||||
|
||||
namespace junit_impl {
|
||||
|
||||
// helper for the JUnit logger
|
||||
struct junit_log_helper
|
||||
{
|
||||
struct assertion_entry {
|
||||
|
||||
enum log_entry_t {
|
||||
log_entry_info,
|
||||
log_entry_error,
|
||||
log_entry_failure
|
||||
};
|
||||
|
||||
assertion_entry() : sealed(false)
|
||||
{}
|
||||
|
||||
std::string logentry_message; // the message associated to the JUnit error/entry
|
||||
std::string logentry_type; // the one that will get expanded in the final junit (failure, error)
|
||||
std::string output; // additional information/message generated by the assertion
|
||||
|
||||
log_entry_t log_entry; // the type associated to the assertion (or error)
|
||||
|
||||
bool sealed; // indicates if the entry can accept additional information
|
||||
};
|
||||
|
||||
std::list<std::string> system_out; // sysout: additional information
|
||||
std::list<std::string> system_err; // syserr: additional information
|
||||
std::string skipping_reason;
|
||||
|
||||
// list of failure, errors and messages (assertions message and the full log)
|
||||
std::vector< assertion_entry > assertion_entries;
|
||||
|
||||
bool skipping;
|
||||
|
||||
junit_log_helper(): skipping(false)
|
||||
{}
|
||||
|
||||
void clear() {
|
||||
assertion_entries.clear();
|
||||
system_out.clear();
|
||||
system_err.clear();
|
||||
skipping_reason.clear();
|
||||
skipping = false;
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** junit_log_formatter ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// JUnit logger class
|
||||
class junit_log_formatter : public unit_test_log_formatter {
|
||||
public:
|
||||
|
||||
junit_log_formatter() : m_display_build_info(false)
|
||||
{
|
||||
// we log everything from the logger singleton point of view
|
||||
// because we need to know about all the messages/commands going to the logger
|
||||
// we decide what we put inside the logs internally
|
||||
this->m_log_level = log_successful_tests;
|
||||
m_log_level_internal = log_messages;
|
||||
}
|
||||
|
||||
// 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 test_unit_aborted( std::ostream& os, test_unit const& tu );
|
||||
|
||||
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& );
|
||||
|
||||
//! Discards changes in the log level
|
||||
virtual void set_log_level(log_level ll)
|
||||
{
|
||||
if(ll > log_successful_tests && ll < log_messages)
|
||||
ll = log_successful_tests;
|
||||
else if (ll > log_all_errors)
|
||||
ll = log_all_errors;
|
||||
|
||||
this->m_log_level_internal = ll;
|
||||
}
|
||||
|
||||
//! Instead of a regular stream, returns a file name corresponding to
|
||||
//! the current master test suite. If the file already exists, adds an index
|
||||
//! to it.
|
||||
virtual std::string get_default_stream_description() const;
|
||||
|
||||
|
||||
private:
|
||||
typedef std::map<test_unit_id, junit_impl::junit_log_helper> map_trace_t;
|
||||
map_trace_t map_tests;
|
||||
junit_impl::junit_log_helper runner_log_entry;
|
||||
|
||||
junit_impl::junit_log_helper& get_current_log_entry() {
|
||||
if(list_path_to_root.empty())
|
||||
return runner_log_entry;
|
||||
map_trace_t::iterator it = map_tests.find(list_path_to_root.back());
|
||||
return (it == map_tests.end() ? runner_log_entry : it->second);
|
||||
}
|
||||
|
||||
std::list<test_unit_id> list_path_to_root;
|
||||
bool m_display_build_info;
|
||||
bool m_is_last_assertion_or_error; // true if failure, false if error
|
||||
|
||||
log_level m_log_level_internal;
|
||||
friend class junit_result_helper;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_JUNIT_LOG_FORMATTER__
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,14 @@
|
||||
// (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 header.
|
||||
//!@deprecated Use boost/test/tools/output_test_stream.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/output_test_stream.hpp>
|
||||
@@ -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 generators and helper macros for parameterized tests
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
|
||||
#define BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/unit_test_suite.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function/function1.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#define BOOST_PARAM_TEST_CASE( function, begin, end ) \
|
||||
boost::unit_test::make_test_case( function, \
|
||||
BOOST_TEST_STRINGIZE( function ), \
|
||||
__FILE__, __LINE__, \
|
||||
(begin), (end) ) \
|
||||
/**/
|
||||
|
||||
#define BOOST_PARAM_CLASS_TEST_CASE( function, tc_instance, begin, end ) \
|
||||
boost::unit_test::make_test_case( function, \
|
||||
BOOST_TEST_STRINGIZE( function ), \
|
||||
__FILE__, __LINE__, \
|
||||
(tc_instance), \
|
||||
(begin), (end) ) \
|
||||
/**/
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
namespace ut_detail {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** param_test_case_generator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename ParamType, typename ParamIter>
|
||||
class param_test_case_generator : public test_unit_generator {
|
||||
public:
|
||||
param_test_case_generator( boost::function<void (ParamType)> const& test_func,
|
||||
const_string tc_name,
|
||||
const_string tc_file,
|
||||
std::size_t tc_line,
|
||||
ParamIter par_begin,
|
||||
ParamIter par_end )
|
||||
: m_test_func( test_func )
|
||||
, m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
|
||||
, m_tc_file( tc_file )
|
||||
, m_tc_line( tc_line )
|
||||
, m_par_begin( par_begin )
|
||||
, m_par_end( par_end )
|
||||
{}
|
||||
|
||||
virtual test_unit* next() const
|
||||
{
|
||||
if( m_par_begin == m_par_end )
|
||||
return (test_unit*)0;
|
||||
|
||||
test_unit* res = new test_case( m_tc_name, m_tc_file, m_tc_line, boost::bind( m_test_func, *m_par_begin ) );
|
||||
|
||||
++m_par_begin;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
boost::function<void (ParamType)> m_test_func;
|
||||
std::string m_tc_name;
|
||||
const_string m_tc_file;
|
||||
std::size_t m_tc_line;
|
||||
mutable ParamIter m_par_begin;
|
||||
ParamIter m_par_end;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename UserTestCase,typename ParamType>
|
||||
struct user_param_tc_method_invoker {
|
||||
typedef void (UserTestCase::*test_method)( ParamType );
|
||||
|
||||
// Constructor
|
||||
user_param_tc_method_invoker( shared_ptr<UserTestCase> inst, test_method test_method )
|
||||
: m_inst( inst ), m_test_method( test_method ) {}
|
||||
|
||||
void operator()( ParamType p ) { ((*m_inst).*m_test_method)( p ); }
|
||||
|
||||
// Data members
|
||||
shared_ptr<UserTestCase> m_inst;
|
||||
test_method m_test_method;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace ut_detail
|
||||
|
||||
template<typename ParamType, typename ParamIter>
|
||||
inline ut_detail::param_test_case_generator<ParamType,ParamIter>
|
||||
make_test_case( boost::function<void (ParamType)> const& test_func,
|
||||
const_string tc_name,
|
||||
const_string tc_file,
|
||||
std::size_t tc_line,
|
||||
ParamIter par_begin,
|
||||
ParamIter par_end )
|
||||
{
|
||||
return ut_detail::param_test_case_generator<ParamType,ParamIter>( test_func, tc_name, tc_file, tc_line, par_begin, par_end );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename ParamType, typename ParamIter>
|
||||
inline ut_detail::param_test_case_generator<
|
||||
BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type,ParamIter>
|
||||
make_test_case( void (*test_func)( ParamType ),
|
||||
const_string tc_name,
|
||||
const_string tc_file,
|
||||
std::size_t tc_line,
|
||||
ParamIter par_begin,
|
||||
ParamIter par_end )
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type param_value_type;
|
||||
return ut_detail::param_test_case_generator<param_value_type,ParamIter>( test_func, tc_name, tc_file, tc_line, par_begin, par_end );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename UserTestCase,typename ParamType, typename ParamIter>
|
||||
inline ut_detail::param_test_case_generator<
|
||||
BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type,ParamIter>
|
||||
make_test_case( void (UserTestCase::*test_method )( ParamType ),
|
||||
const_string tc_name,
|
||||
const_string tc_file,
|
||||
std::size_t tc_line,
|
||||
boost::shared_ptr<UserTestCase> const& user_test_case,
|
||||
ParamIter par_begin,
|
||||
ParamIter par_end )
|
||||
{
|
||||
typedef BOOST_DEDUCED_TYPENAME remove_const<BOOST_DEDUCED_TYPENAME remove_reference<ParamType>::type>::type param_value_type;
|
||||
return ut_detail::param_test_case_generator<param_value_type,ParamIter>(
|
||||
ut_detail::user_param_tc_method_invoker<UserTestCase,ParamType>( user_test_case, test_method ),
|
||||
tc_name,
|
||||
tc_file,
|
||||
tc_line,
|
||||
par_begin,
|
||||
par_end );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_PARAMETERIZED_TEST_HPP_021102GER
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
// (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 header
|
||||
/// @deprecated Use boost/test/tools/assertion_result.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/assertion_result.hpp>
|
||||
@@ -0,0 +1,81 @@
|
||||
// (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 for the end user into the Program Execution Monitor.
|
||||
///
|
||||
/// Use this header to forward declare function prg_exec_monitor_main and to automatically define a main
|
||||
/// function for you. If you prefer to use your own main you are free to do so, but you need to define
|
||||
/// BOOST_TEST_NO_MAIN before incuding this header. To initiate your main program body execution you
|
||||
/// would use statement like this:
|
||||
/// @code ::boost::prg_exec_monitor_main( &my_main, argc, argv ); @endcode
|
||||
/// Also this header facilitate auto linking with the Program Execution Monitor library if this feature
|
||||
/// is supported
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_PRG_EXEC_MONITOR_HPP_071894GER
|
||||
#define BOOST_PRG_EXEC_MONITOR_HPP_071894GER
|
||||
|
||||
#include <boost/test/detail/config.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** Auto Linking ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
// Automatically link to the correct build variant where possible.
|
||||
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
|
||||
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
|
||||
# define BOOST_LIB_NAME boost_prg_exec_monitor
|
||||
|
||||
// If we're importing code from a dll, then tell auto_link.hpp about it:
|
||||
# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_TEST_DYN_LINK)
|
||||
# define BOOST_DYN_LINK
|
||||
# endif
|
||||
|
||||
# include <boost/config/auto_link.hpp>
|
||||
|
||||
#endif // auto-linking disabled
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** prg_exec_monitor_main ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace boost {
|
||||
|
||||
/// @brief Wrapper around the main function
|
||||
///
|
||||
/// Call this routine instead of your own main body implementation directly. This routine impements all the monitoring
|
||||
/// functionality. THe monitor behavior is configurable by using the environment variable BOOST_TEST_CATCH_SYSTEM_ERRORS.
|
||||
/// If set to string value "no", the monitor will not attempt to catch system errors (signals)
|
||||
/// @param[in] cpp_main main function body. Should have the same signature as regular main function
|
||||
/// @param[in] argc, argv command line arguments
|
||||
int BOOST_TEST_DECL prg_exec_monitor_main( int (*cpp_main)( int argc, char* argv[] ), int argc, char* argv[] );
|
||||
|
||||
} // boost
|
||||
|
||||
#if defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** main function for tests using dll ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
// prototype for user's cpp_main()
|
||||
int cpp_main( int argc, char* argv[] );
|
||||
|
||||
int BOOST_TEST_CALL_DECL
|
||||
main( int argc, char* argv[] )
|
||||
{
|
||||
return ::boost::prg_exec_monitor_main( &cpp_main, argc, argv );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#endif // BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
|
||||
|
||||
#endif // BOOST_PRG_EXEC_MONITOR_HPP_071894GER
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
// (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 collector components
|
||||
///
|
||||
/// Defines classes for keeping track (@ref test_results) and collecting
|
||||
/// (@ref results_collector_t) the states of the test units.
|
||||
// ***************************************************************************
|
||||
|
||||
#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 a test result.
|
||||
///
|
||||
/// The attributes 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;
|
||||
|
||||
counter_prop p_assertions_passed; //!< Number of successful assertions
|
||||
counter_prop p_assertions_failed; //!< Number of failing assertions
|
||||
counter_prop p_warnings_failed; //!< Number of warnings
|
||||
counter_prop p_expected_failures;
|
||||
counter_prop p_test_cases_passed; //!< Number of successfull test cases
|
||||
counter_prop p_test_cases_warned; //!< Number of warnings in test cases
|
||||
counter_prop p_test_cases_failed; //!< Number of failing test cases
|
||||
counter_prop p_test_cases_skipped; //!< Number of skipped test cases
|
||||
counter_prop p_test_cases_aborted; //!< Number of aborted test cases
|
||||
counter_prop p_duration_microseconds; //!< Duration of the test in microseconds
|
||||
bool_prop p_aborted; //!< Indicates that the test unit execution has been aborted
|
||||
bool_prop p_skipped; //!< Indicates that the test unit execution has been skipped
|
||||
|
||||
/// 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 @c boost/cstdlib.hpp
|
||||
/// @returns
|
||||
/// - @c boost::exit_success on success,
|
||||
/// - @c boost::exit_exception_failure in case test unit
|
||||
/// was aborted for any reason (incuding uncaught exception)
|
||||
/// - and @c boost::exit_test_failure otherwise
|
||||
int result_code() const;
|
||||
|
||||
//! Combines the results of the current instance with another
|
||||
//!
|
||||
//! Only the counters are updated and the @c p_aborted and @c p_skipped are left unchanged.
|
||||
void operator+=( test_results const& );
|
||||
|
||||
//! Resets the current state of the result
|
||||
void clear();
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
/// @brief Collects and combines the test results
|
||||
///
|
||||
/// This class collects and combines the results of the test unit during the execution of the
|
||||
/// test tree. The results_collector_t::results() function combines the test results on a subtree
|
||||
/// of the test tree.
|
||||
///
|
||||
/// @see boost::unit_test::test_observer
|
||||
class BOOST_TEST_DECL results_collector_t : public test_observer, public singleton<results_collector_t> {
|
||||
public:
|
||||
|
||||
virtual void test_start( counter_t );
|
||||
|
||||
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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
// (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 header.
|
||||
/// @deprecated Use @c boost/test/unit_test.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
@@ -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
|
||||
/// @brief Deprecated implementation of Test Execution Monitor
|
||||
///
|
||||
/// To convert to Unit Test Framework simply rewrite:
|
||||
/// @code
|
||||
/// #include <boost/test/test_exec_monitor.hpp>
|
||||
///
|
||||
/// int test_main( int, char *[] )
|
||||
/// {
|
||||
/// ...
|
||||
/// }
|
||||
/// @endcode
|
||||
/// as
|
||||
/// @code
|
||||
/// #include <boost/test/unit_test.hpp>
|
||||
///
|
||||
/// BOOST_AUTO_TEST_CASE(test_main)
|
||||
/// {
|
||||
/// ...
|
||||
/// }
|
||||
/// @endcode
|
||||
/// and link with boost_unit_test_framework library *instead of* boost_test_exec_monitor
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_EXEC_MONITOR_HPP_071894GER
|
||||
#define BOOST_TEST_EXEC_MONITOR_HPP_071894GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/test_tools.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** Auto Linking ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
// Automatically link to the correct build variant where possible.
|
||||
#if !defined(BOOST_ALL_NO_LIB) && !defined(BOOST_TEST_NO_LIB) && \
|
||||
!defined(BOOST_TEST_SOURCE) && !defined(BOOST_TEST_INCLUDED)
|
||||
|
||||
# define BOOST_LIB_NAME boost_test_exec_monitor
|
||||
# include <boost/config/auto_link.hpp>
|
||||
|
||||
#endif // auto-linking disabled
|
||||
|
||||
#endif // BOOST_TEST_EXEC_MONITOR_HPP_071894GER
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,419 @@
|
||||
// (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>
|
||||
#include <boost/test/utils/is_cstring.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
|
||||
typename boost::enable_if_c<
|
||||
unit_test::is_forward_iterable<Lhs>::value && unit_test::is_forward_iterable<Rhs>::value,
|
||||
assertion_result>::type
|
||||
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;
|
||||
}
|
||||
|
||||
template <typename OP, bool can_be_equal, bool prefer_shorter,
|
||||
typename Lhs, typename Rhs>
|
||||
inline
|
||||
typename boost::enable_if_c<
|
||||
(!unit_test::is_forward_iterable<Lhs>::value && unit_test::is_cstring<Lhs>::value) ||
|
||||
(!unit_test::is_forward_iterable<Rhs>::value && unit_test::is_cstring<Rhs>::value),
|
||||
assertion_result>::type
|
||||
lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
{
|
||||
typedef typename unit_test::deduce_cstring<Lhs>::type lhs_char_type;
|
||||
typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type;
|
||||
|
||||
return lexicographic_compare<OP, can_be_equal, prefer_shorter>(
|
||||
boost::unit_test::basic_cstring<lhs_char_type>(lhs),
|
||||
boost::unit_test::basic_cstring<rhs_char_type>(rhs));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** equality_compare ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template <typename OP, typename Lhs, typename Rhs>
|
||||
inline
|
||||
typename boost::enable_if_c<
|
||||
unit_test::is_forward_iterable<Lhs>::value && unit_test::is_forward_iterable<Rhs>::value,
|
||||
assertion_result>::type
|
||||
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;
|
||||
}
|
||||
|
||||
// In case string comparison is branching here
|
||||
template <typename OP, typename Lhs, typename Rhs>
|
||||
inline
|
||||
typename boost::enable_if_c<
|
||||
(!unit_test::is_forward_iterable<Lhs>::value && unit_test::is_cstring<Lhs>::value) ||
|
||||
(!unit_test::is_forward_iterable<Rhs>::value && unit_test::is_cstring<Rhs>::value),
|
||||
assertion_result>::type
|
||||
element_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
{
|
||||
typedef typename unit_test::deduce_cstring<Lhs>::type lhs_char_type;
|
||||
typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type;
|
||||
|
||||
return element_compare<OP>(boost::unit_test::basic_cstring<lhs_char_type>(lhs),
|
||||
boost::unit_test::basic_cstring<rhs_char_type>(rhs));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** 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_cstring<Lhs>::value \
|
||||
&& unit_test::is_forward_iterable<Rhs>::value \
|
||||
&& !unit_test::is_cstring<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
|
||||
@@ -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
|
||||
@@ -0,0 +1,87 @@
|
||||
// (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 unit_test::deduce_cstring<Lhs>::type lhs_char_type; \
|
||||
typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type; \
|
||||
public: \
|
||||
typedef assertion_result result_type; \
|
||||
\
|
||||
typedef name<lhs_char_type, rhs_char_type> elem_op; \
|
||||
\
|
||||
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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,243 @@
|
||||
// (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>
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
#include <cstddef>
|
||||
#endif
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
namespace tt_detail {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** boost_test_print_type ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace impl {
|
||||
template <class T>
|
||||
std::ostream& boost_test_print_type(std::ostream& ostr, T const& t) {
|
||||
BOOST_STATIC_ASSERT_MSG( (boost::has_left_shift<std::ostream,T>::value),
|
||||
"Type has to implement operator<< to be printable");
|
||||
ostr << t;
|
||||
return ostr;
|
||||
}
|
||||
|
||||
struct boost_test_print_type_impl {
|
||||
template <class R>
|
||||
std::ostream& operator()(std::ostream& ostr, R const& r) const {
|
||||
return boost_test_print_type(ostr, r);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// To avoid ODR violations, see N4381
|
||||
template <class T> struct static_const { static const T value; };
|
||||
template <class T> const T static_const<T>::value = T();
|
||||
|
||||
namespace {
|
||||
static const impl::boost_test_print_type_impl& boost_test_print_type =
|
||||
static_const<impl::boost_test_print_type_impl>::value;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** print_log_value ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename T>
|
||||
struct print_log_value {
|
||||
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;
|
||||
using boost::test_tools::tt_detail::boost_test_print_type;
|
||||
boost_test_print_type(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 );
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 );
|
||||
};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
template<>
|
||||
struct BOOST_TEST_DECL print_log_value<std::nullptr_t> {
|
||||
void operator()( std::ostream& ostr, std::nullptr_t t );
|
||||
};
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,230 @@
|
||||
// (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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -0,0 +1,107 @@
|
||||
// (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
|
||||
virtual ~output_test_stream();
|
||||
|
||||
//! Checks if the stream is empty
|
||||
//!
|
||||
//!@param[in] flush_stream if true, flushes the stream after the call
|
||||
virtual 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.
|
||||
virtual 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.
|
||||
virtual 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/resets the stream after the call.
|
||||
virtual assertion_result match_pattern( bool flush_stream = true );
|
||||
|
||||
//! Flushes the stream
|
||||
void flush();
|
||||
|
||||
protected:
|
||||
|
||||
//! Returns the string representation of the stream
|
||||
//!
|
||||
//! May be overriden in order to mutate the string before the matching operations.
|
||||
virtual std::string get_stream_string_representation() const;
|
||||
|
||||
private:
|
||||
// helper functions
|
||||
|
||||
//! Length of the stream
|
||||
std::size_t length();
|
||||
|
||||
//! Synching the stream into an internal string representation
|
||||
virtual 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
|
||||
@@ -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
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user