mirror of
https://github.com/vdemydiuk/mtapi.git
synced 2026-08-03 22:17:47 +00:00
Added thirdparty: boost library
This commit is contained in:
+21
@@ -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
|
||||
//! @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/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/unit_test.hpp>" )
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#endif // BOOST_TEST_AUTO_UNIT_TEST_HPP_071894GER
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
// (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
|
||||
|
||||
//! Defined when the initializer_list implementation is buggy, such as for VS2013
|
||||
#if defined(_MSC_VER) && _MSC_VER < 1900
|
||||
# define BOOST_TEST_ERRONEOUS_INIT_LIST
|
||||
#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
|
||||
+19
@@ -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
|
||||
|
||||
+117
@@ -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 const & 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
|
||||
|
||||
+67
@@ -0,0 +1,67 @@
|
||||
// (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 <>
|
||||
struct make_index_sequence<0, 0> {
|
||||
typedef index_sequence<> 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
|
||||
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
// (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>
|
||||
#include <boost/test/data/monomorphic/delayed.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_HPP_102211GER
|
||||
|
||||
+83
@@ -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;
|
||||
|
||||
static const int 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
|
||||
|
||||
+91
@@ -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;
|
||||
|
||||
static const int 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_container_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
|
||||
|
||||
+124
@@ -0,0 +1,124 @@
|
||||
// (C) Copyright Raffi Enficiaud 2018.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt 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 a lazy/delayed dataset store
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_DELAYED_HPP_062018GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_DELAYED_HPP_062018GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/config.hpp>
|
||||
#include <boost/test/data/monomorphic/fwd.hpp>
|
||||
#include <boost/test/data/index_sequence.hpp>
|
||||
|
||||
#include <boost/core/ref.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <memory>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** delayed_dataset ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
|
||||
/// Delayed dataset
|
||||
///
|
||||
/// This dataset holds another dataset that is instanciated on demand. It is
|
||||
/// constructed with the @c data::make_delayed<dataset_t>(arg1,....) instead of the
|
||||
/// @c data::make.
|
||||
template <class dataset_t, class ...Args>
|
||||
class delayed_dataset
|
||||
{
|
||||
public:
|
||||
static const int arity = dataset_t::arity;
|
||||
using iterator = decltype(std::declval<dataset_t>().begin());
|
||||
|
||||
delayed_dataset(Args... args)
|
||||
: m_args(std::make_tuple(std::forward<Args>(args)...))
|
||||
{}
|
||||
|
||||
// Mostly for VS2013
|
||||
delayed_dataset(delayed_dataset&& b)
|
||||
: m_args(std::move(b.m_args))
|
||||
, m_dataset(std::move(b.m_dataset))
|
||||
{}
|
||||
|
||||
boost::unit_test::data::size_t size() const {
|
||||
return this->get().size();
|
||||
}
|
||||
|
||||
// iterator
|
||||
iterator begin() const {
|
||||
return this->get().begin();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
dataset_t& get() const {
|
||||
if(!m_dataset) {
|
||||
m_dataset = create(boost::unit_test::data::index_sequence_for<Args...>());
|
||||
}
|
||||
return *m_dataset;
|
||||
}
|
||||
|
||||
template<std::size_t... I>
|
||||
std::unique_ptr<dataset_t>
|
||||
create(boost::unit_test::data::index_sequence<I...>) const
|
||||
{
|
||||
return std::unique_ptr<dataset_t>{new dataset_t(std::get<I>(m_args)...)};
|
||||
}
|
||||
|
||||
std::tuple<typename std::decay<Args>::type...> m_args;
|
||||
mutable std::unique_ptr<dataset_t> m_dataset;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! A lazy/delayed dataset is a dataset.
|
||||
template <class dataset_t, class ...Args>
|
||||
struct is_dataset< delayed_dataset<dataset_t, Args...> > : boost::mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace monomorphic
|
||||
|
||||
|
||||
//! Delayed dataset instanciation
|
||||
template<class dataset_t, class ...Args>
|
||||
inline typename std::enable_if<
|
||||
monomorphic::is_dataset< dataset_t >::value,
|
||||
monomorphic::delayed_dataset<dataset_t, Args...>
|
||||
>::type
|
||||
make_delayed(Args... args)
|
||||
{
|
||||
return monomorphic::delayed_dataset<dataset_t, Args...>( std::forward<Args>(args)... );
|
||||
}
|
||||
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_DELAYED_HPP_062018GER
|
||||
+222
@@ -0,0 +1,222 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
/// @file
|
||||
/// 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>
|
||||
class singleton;
|
||||
|
||||
template<typename C>
|
||||
class collection;
|
||||
|
||||
template<typename T>
|
||||
class array;
|
||||
|
||||
template<typename T>
|
||||
class init_list;
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
template<class dataset_t, class ...Args>
|
||||
class delayed_dataset;
|
||||
#endif
|
||||
|
||||
#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> {};
|
||||
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> {};
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
|
||||
|
||||
//! Helper to check if a list of types contains a dataset
|
||||
template<class DataSet, class...>
|
||||
struct has_dataset : is_dataset<DataSet> {};
|
||||
|
||||
template<class DataSet0, class DataSet1, class... DataSetTT>
|
||||
struct has_dataset<DataSet0, DataSet1, DataSetTT...>
|
||||
: std::integral_constant<bool, is_dataset<DataSet0>::value || has_dataset<DataSet1, DataSetTT...>::value>
|
||||
{};
|
||||
#endif
|
||||
|
||||
} // 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_container_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_container_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>&& );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_TEST_ERRONEOUS_INIT_LIST)
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<class T, class ...Args>
|
||||
inline typename std::enable_if<
|
||||
!monomorphic::has_dataset<T, Args...>::value,
|
||||
monomorphic::init_list<T>
|
||||
>::type
|
||||
make( T&& arg0, Args&&... args );
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_HDR_TUPLE)
|
||||
template<class dataset_t, class ...Args>
|
||||
inline typename std::enable_if<
|
||||
monomorphic::is_dataset< dataset_t >::value,
|
||||
monomorphic::delayed_dataset<dataset_t, Args...>
|
||||
>::type
|
||||
make_delayed(Args... args);
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
|
||||
+111
@@ -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
|
||||
/// 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/core/ref.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;
|
||||
|
||||
static const int 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
|
||||
|
||||
+20
@@ -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 BOOST_ATTRIBUTE_UNUSED;
|
||||
nfp::keyword<struct end_t> end BOOST_ATTRIBUTE_UNUSED;
|
||||
nfp::keyword<struct step_t> step BOOST_ATTRIBUTE_UNUSED;
|
||||
} // 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
|
||||
+185
@@ -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
|
||||
/// 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/core/enable_if.hpp>
|
||||
#include <boost/mpl/identity.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( 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:
|
||||
static const int 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 {
|
||||
BOOST_TEST_DS_ASSERT( !m_ds1.size().is_inf() && !m_ds2.size().is_inf(), "Grid axes can't have infinite size" );
|
||||
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 )
|
||||
{
|
||||
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
|
||||
|
||||
+159
@@ -0,0 +1,159 @@
|
||||
// (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/core/ignore_unused.hpp>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** initializer_list ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// Dataset view from an initializer_list or variadic template arguments
|
||||
///
|
||||
/// The data should be stored in the dataset, and since the elements
|
||||
/// are passed by an @c std::initializer_list , it implies a copy of
|
||||
/// the elements.
|
||||
template<typename T>
|
||||
class init_list {
|
||||
public:
|
||||
static const int arity = 1;
|
||||
|
||||
typedef typename std::vector<T>::const_iterator iterator;
|
||||
|
||||
//! Constructor copies content of initializer_list
|
||||
init_list( std::initializer_list<T> il )
|
||||
: m_data( il )
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_TEST_ERRONEOUS_INIT_LIST)
|
||||
//! Variadic template initialization
|
||||
template <class ...Args>
|
||||
init_list( Args&& ... args ) {
|
||||
int dummy[] = { 0, (m_data.emplace_back(std::forward<Args&&>(args)), 0)... };
|
||||
boost::ignore_unused(dummy);
|
||||
}
|
||||
#endif
|
||||
|
||||
//! dataset interface
|
||||
data::size_t size() const { return m_data.size(); }
|
||||
iterator begin() const { return m_data.begin(); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::vector<T> m_data;
|
||||
};
|
||||
|
||||
//! Specialization of init_list for type bool
|
||||
template <>
|
||||
class init_list<bool> {
|
||||
public:
|
||||
typedef bool sample;
|
||||
|
||||
static const int arity = 1;
|
||||
|
||||
//! Constructor copies content of initializer_list
|
||||
init_list( std::initializer_list<bool>&& il )
|
||||
: m_data( std::forward<std::initializer_list<bool>>( il ) )
|
||||
{}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_TEST_ERRONEOUS_INIT_LIST)
|
||||
//! Variadic template initialization
|
||||
template <class ...Args>
|
||||
init_list( Args&& ... args ) : m_data{ args... }
|
||||
{ }
|
||||
#endif
|
||||
|
||||
struct non_proxy_iterator {
|
||||
std::vector<bool>::const_iterator iterator;
|
||||
non_proxy_iterator(std::vector<bool>::const_iterator &&it)
|
||||
: iterator(std::forward<std::vector<bool>::const_iterator>(it))
|
||||
{}
|
||||
|
||||
bool operator*() const {
|
||||
return *iterator;
|
||||
}
|
||||
|
||||
non_proxy_iterator& operator++() {
|
||||
++iterator;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
typedef non_proxy_iterator iterator;
|
||||
|
||||
//! dataset interface
|
||||
data::size_t size() const { return m_data.size(); }
|
||||
iterator begin() const { return m_data.begin(); }
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::vector<bool> 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 ) );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_TEST_ERRONEOUS_INIT_LIST)
|
||||
template<class T, class ...Args>
|
||||
inline typename std::enable_if<
|
||||
!monomorphic::has_dataset<T, Args...>::value,
|
||||
monomorphic::init_list<T>
|
||||
>::type
|
||||
make( T&& arg0, Args&&... args )
|
||||
{
|
||||
return monomorphic::init_list<T>( std::forward<T>(arg0), std::forward<Args>( args )... );
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // namespace data
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_INITIALIZATION_LIST_HPP_091515GER
|
||||
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
// (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/core/enable_if.hpp>
|
||||
#include <boost/mpl/identity.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;
|
||||
|
||||
using iter1_ret = decltype(*std::declval<DataSet1>().begin());
|
||||
using iter2_ret = decltype(*std::declval<DataSet2>().begin());
|
||||
|
||||
public:
|
||||
|
||||
static const int arity = dataset1_decay::arity;
|
||||
|
||||
using sample_t = typename std::conditional<
|
||||
std::is_reference<iter1_ret>::value && std::is_reference<iter2_ret>::value && std::is_same<iter1_ret, iter2_ret>::value,
|
||||
iter1_ret,
|
||||
typename std::remove_reference<iter1_ret>::type
|
||||
>::type
|
||||
;
|
||||
|
||||
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
|
||||
// The returned sample should be by value, as the operator* may return a temporary object
|
||||
sample_t 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
|
||||
|
||||
+103
@@ -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
|
||||
|
||||
+121
@@ -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
|
||||
/// 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 {
|
||||
private:
|
||||
typedef typename boost::decay<T>::type sample;
|
||||
|
||||
public:
|
||||
|
||||
static const int 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_container_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
|
||||
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
// (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/core/enable_if.hpp>
|
||||
#include <boost/mpl/identity.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:
|
||||
static const int 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;
|
||||
};
|
||||
|
||||
//! 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 zip_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;
|
||||
|
||||
|
||||
//! Handles the sise of the resulting zipped dataset.
|
||||
data::size_t zip_size() const
|
||||
{
|
||||
data::size_t ds1_size = m_ds1.size();
|
||||
data::size_t ds2_size = m_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" );
|
||||
}
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
//! Zipped datasets results in a dataset.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
struct is_dataset<zip<DataSet1,DataSet2>> : mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
|
||||
+145
@@ -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
|
||||
|
||||
+345
@@ -0,0 +1,345 @@
|
||||
// (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>
|
||||
#include <boost/test/tree/test_unit.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/bind.hpp>
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
|
||||
#include <boost/test/tools/detail/print_helper.hpp>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.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_dataset( std::forward<DataSet>( ds ) )
|
||||
, m_generated( false )
|
||||
, 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 )
|
||||
{}
|
||||
test_case_gen( test_case_gen&& gen )
|
||||
: m_dataset( std::move( gen.m_dataset ) )
|
||||
, m_generated( gen.m_generated )
|
||||
, 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_dataset( ds )
|
||||
, m_generated( false )
|
||||
, 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 )
|
||||
{}
|
||||
#endif
|
||||
|
||||
public:
|
||||
virtual test_unit* next() const
|
||||
{
|
||||
if(!m_generated) {
|
||||
data::for_each_sample( m_dataset, *this );
|
||||
m_generated = true;
|
||||
}
|
||||
|
||||
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
|
||||
// there is also a limit on boost::bind
|
||||
#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,
|
||||
std::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
|
||||
DataSet m_dataset;
|
||||
mutable bool m_generated;
|
||||
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>
|
||||
boost::shared_ptr<test_unit_generator> //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 boost::shared_ptr<test_unit_generator>(new 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_CONTEXT( "" \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
|
||||
{ \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture ctor");\
|
||||
BOOST_PP_CAT(test_name, case) t; \
|
||||
BOOST_TEST_CHECKPOINT('"' \
|
||||
<< #test_name << "\" fixture setup"); \
|
||||
boost::unit_test::setup_conditional(t); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" test entry"); \
|
||||
t._impl(BOOST_PP_SEQ_ENUM(params)); \
|
||||
BOOST_TEST_CHECKPOINT('"' \
|
||||
<< #test_name << "\" fixture teardown"); \
|
||||
boost::unit_test::teardown_conditional(t); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture dtor");\
|
||||
} \
|
||||
} \
|
||||
private: \
|
||||
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
|
||||
void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \
|
||||
}; \
|
||||
\
|
||||
BOOST_AUTO_TEST_SUITE( test_name, \
|
||||
*boost::unit_test::decorator::stack_decorator()) \
|
||||
\
|
||||
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_t::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
|
||||
|
||||
+138
@@ -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
|
||||
+24
@@ -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
|
||||
+181
@@ -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
|
||||
//!@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__) && !defined(BOOST_EMBTC) || \
|
||||
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(BOOST_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(BOOST_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 BOOST_WORKAROUND(BOOST_MSVC, < 1400)
|
||||
#define BOOST_TEST_PROTECTED_VIRTUAL
|
||||
#else
|
||||
#define BOOST_TEST_PROTECTED_VIRTUAL virtual
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if !defined(BOOST_BORLANDC) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
|
||||
#define BOOST_TEST_SUPPORT_TOKEN_ITERATOR 1
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// Sun compiler does not support visibility on enums
|
||||
#if defined(__SUNPRO_CC)
|
||||
#define BOOST_TEST_ENUM_SYMBOL_VISIBLE
|
||||
#else
|
||||
#define BOOST_TEST_ENUM_SYMBOL_VISIBLE BOOST_SYMBOL_VISIBLE
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if defined(BOOST_ALL_DYN_LINK) && !defined(BOOST_TEST_DYN_LINK)
|
||||
# define BOOST_TEST_DYN_LINK
|
||||
#endif
|
||||
|
||||
// in case any of the define from cmake/b2 is set
|
||||
#if !defined(BOOST_TEST_DYN_LINK) \
|
||||
&& (defined(BOOST_UNIT_TEST_FRAMEWORK_DYN_LINK) \
|
||||
|| defined(BOOST_TEST_EXEC_MONITOR_DYN_LINK) \
|
||||
|| defined(BOOST_PRG_EXEC_MONITOR_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 BOOST_SYMBOL_VISIBLE
|
||||
# else
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_IMPORT BOOST_SYMBOL_VISIBLE
|
||||
# endif // BOOST_TEST_SOURCE
|
||||
#else
|
||||
# if defined(BOOST_TEST_INCLUDED)
|
||||
# define BOOST_TEST_DECL
|
||||
# else
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_VISIBLE
|
||||
# endif
|
||||
#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
|
||||
|
||||
#if defined(__NVCC__)
|
||||
#define BOOST_PP_VARIADICS 1
|
||||
#endif
|
||||
|
||||
#endif /* ifndef BOOST_PP_VARIADICS */
|
||||
|
||||
// some versions of VC exibit a manifest error with this BOOST_UNREACHABLE_RETURN
|
||||
#if BOOST_WORKAROUND(BOOST_MSVC, < 1910)
|
||||
# define BOOST_TEST_UNREACHABLE_RETURN(x) return x
|
||||
#else
|
||||
# define BOOST_TEST_UNREACHABLE_RETURN(x) BOOST_UNREACHABLE_RETURN(x)
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// MSVC <= 12 and GCC <= 4.6 do not allow for defaulted destructors
|
||||
// See: https://github.com/boostorg/test/issues/385
|
||||
|
||||
#if (defined(BOOST_MSVC) && BOOST_MSVC < 1900) || (defined(BOOST_GCC) && BOOST_GCC < 40700)
|
||||
# define BOOST_TEST_DEFAULTED_FUNCTION(fun, body) fun body
|
||||
#else
|
||||
# define BOOST_TEST_DEFAULTED_FUNCTION(fun, body) BOOST_DEFAULTED_FUNCTION(fun, body);
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
// string_view support
|
||||
//____________________________________________________________________________//
|
||||
// note the code should always be compatible with compiled version of boost.test
|
||||
// using a pre-c++17 compiler
|
||||
|
||||
#ifndef BOOST_NO_CXX17_HDR_STRING_VIEW
|
||||
#define BOOST_TEST_STRING_VIEW
|
||||
#endif
|
||||
|
||||
#endif // BOOST_TEST_CONFIG_HPP_071894GER
|
||||
+36
@@ -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 defined(BOOST_CLANG) && (BOOST_CLANG == 1)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 4 * 10000 + 6 * 100)
|
||||
# pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
+47
@@ -0,0 +1,47 @@
|
||||
// (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;
|
||||
class test_unit_fixture;
|
||||
class global_fixture;
|
||||
|
||||
// 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
|
||||
|
||||
+149
@@ -0,0 +1,149 @@
|
||||
// (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>
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
//! Helper class for restoring the current test unit ID in a RAII manner
|
||||
struct test_unit_id_restore {
|
||||
test_unit_id_restore(test_unit_id& to_restore_, test_unit_id new_value)
|
||||
: to_restore(to_restore_)
|
||||
, bkup(to_restore_) {
|
||||
to_restore = new_value;
|
||||
}
|
||||
~test_unit_id_restore() {
|
||||
to_restore = bkup;
|
||||
}
|
||||
private:
|
||||
test_unit_id& to_restore;
|
||||
test_unit_id bkup;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // 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;
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// helper defines for singletons.
|
||||
// BOOST_TEST_SINGLETON_CONS should appear in the class body,
|
||||
// BOOST_TEST_SINGLETON_CONS_IMPL should be in only one translation unit. The
|
||||
// global instance should be declared by BOOST_TEST_SINGLETON_INST.
|
||||
|
||||
#define BOOST_TEST_SINGLETON_CONS_NO_CTOR( type ) \
|
||||
public: \
|
||||
static type& instance(); \
|
||||
private: \
|
||||
BOOST_DELETED_FUNCTION(type(type const&)) \
|
||||
BOOST_DELETED_FUNCTION(type& operator=(type const&)) \
|
||||
BOOST_DEFAULTED_FUNCTION(~type(), {}) \
|
||||
/**/
|
||||
|
||||
#define BOOST_TEST_SINGLETON_CONS( type ) \
|
||||
BOOST_TEST_SINGLETON_CONS_NO_CTOR(type) \
|
||||
private: \
|
||||
BOOST_DEFAULTED_FUNCTION(type(), {}) \
|
||||
/**/
|
||||
|
||||
#define BOOST_TEST_SINGLETON_CONS_IMPL( type ) \
|
||||
type& type::instance() { \
|
||||
static type the_inst; return the_inst; \
|
||||
} \
|
||||
/**/
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#if defined(__APPLE_CC__) && defined(__GNUC__) && __GNUC__ < 4
|
||||
#define BOOST_TEST_SINGLETON_INST( inst ) \
|
||||
static BOOST_JOIN( inst, _t)& inst BOOST_ATTRIBUTE_UNUSED = BOOST_JOIN (inst, _t)::instance();
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_TEST_SINGLETON_INST( inst ) \
|
||||
namespace { BOOST_JOIN( inst, _t)& inst BOOST_ATTRIBUTE_UNUSED = BOOST_JOIN( inst, _t)::instance(); }
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
|
||||
+42
@@ -0,0 +1,42 @@
|
||||
// (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
|
||||
|
||||
#include <boost/test/detail/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** log levels ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
// each log level includes all subsequent higher loging levels
|
||||
enum BOOST_TEST_ENUM_SYMBOL_VISIBLE 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
|
||||
+49
@@ -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
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
// (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 defined(BOOST_CLANG) && (BOOST_CLANG == 1)
|
||||
# pragma clang diagnostic push
|
||||
# pragma clang diagnostic ignored "-Wvariadic-macros"
|
||||
# pragma clang diagnostic ignored "-Wmissing-declarations"
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_GCC) && (BOOST_GCC >= 4 * 10000 + 6 * 100)
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wvariadic-macros"
|
||||
# pragma GCC diagnostic ignored "-Wmissing-declarations"
|
||||
// # pragma GCC diagnostic ignored "-Wattributes"
|
||||
#endif
|
||||
|
||||
+71
@@ -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
|
||||
+584
@@ -0,0 +1,584 @@
|
||||
// (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 discussions 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_SYMBOL_VISIBLE 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 );
|
||||
explicit location( const_string file_name, 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 execution_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 microseconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
|
||||
/// or infinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
|
||||
unit_test::readwrite_property<unsigned long int> 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 doesn'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
|
||||
int operator()( boost::function<int ()> const& F ) BOOST_OVERRIDE
|
||||
{
|
||||
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
|
||||
translator_holder_base_ptr erase( translator_holder_base_ptr this_, std::type_info const& ti ) BOOST_OVERRIDE
|
||||
{
|
||||
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 BOOST_SYMBOL_VISIBLE 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_DIVBYZERO = BOOST_FPE_OFF,
|
||||
BOOST_FPE_INEXACT = BOOST_FPE_OFF,
|
||||
BOOST_FPE_INVALID = BOOST_FPE_OFF,
|
||||
BOOST_FPE_OVERFLOW = BOOST_FPE_OFF,
|
||||
BOOST_FPE_UNDERFLOW = BOOST_FPE_OFF,
|
||||
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
|
||||
+18
@@ -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 boost/test/tools/floating_point_comparison.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/tools/floating_point_comparison.hpp>" )
|
||||
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/floating_point_comparison.hpp>
|
||||
+307
@@ -0,0 +1,307 @@
|
||||
// (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/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 );
|
||||
|
||||
/// Excludes 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 Global fixtures registration
|
||||
/// @{
|
||||
|
||||
/// Adds a new global fixture to be setup before any other tests starts and tore down after
|
||||
/// any other tests finished.
|
||||
/// Test unit fixture lifetime should exceed the testing execution timeframe
|
||||
/// @param[in] tuf fixture to add
|
||||
BOOST_TEST_DECL void register_global_fixture( global_fixture& tuf );
|
||||
|
||||
/// Removes a test global fixture from the framework
|
||||
///
|
||||
/// Test unit fixture lifetime should exceed the testing execution timeframe
|
||||
/// @param[in] tuf fixture to remove
|
||||
BOOST_TEST_DECL void deregister_global_fixture( global_fixture& tuf );
|
||||
/// @}
|
||||
|
||||
/// @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 unit currently being executed.
|
||||
|
||||
/// The difference with current_test_case is about the time between a test-suite
|
||||
/// is being set up or torn down (fixtures) and when the test-cases of that suite start.
|
||||
|
||||
/// This function is only valid during test execution phase.
|
||||
/// @see current_test_case_id, current_test_case
|
||||
BOOST_TEST_DECL test_unit const& current_test_unit();
|
||||
|
||||
/// 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& );
|
||||
/// Reports aborted test module to all test observers
|
||||
BOOST_TEST_DECL void test_aborted( );
|
||||
/// @}
|
||||
|
||||
namespace impl {
|
||||
// exclusively for self test
|
||||
BOOST_TEST_DECL void setup_for_execution( test_unit const& );
|
||||
BOOST_TEST_DECL void setup_loggers( );
|
||||
|
||||
// Helper for setting the name of the master test suite globally
|
||||
struct BOOST_TEST_DECL master_test_suite_name_setter {
|
||||
master_test_suite_name_setter( const_string name );
|
||||
};
|
||||
|
||||
} // 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
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description : 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>
|
||||
|
||||
// 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_unit().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, bool log_build_info )
|
||||
{
|
||||
if(log_build_info) {
|
||||
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 );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::GREEN, term_color::ORIGINAL, &m_color_state);
|
||||
output << "info: ";
|
||||
break;
|
||||
case BOOST_UTL_ET_MESSAGE:
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::CYAN, term_color::ORIGINAL, &m_color_state);
|
||||
break;
|
||||
case BOOST_UTL_ET_WARNING:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::YELLOW, term_color::ORIGINAL, &m_color_state);
|
||||
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 );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::RED, term_color::ORIGINAL, &m_color_state);
|
||||
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 );
|
||||
output << setcolor( m_color_output, term_attr::UNDERLINE, term_color::RED, term_color::ORIGINAL, &m_color_state);
|
||||
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(m_color_output, &m_color_state);
|
||||
|
||||
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 )
|
||||
{
|
||||
if( l == log_messages ) {
|
||||
output << "\n[context:";
|
||||
}
|
||||
else {
|
||||
output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
compiler_log_formatter::entry_context_finish( std::ostream& output, log_level l )
|
||||
{
|
||||
if( l == log_messages ) {
|
||||
output << "]";
|
||||
}
|
||||
output.flush();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
compiler_log_formatter::log_entry_context( std::ostream& output, log_level /*l*/, 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
|
||||
+136
@@ -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
|
||||
+1052
File diff suppressed because it is too large
Load Diff
+244
@@ -0,0 +1,244 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// Description : 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_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(collector_t)
|
||||
|
||||
|
||||
collector_t&
|
||||
collector_t::operator*( base const& d )
|
||||
{
|
||||
m_tu_decorators_stack.begin()->push_back( d.clone() );
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
collector_t::store_in( test_unit& tu )
|
||||
{
|
||||
tu.p_decorators.value.insert(
|
||||
tu.p_decorators.value.end(),
|
||||
m_tu_decorators_stack.begin()->begin(),
|
||||
m_tu_decorators_stack.begin()->end() );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
collector_t::reset()
|
||||
{
|
||||
if(m_tu_decorators_stack.size() > 1) {
|
||||
m_tu_decorators_stack.erase(m_tu_decorators_stack.begin());
|
||||
}
|
||||
else {
|
||||
assert(m_tu_decorators_stack.size() == 1);
|
||||
m_tu_decorators_stack.begin()->clear();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
collector_t::stack()
|
||||
{
|
||||
assert(m_tu_decorators_stack.size() >= 1);
|
||||
m_tu_decorators_stack.insert(m_tu_decorators_stack.begin(), std::vector<base_ptr>());
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
std::vector<base_ptr>
|
||||
collector_t::get_lazy_decorators() const
|
||||
{
|
||||
return *m_tu_decorators_stack.begin();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::base ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector_t&
|
||||
base::operator*() const
|
||||
{
|
||||
return collector_t::instance() * *this;
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::stack_decorator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector_t&
|
||||
stack_decorator::operator*() const
|
||||
{
|
||||
collector_t& instance = collector_t::instance();
|
||||
instance.stack();
|
||||
return instance * *this;
|
||||
}
|
||||
|
||||
void
|
||||
stack_decorator::apply( test_unit& /*tu*/ )
|
||||
{
|
||||
// does nothing by definition
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** 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
|
||||
+1543
File diff suppressed because it is too large
Load Diff
+1819
File diff suppressed because it is too large
Load Diff
+878
@@ -0,0 +1,878 @@
|
||||
// (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/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>
|
||||
#include <boost/core/ignore_unused.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;
|
||||
}
|
||||
|
||||
inline std::string tu_name_remove_newlines(std::string full_name)
|
||||
{
|
||||
full_name.erase(std::remove(full_name.begin(), full_name.end(), '\n'), full_name.end());
|
||||
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 {
|
||||
private:
|
||||
typedef junit_impl::junit_log_helper::assertion_entry assertion_entry;
|
||||
typedef std::vector< assertion_entry >::const_iterator vect_assertion_entry_citerator;
|
||||
typedef std::list<std::string>::const_iterator list_str_citerator;
|
||||
|
||||
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(assertion_entry const& log) const
|
||||
{
|
||||
std::string entry_type;
|
||||
if( log.log_entry == assertion_entry::log_entry_failure ) {
|
||||
entry_type = "failure";
|
||||
}
|
||||
else if( log.log_entry == assertion_entry::log_entry_error ) {
|
||||
entry_type = "error";
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
|
||||
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_unit const & tu) const
|
||||
{
|
||||
// we enter here because we know that the tu has been skipped.
|
||||
// either junit has not seen this tu, or it is indicated as disabled
|
||||
assert(m_map_test.count(tu.p_id) == 0 || results_collector.results( tu.p_id ).p_skipped);
|
||||
|
||||
std::list<std::string> out;
|
||||
|
||||
test_unit_id id(tu.p_id);
|
||||
while( id != m_ts.p_id && id != INV_TEST_UNIT_ID) {
|
||||
test_unit const& tu_hierarchy = boost::unit_test::framework::get( id, TUT_ANY );
|
||||
out.push_back("- disabled test unit: '" + tu_name_remove_newlines(tu_hierarchy.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_hierarchy.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_unit const & tu_class) const {
|
||||
std::string classname;
|
||||
test_unit_id id(tu_class.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_unit const & tu,
|
||||
test_results const *tr,
|
||||
int nb_assertions) const
|
||||
{
|
||||
std::string name;
|
||||
std::string classname;
|
||||
|
||||
if(tu.p_id == m_ts.p_id ) {
|
||||
name = "boost_test";
|
||||
}
|
||||
else {
|
||||
classname = get_class_name(tu);
|
||||
name = tu_name_normalize(tu.p_name);
|
||||
}
|
||||
|
||||
if( tu.p_type == TUT_SUITE ) {
|
||||
if(tr->p_timed_out)
|
||||
name += "-timed-execution";
|
||||
else
|
||||
name += "-setup-teardown";
|
||||
}
|
||||
|
||||
m_stream << "<testcase assertions" << utils::attr_value() << nb_assertions;
|
||||
if(!classname.empty())
|
||||
m_stream << " classname" << utils::attr_value() << classname;
|
||||
|
||||
// test case name and time taken
|
||||
m_stream
|
||||
<< " name" << utils::attr_value() << 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_unit const * tu,
|
||||
bool skipped) 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(*tu);
|
||||
for(list_str_citerator it(skipping_decision_chain.begin()), ite(skipping_decision_chain.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
system_out_helper(*it);
|
||||
}
|
||||
}
|
||||
|
||||
// stdout
|
||||
for(list_str_citerator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
system_out_helper(*it);
|
||||
}
|
||||
|
||||
// warning/info message last
|
||||
for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
if(it->log_entry != 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_unit const * tu,
|
||||
test_results const *tr) const
|
||||
{
|
||||
// system-err output + test case informations
|
||||
bool has_failed = (tr != 0) ? !tr->p_skipped && !tr->passed() : false;
|
||||
if(!detailed_log.system_err.empty() || has_failed)
|
||||
{
|
||||
std::ostringstream o;
|
||||
if(has_failed) {
|
||||
o << "Failures detected in:" << std::endl;
|
||||
}
|
||||
else {
|
||||
o << "ERROR STREAM:" << std::endl;
|
||||
}
|
||||
|
||||
if(tu->p_type == TUT_SUITE) {
|
||||
if( tu->p_id == m_ts.p_id ) {
|
||||
o << " boost.test global setup/teardown" << std::endl;
|
||||
} else {
|
||||
o << "- test suite: " << tu_name_remove_newlines(tu->full_name()) << std::endl;
|
||||
}
|
||||
}
|
||||
else {
|
||||
o << "- test case: " << tu_name_remove_newlines(tu->full_name());
|
||||
if(!tu->p_description.value.empty())
|
||||
o << " '" << tu->p_description << "'";
|
||||
|
||||
o << std::endl
|
||||
<< "- file: " << file_basename(tu->p_file_name) << std::endl
|
||||
<< "- line: " << tu->p_line_num << std::endl
|
||||
;
|
||||
}
|
||||
|
||||
if(!detailed_log.system_err.empty())
|
||||
o << std::endl << "STDERR BEGIN: ------------" << std::endl;
|
||||
|
||||
for(list_str_citerator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
o << *it;
|
||||
}
|
||||
|
||||
if(!detailed_log.system_err.empty())
|
||||
o << std::endl << "STDERR END ------------" << std::endl;
|
||||
|
||||
conditional_cdata_helper system_err_helper(m_stream, "system-err");
|
||||
system_err_helper(o.str());
|
||||
}
|
||||
}
|
||||
|
||||
int get_nb_assertions(junit_impl::junit_log_helper const &detailed_log,
|
||||
test_unit const & tu,
|
||||
test_results const *tr) const {
|
||||
int nb_assertions(-1);
|
||||
if( tu.p_type == TUT_SUITE ) {
|
||||
nb_assertions = 0;
|
||||
for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
if(it->log_entry != assertion_entry::log_entry_info)
|
||||
nb_assertions++;
|
||||
}
|
||||
}
|
||||
else {
|
||||
nb_assertions = static_cast<int>(tr->p_assertions_passed + tr->p_assertions_failed);
|
||||
}
|
||||
|
||||
return nb_assertions;
|
||||
}
|
||||
|
||||
void output_detailed_logs(junit_impl::junit_log_helper const &detailed_log,
|
||||
test_unit const & tu,
|
||||
bool skipped,
|
||||
test_results const *tr) const
|
||||
{
|
||||
int nb_assertions = get_nb_assertions(detailed_log, tu, tr);
|
||||
if(!nb_assertions && tu.p_type == TUT_SUITE)
|
||||
return;
|
||||
|
||||
write_testcase_header(tu, tr, nb_assertions);
|
||||
|
||||
if( skipped ) {
|
||||
m_stream << "<skipped/>" << std::endl;
|
||||
}
|
||||
else {
|
||||
|
||||
for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
add_log_entry(*it);
|
||||
}
|
||||
}
|
||||
|
||||
write_testcase_system_out(detailed_log, &tu, skipped);
|
||||
write_testcase_system_err(detailed_log, &tu, tr);
|
||||
m_stream << "</testcase>" << std::endl;
|
||||
}
|
||||
|
||||
void visit( test_case const& tc ) BOOST_OVERRIDE
|
||||
{
|
||||
|
||||
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 ) BOOST_OVERRIDE
|
||||
{
|
||||
test_results const& tr = results_collector.results( ts.p_id );
|
||||
|
||||
// unique test suite, without s, nesting not supported in CI
|
||||
if( m_ts.p_id == ts.p_id ) {
|
||||
m_stream << "<testsuite";
|
||||
|
||||
// think about: maybe we should add the number of fixtures of a test_suite as
|
||||
// independent tests (field p_fixtures).
|
||||
// same goes for the timed-execution: we can think of that as a separate test-unit
|
||||
// in the suite.
|
||||
// see https://llg.cubic.org/docs/junit/ and
|
||||
// http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/XMLJUnitResultFormatter.java?view=markup
|
||||
m_stream
|
||||
// << "disabled=\"" << tr.p_test_cases_skipped << "\" "
|
||||
<< " tests" << utils::attr_value()
|
||||
<< tr.p_test_cases_passed
|
||||
+ tr.p_test_cases_failed
|
||||
// + tr.p_test_cases_aborted // aborted is also failed, we avoid counting it twice
|
||||
<< " 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
|
||||
+ tr.p_test_suites_timed_out
|
||||
+ tr.p_test_cases_timed_out
|
||||
- tr.p_test_cases_aborted // failed is not aborted in the Junit sense
|
||||
<< " 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;
|
||||
}
|
||||
}
|
||||
|
||||
if( !tr.p_skipped ) {
|
||||
// if we land here, then this is a chance that we are logging the fixture setup/teardown of a test-suite.
|
||||
// the setup/teardown logging of a test-case is part of the test case.
|
||||
// we do not care about the test-suite that were skipped (really??)
|
||||
junit_log_formatter::map_trace_t::const_iterator it_find = m_map_test.find(ts.p_id);
|
||||
if(it_find != m_map_test.end()) {
|
||||
output_detailed_logs(it_find->second, ts, false, &tr);
|
||||
}
|
||||
}
|
||||
|
||||
return true; // indicates that the children should also be parsed
|
||||
}
|
||||
|
||||
void test_suite_finish( test_suite const& ts ) BOOST_OVERRIDE
|
||||
{
|
||||
if( m_ts.p_id == ts.p_id ) {
|
||||
write_testcase_system_out(runner_log, 0, false);
|
||||
write_testcase_system_err(runner_log, 0, 0);
|
||||
|
||||
m_stream << "</testsuite>";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
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*/, bool log_build_info )
|
||||
{
|
||||
m_display_build_info = log_build_info;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
boost::ignore_unused( tu );
|
||||
assert( tu.p_id == list_path_to_root.back() );
|
||||
list_path_to_root.pop_back();
|
||||
}
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_aborted( std::ostream& /*ostr*/, test_unit const& tu )
|
||||
{
|
||||
boost::ignore_unused( tu );
|
||||
assert( tu.p_id == list_path_to_root.back() );
|
||||
//list_path_to_root.pop_back();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_timed_out( std::ostream& /*os*/, test_unit const& tu)
|
||||
{
|
||||
if(tu.p_type == TUT_SUITE)
|
||||
{
|
||||
// if we reach this call, it means that the test has already started and
|
||||
// test_unit_start has already been called on the tu.
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
junit_impl::junit_log_helper::assertion_entry entry;
|
||||
entry.logentry_message = "test-suite time out";
|
||||
entry.logentry_type = "execution timeout";
|
||||
entry.log_entry = junit_impl::junit_log_helper::assertion_entry::log_entry_error;
|
||||
entry.output = "the current suite exceeded the allocated execution time";
|
||||
last_entry.assertion_entries.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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;
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_MESSAGE:
|
||||
{
|
||||
if(m_log_level_internal > log_messages) {
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
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*/, log_level )
|
||||
{
|
||||
// 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*/, log_level , 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
|
||||
+218
@@ -0,0 +1,218 @@
|
||||
// (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_timed_out )
|
||||
descr = "has timed out";
|
||||
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;
|
||||
}
|
||||
|
||||
// aborted test case within failed ones, timed-out TC exclusive with failed/aborted
|
||||
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 + tr.p_test_cases_timed_out;
|
||||
|
||||
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_timed_out, m_indent, total_tc , "test case", "timed-out" );
|
||||
print_stat_value( ostr, tr.p_test_suites_timed_out, m_indent, tr.p_test_suites, "test suite", "timed-out" );
|
||||
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_timed_out ) {
|
||||
ostr << "*** The test " << tu.p_type_name << ' ' << quote() << tu.full_name() << " has timed out"
|
||||
<< "; 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
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
// (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
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(progress_monitor_t)
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
progress_monitor_t::test_start( counter_t test_cases_amount, test_unit_id )
|
||||
{
|
||||
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
|
||||
+349
@@ -0,0 +1,349 @@
|
||||
// (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
|
||||
/// 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/execution_monitor.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
|
||||
{
|
||||
// if it is skipped, it is not passed. However, if any children is not failed/aborted
|
||||
// then their skipped status is not taken into account.
|
||||
return !p_skipped &&
|
||||
p_test_cases_failed == 0 &&
|
||||
p_assertions_failed <= p_expected_failures &&
|
||||
// p_test_cases_skipped == 0 &&
|
||||
!p_timed_out &&
|
||||
p_test_cases_timed_out == 0 &&
|
||||
!aborted();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
test_results::aborted() const
|
||||
{
|
||||
return p_aborted;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
test_results::skipped() const
|
||||
{
|
||||
return p_skipped;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
int
|
||||
test_results::result_code() const
|
||||
{
|
||||
return passed() ? exit_success
|
||||
: ( (p_assertions_failed > p_expected_failures || p_skipped || p_timed_out || p_test_cases_timed_out )
|
||||
? exit_test_failure
|
||||
: exit_exception_failure );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_results::operator+=( test_results const& tr )
|
||||
{
|
||||
p_test_suites.value += tr.p_test_suites;
|
||||
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_test_cases_timed_out.value += tr.p_test_cases_timed_out;
|
||||
p_test_suites_timed_out.value += tr.p_test_suites_timed_out;
|
||||
p_duration_microseconds.value += tr.p_duration_microseconds;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_results::clear()
|
||||
{
|
||||
p_test_suites.value = 0;
|
||||
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_test_cases_timed_out.value = 0;
|
||||
p_test_suites_timed_out.value = 0;
|
||||
p_duration_microseconds.value= 0;
|
||||
p_aborted.value = false;
|
||||
p_skipped.value = false;
|
||||
p_timed_out.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; }
|
||||
|
||||
// deletes the entries of results_collector_impl
|
||||
class clear_subtree_result : public test_tree_visitor {
|
||||
public:
|
||||
clear_subtree_result(results_collector_impl& store)
|
||||
: m_store( store )
|
||||
{}
|
||||
|
||||
private:
|
||||
bool visit( test_unit const& tu) BOOST_OVERRIDE
|
||||
{
|
||||
typedef std::map<test_unit_id,test_results>::iterator iterator;
|
||||
iterator found = m_store.m_results_store.find(tu.p_id);
|
||||
if(found != m_store.m_results_store.end()) {
|
||||
m_store.m_results_store.erase( found );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
results_collector_impl& m_store;
|
||||
};
|
||||
|
||||
} // local namespace
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL( results_collector_t )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::test_start( counter_t, test_unit_id id )
|
||||
{
|
||||
// deletes the results under id only
|
||||
clear_subtree_result tree_clear(s_rc_impl());
|
||||
traverse_test_tree( id, tree_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 ) BOOST_OVERRIDE
|
||||
{
|
||||
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_timed_out ) {
|
||||
m_tr.p_test_cases_timed_out.value++;
|
||||
}
|
||||
else if( tr.p_skipped || !tc.is_enabled() ) {
|
||||
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 ) BOOST_OVERRIDE
|
||||
{
|
||||
if( m_ts.p_id == ts.p_id )
|
||||
return true;
|
||||
|
||||
m_tr += results_collector.results( ts.p_id );
|
||||
m_tr.p_test_suites.value++;
|
||||
|
||||
if( results_collector.results( ts.p_id ).p_timed_out )
|
||||
m_tr.p_test_suites_timed_out.value++;
|
||||
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 )
|
||||
{
|
||||
test_results & tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
if( tu.p_type == TUT_SUITE ) {
|
||||
results_collect_helper ch( tr, tu );
|
||||
traverse_test_tree( tu, ch, true ); // true to ignore the status: we need to count the skipped/disabled tests
|
||||
}
|
||||
else {
|
||||
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" );
|
||||
}
|
||||
tr.p_duration_microseconds.value = elapsed_in_microseconds;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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(true);
|
||||
traverse_test_tree( tu, tcc, true ); // true because need to count the disabled tests/units
|
||||
|
||||
tr.p_test_cases_skipped.value = tcc.p_count;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::test_unit_timed_out(test_unit const& tu)
|
||||
{
|
||||
test_results& tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
tr.p_timed_out.value = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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& ex)
|
||||
{
|
||||
test_results& tr = s_rc_impl().m_results_store[framework::current_test_case_id()];
|
||||
|
||||
tr.p_assertions_failed.value++;
|
||||
if( ex.code() == execution_exception::timeout_error ) {
|
||||
tr.p_timed_out.value = true;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
+197
@@ -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 facilities
|
||||
// ***************************************************************************
|
||||
|
||||
#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 ) BOOST_OVERRIDE
|
||||
{
|
||||
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 ) BOOST_OVERRIDE
|
||||
{
|
||||
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 ) BOOST_OVERRIDE
|
||||
{
|
||||
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
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
// (c) Copyright Raffi Enficiaud 2017.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//! @file
|
||||
//! An observer for monitoring the success/failure of the other observers
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
#define BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/test_framework_init_observer.hpp>
|
||||
#include <boost/test/framework.hpp>
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** framework_init_observer_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
framework_init_observer_t::clear()
|
||||
{
|
||||
m_has_failure = false;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::test_start( counter_t, test_unit_id )
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::assertion_result( unit_test::assertion_result ar )
|
||||
{
|
||||
switch( ar ) {
|
||||
case AR_FAILED: m_has_failure = true; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::exception_caught( execution_exception const& )
|
||||
{
|
||||
m_has_failure = true;
|
||||
}
|
||||
|
||||
void
|
||||
framework_init_observer_t::test_aborted()
|
||||
{
|
||||
m_has_failure = true;
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
framework_init_observer_t::has_failed() const
|
||||
{
|
||||
return m_has_failure;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
+65
@@ -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
|
||||
+854
@@ -0,0 +1,854 @@
|
||||
// (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/test_tools.hpp>
|
||||
#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 unit_test {
|
||||
// local static variable, needed here for visibility reasons
|
||||
lazy_ostream lazy_ostream::inst = lazy_ostream();
|
||||
}}
|
||||
|
||||
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<wchar_t>::operator()( std::ostream& ostr, wchar_t r )
|
||||
{
|
||||
std::mbstate_t state;
|
||||
std::string mb(MB_CUR_MAX, '\0');
|
||||
std::size_t ret = std::wcrtomb(&mb[0], r, &state);
|
||||
if( ret > 0) {
|
||||
ostr << mb;
|
||||
}
|
||||
else {
|
||||
ostr << "(wchar_t unable to convert)";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 )
|
||||
{
|
||||
if(t) {
|
||||
ostr << static_cast<const void*>(t);
|
||||
}
|
||||
else {
|
||||
ostr << "null w-string";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** TOOL BOX Implementation ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
using ::boost::unit_test::lazy_ostream;
|
||||
|
||||
static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
|
||||
static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
|
||||
|
||||
template<typename OutStream>
|
||||
void
|
||||
format_report( OutStream& os, assertion_result const& pr, unit_test::lazy_ostream const& assertion_descr,
|
||||
tool_level tl, check_type ct,
|
||||
std::size_t num_args, va_list args,
|
||||
char const* prefix, char const* suffix )
|
||||
{
|
||||
using namespace unit_test;
|
||||
|
||||
switch( ct ) {
|
||||
case CHECK_PRED:
|
||||
os << prefix << assertion_descr << suffix;
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
|
||||
case CHECK_BUILT_ASSERTION: {
|
||||
os << prefix << assertion_descr << suffix;
|
||||
|
||||
if( tl != PASS ) {
|
||||
const_string details_message = pr.message();
|
||||
|
||||
if( !details_message.is_empty() ) {
|
||||
os << details_message;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_MSG:
|
||||
if( tl == PASS )
|
||||
os << prefix << "'" << assertion_descr << "'" << suffix;
|
||||
else
|
||||
os << assertion_descr;
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
|
||||
case CHECK_EQUAL:
|
||||
case CHECK_NE:
|
||||
case CHECK_LT:
|
||||
case CHECK_LE:
|
||||
case CHECK_GT:
|
||||
case CHECK_GE: {
|
||||
char const* arg1_descr = va_arg( args, char const* );
|
||||
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
|
||||
char const* arg2_descr = va_arg( args, char const* );
|
||||
lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
|
||||
|
||||
os << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
|
||||
|
||||
if( tl != PASS )
|
||||
os << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_CLOSE:
|
||||
case CHECK_CLOSE_FRACTION: {
|
||||
char const* arg1_descr = va_arg( args, char const* );
|
||||
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
|
||||
char const* arg2_descr = va_arg( args, char const* );
|
||||
lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
|
||||
/* toler_descr = */ va_arg( args, char const* );
|
||||
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
|
||||
|
||||
os << "difference{" << pr.message()
|
||||
<< "} between " << arg1_descr << "{" << *arg1_val
|
||||
<< "} and " << arg2_descr << "{" << *arg2_val
|
||||
<< ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
|
||||
<< *toler_val;
|
||||
if( ct == CHECK_CLOSE )
|
||||
os << "%";
|
||||
break;
|
||||
}
|
||||
case CHECK_SMALL: {
|
||||
char const* arg1_descr = va_arg( args, char const* );
|
||||
lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
|
||||
/* toler_descr = */ va_arg( args, char const* );
|
||||
lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
|
||||
|
||||
os << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
|
||||
<< ( tl == PASS ? " doesn't exceed " : " exceeds " )
|
||||
<< *toler_val;
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_PRED_WITH_ARGS: {
|
||||
std::vector< std::pair<char const*, lazy_ostream const*> > args_copy;
|
||||
args_copy.reserve( num_args );
|
||||
for( std::size_t i = 0; i < num_args; ++i ) {
|
||||
char const* desc = va_arg( args, char const* );
|
||||
lazy_ostream const* value = va_arg( args, lazy_ostream const* );
|
||||
args_copy.push_back( std::make_pair( desc, value ) );
|
||||
}
|
||||
|
||||
os << prefix << assertion_descr;
|
||||
|
||||
// print predicate call description
|
||||
os << "( ";
|
||||
for( std::size_t i = 0; i < num_args; ++i ) {
|
||||
os << args_copy[i].first;
|
||||
|
||||
if( i != num_args-1 )
|
||||
os << ", ";
|
||||
}
|
||||
os << " )" << suffix;
|
||||
|
||||
if( tl != PASS ) {
|
||||
os << " for ( ";
|
||||
for( std::size_t i = 0; i < num_args; ++i ) {
|
||||
os << *args_copy[i].second;
|
||||
|
||||
if( i != num_args-1 )
|
||||
os << ", ";
|
||||
}
|
||||
os << " )";
|
||||
}
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_EQUAL_COLL: {
|
||||
char const* left_begin_descr = va_arg( args, char const* );
|
||||
char const* left_end_descr = va_arg( args, char const* );
|
||||
char const* right_begin_descr = va_arg( args, char const* );
|
||||
char const* right_end_descr = va_arg( args, char const* );
|
||||
|
||||
os << prefix << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
|
||||
<< right_begin_descr << ", " << right_end_descr << " }"
|
||||
<< suffix;
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
}
|
||||
|
||||
case CHECK_BITWISE_EQUAL: {
|
||||
char const* left_descr = va_arg( args, char const* );
|
||||
char const* right_descr = va_arg( args, char const* );
|
||||
|
||||
os << prefix << left_descr << " =.= " << right_descr << suffix;
|
||||
|
||||
if( !pr.has_empty_message() )
|
||||
os << ". " << pr.message();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
report_assertion( assertion_result const& ar,
|
||||
lazy_ostream const& assertion_descr,
|
||||
const_string file_name,
|
||||
std::size_t line_num,
|
||||
tool_level tl,
|
||||
check_type ct,
|
||||
std::size_t num_args, ... )
|
||||
{
|
||||
using namespace unit_test;
|
||||
|
||||
if( !framework::test_in_progress() ) {
|
||||
// in case no test is in progress, we do not throw anything:
|
||||
// raising an exception here may result in raising an exception in a destructor of a global fixture
|
||||
// which will abort the process
|
||||
// We flag this as aborted instead
|
||||
|
||||
//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." ) );
|
||||
|
||||
framework::test_aborted();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
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_unit() );
|
||||
BOOST_TEST_I_THROW( execution_aborted() );
|
||||
// the previous line either throws or aborts and the return below is not reached
|
||||
// return false;
|
||||
BOOST_TEST_UNREACHABLE_RETURN(false);
|
||||
}
|
||||
|
||||
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 = 0;
|
||||
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 matching 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() << ' ';
|
||||
}
|
||||
|
||||
result.message() << '~'; // places the first tilde at the current char that mismatches
|
||||
|
||||
for( std::size_t k = 1; 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 = static_cast<int>((std::max)(s1.size(), s2.size())); h > 0; h--)
|
||||
result.message() << "~";
|
||||
}
|
||||
|
||||
if( m_pimpl->m_pattern.eof() ) {
|
||||
result.message() << " (reference string shorter than current stream)";
|
||||
}
|
||||
|
||||
result.message() << "\n";
|
||||
|
||||
// no need to continue if the EOF is reached
|
||||
if( m_pimpl->m_pattern.eof() ) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 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
|
||||
+584
@@ -0,0 +1,584 @@
|
||||
// (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>
|
||||
|
||||
// STL
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#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() << (test_rslt.skipped() ? "\" was skipped":"\" 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( ut_detail::normalize_test_case_name( 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_t& decorators )
|
||||
{
|
||||
test_unit* tu;
|
||||
while((tu = gen.next()) != 0) {
|
||||
decorators.store_in( *tu );
|
||||
add( tu, 0 );
|
||||
}
|
||||
decorators.reset();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::add( boost::shared_ptr<test_unit_generator> gen_ptr, decorator::collector_t& decorators )
|
||||
{
|
||||
std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > tmp_p(gen_ptr, decorators.get_lazy_decorators() );
|
||||
m_generators.push_back(tmp_p);
|
||||
decorators.reset();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::generate( )
|
||||
{
|
||||
typedef std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > element_t;
|
||||
|
||||
for(std::vector<element_t>::iterator it(m_generators.begin()), ite(m_generators.end());
|
||||
it < ite;
|
||||
++it)
|
||||
{
|
||||
test_unit* tu;
|
||||
while((tu = it->first->next()) != 0) {
|
||||
tu->p_decorators.value.insert( tu->p_decorators.value.end(), it->second.begin(), it->second.end() );
|
||||
//it->second.store_in( *tu );
|
||||
add( tu, 0 );
|
||||
}
|
||||
|
||||
}
|
||||
m_generators.clear();
|
||||
|
||||
#if 0
|
||||
test_unit* tu;
|
||||
while((tu = gen.next()) != 0) {
|
||||
decorators.store_in( *tu );
|
||||
add( tu, 0 );
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::check_for_duplicate_test_cases() {
|
||||
// check for clashing names #12597
|
||||
std::set<std::string> names;
|
||||
for( test_unit_id_list::const_iterator it(m_children.begin()), ite(m_children.end());
|
||||
it < ite;
|
||||
++it) {
|
||||
std::string name = framework::get(*it, TUT_ANY).p_name;
|
||||
std::pair<std::set<std::string>::iterator, bool> ret = names.insert(name);
|
||||
BOOST_TEST_SETUP_ASSERT(ret.second,
|
||||
"test unit with name '"
|
||||
+ name
|
||||
+ std::string("' registered multiple times in the test suite '")
|
||||
+ this->p_name.value
|
||||
+ "'");
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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.end() );
|
||||
|
||||
if( name[0] == '&' )
|
||||
norm_name = norm_name.substr( 1 );
|
||||
|
||||
// trim spaces
|
||||
std::size_t first_not_space = norm_name.find_first_not_of(' ');
|
||||
if( first_not_space ) {
|
||||
norm_name.erase(0, first_not_space);
|
||||
}
|
||||
|
||||
std::size_t last_not_space = norm_name.find_last_not_of(' ');
|
||||
if( last_not_space !=std::string::npos ) {
|
||||
norm_name.erase(last_not_space + 1);
|
||||
}
|
||||
|
||||
// sanitize all chars that might be used in runtime filters
|
||||
static const char to_replace[] = { ':', '*', '@', '+', '!', '/', ',' };
|
||||
for(std::size_t index = 0;
|
||||
index < sizeof(to_replace)/sizeof(to_replace[0]);
|
||||
index++) {
|
||||
std::replace(norm_name.begin(), norm_name.end(), to_replace[index], '_');
|
||||
}
|
||||
|
||||
return norm_name;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** auto_test_unit_registrar ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector_t& 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_t& 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_t& decorators )
|
||||
{
|
||||
framework::current_auto_test_suite().add( tc_gen, decorators );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( boost::shared_ptr<test_unit_generator> tc_gen, decorator::collector_t& 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(): registered(false)
|
||||
{
|
||||
framework::register_global_fixture( *this );
|
||||
registered = true;
|
||||
}
|
||||
|
||||
void global_fixture::unregister_from_framework() {
|
||||
// not accessing the framework singleton after deregistering -> release
|
||||
// of the observer from the framework
|
||||
if(registered) {
|
||||
framework::deregister_global_fixture( *this );
|
||||
}
|
||||
registered = false;
|
||||
}
|
||||
|
||||
global_fixture::~global_fixture()
|
||||
{
|
||||
this->unregister_from_framework();
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** global_configuration ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
global_configuration::global_configuration(): registered(false)
|
||||
{
|
||||
framework::register_observer( *this );
|
||||
registered = true;
|
||||
}
|
||||
|
||||
void global_configuration::unregister_from_framework()
|
||||
{
|
||||
// not accessing the framework singleton after deregistering -> release
|
||||
// of the observer from the framework
|
||||
if(registered) {
|
||||
framework::deregister_observer( *this );
|
||||
}
|
||||
registered = false;
|
||||
}
|
||||
|
||||
global_configuration::~global_configuration()
|
||||
{
|
||||
this->unregister_from_framework();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_UNIT_TEST_SUITE_IPP_012205GER
|
||||
+787
@@ -0,0 +1,787 @@
|
||||
// (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;
|
||||
|
||||
typedef std::vector<unit_test_log_data_helper_impl*> vp_formatter_data_t;
|
||||
vp_formatter_data_t m_active_log_formatter_data;
|
||||
|
||||
// entry data
|
||||
log_entry_data m_entry_data;
|
||||
|
||||
bool has_entry_in_progress() const {
|
||||
for( vp_formatter_data_t::const_iterator it(m_active_log_formatter_data.begin()), ite(m_active_log_formatter_data.end());
|
||||
it < ite;
|
||||
++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
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; }
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
log_entry_context( log_level l, unit_test_log_data_helper_impl& current_logger_data)
|
||||
{
|
||||
framework::context_generator const& context = framework::get_context();
|
||||
if( context.is_empty() )
|
||||
return;
|
||||
|
||||
const_string frame;
|
||||
current_logger_data.m_log_formatter->entry_context_start( current_logger_data.stream(), l );
|
||||
while( !(frame=context.next()).is_empty() )
|
||||
{
|
||||
current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), l, frame );
|
||||
}
|
||||
current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream(), l );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
clear_entry_context()
|
||||
{
|
||||
framework::clear_context();
|
||||
}
|
||||
|
||||
// convenience
|
||||
typedef unit_test_log_impl::vp_formatter_data_t vp_logger_t;
|
||||
typedef unit_test_log_impl::v_formatter_data_t v_logger_t;
|
||||
|
||||
} // local namespace
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL( unit_test_log_t )
|
||||
|
||||
void
|
||||
unit_test_log_t::configure( )
|
||||
{
|
||||
// configure is not test_start:
|
||||
// test_start pushes the necessary log information when the test module is starting, and implies configure.
|
||||
// configure: should be called each time the set of loggers, stream or configuration is changed.
|
||||
s_log_impl().m_active_log_formatter_data.clear();
|
||||
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 || it->get_log_level() == log_nothing )
|
||||
continue;
|
||||
|
||||
s_log_impl().m_active_log_formatter_data.push_back(&*it);
|
||||
it->m_entry_in_progress = false;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_start( counter_t test_cases_amount, test_unit_id )
|
||||
{
|
||||
configure();
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
|
||||
current_logger_data.m_log_formatter->log_start( current_logger_data.stream(), test_cases_amount );
|
||||
current_logger_data.m_log_formatter->log_build_info(
|
||||
current_logger_data.stream(),
|
||||
runtime_config::get<bool>( runtime_config::btrt_build_info ));
|
||||
|
||||
//current_logger_data.stream().flush();
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_finish()
|
||||
{
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
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();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( 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();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( 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();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( 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();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( 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::test_unit_timed_out( test_unit const& tu )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
*this << log::end();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->test_unit_timed_out(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();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
|
||||
if( 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 );
|
||||
|
||||
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();
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
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() ) {
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
log_level l = s_log_impl().m_entry_data.m_level;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( current_logger_data.m_entry_in_progress ) {
|
||||
if( l >= current_logger_data.get_log_level() ) {
|
||||
log_entry_context( l, current_logger_data );
|
||||
}
|
||||
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
|
||||
log_entry_start(unit_test_log_data_helper_impl ¤t_logger_data)
|
||||
{
|
||||
if( current_logger_data.m_entry_in_progress )
|
||||
return true;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
unit_test_log_t&
|
||||
unit_test_log_t::operator<<( const_string value )
|
||||
{
|
||||
if(value.empty()) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() )
|
||||
if( log_entry_start(current_logger_data) ) {
|
||||
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 )
|
||||
{
|
||||
if(value.empty()) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
vp_logger_t& vloggers = s_log_impl().m_active_log_formatter_data;
|
||||
for( vp_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = **it;
|
||||
if( s_log_impl().m_entry_data.m_level >= current_logger_data.get_log_level() ) {
|
||||
if( log_entry_start(current_logger_data) ) {
|
||||
current_logger_data.m_log_formatter->log_entry_value( current_logger_data.stream(), value );
|
||||
}
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::set_stream( std::ostream& str )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
|
||||
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;
|
||||
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream*
|
||||
unit_test_log_t::get_stream( output_format log_format ) const
|
||||
{
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
return current_logger_data.m_stream;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
log_level
|
||||
unit_test_log_t::set_threshold_level( log_level lev )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() || lev == invalid_log_level )
|
||||
return invalid_log_level;
|
||||
|
||||
log_level ret = log_nothing;
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
ret = (std::min)(ret, current_logger_data.m_log_formatter->get_log_level());
|
||||
current_logger_data.m_log_formatter->set_log_level( lev );
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
log_level
|
||||
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 invalid_log_level;
|
||||
|
||||
log_level ret = log_nothing;
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
ret = current_logger_data.m_log_formatter->get_log_level();
|
||||
current_logger_data.m_log_formatter->set_log_level( lev );
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::set_format( output_format log_format )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
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;
|
||||
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
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 ) {
|
||||
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for( v_logger_t::iterator it(vloggers.begin()), ite(vloggers.end()); it < ite; ++it)
|
||||
{
|
||||
unit_test_log_data_helper_impl& current_logger_data = *it;
|
||||
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
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for(v_logger_t::iterator it(vloggers.begin()), ite(vloggers.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_active_log_formatter_data.clear(); // otherwise dandling references
|
||||
vloggers.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 )
|
||||
{
|
||||
if( s_log_impl().has_entry_in_progress() )
|
||||
return;
|
||||
|
||||
// remove only user defined logger
|
||||
log_level current_level = invalid_log_level;
|
||||
std::ostream *current_stream = 0;
|
||||
output_format previous_format = OF_INVALID;
|
||||
v_logger_t& vloggers = s_log_impl().m_log_formatter_data;
|
||||
for(v_logger_t::iterator it(vloggers.begin()), ite(vloggers.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);
|
||||
}
|
||||
|
||||
configure();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** 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
|
||||
|
||||
+315
@@ -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 : $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/core/ignore_unused.hpp>
|
||||
#include <boost/cstdlib.hpp>
|
||||
|
||||
// STL
|
||||
#include <cstdio>
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#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";
|
||||
}
|
||||
void visit( test_case const& tc ) BOOST_OVERRIDE { report_test_unit( tc ); }
|
||||
bool test_suite_start( test_suite const& ts ) BOOST_OVERRIDE
|
||||
{
|
||||
if( m_indent >= 0 )
|
||||
report_test_unit( ts );
|
||||
m_indent += 4;
|
||||
return true;
|
||||
}
|
||||
void test_suite_finish( test_suite const& ) BOOST_OVERRIDE
|
||||
{
|
||||
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";
|
||||
}
|
||||
|
||||
}
|
||||
void visit( test_case const& tc ) BOOST_OVERRIDE
|
||||
{
|
||||
report_test_unit( tc );
|
||||
}
|
||||
bool test_suite_start( test_suite const& ts ) BOOST_OVERRIDE
|
||||
{
|
||||
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;
|
||||
}
|
||||
void test_suite_finish( test_suite const& ts ) BOOST_OVERRIDE
|
||||
{
|
||||
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:
|
||||
bool visit( test_unit const& tu ) BOOST_OVERRIDE
|
||||
{
|
||||
m_labels.insert( tu.p_labels->begin(), tu.p_labels->end() );
|
||||
return true;
|
||||
}
|
||||
|
||||
// Data members
|
||||
std::set<std::string> m_labels;
|
||||
};
|
||||
|
||||
struct framework_shutdown_helper {
|
||||
~framework_shutdown_helper() {
|
||||
try {
|
||||
framework::shutdown();
|
||||
}
|
||||
catch(...) {
|
||||
std::cerr << "Boost.Test shutdown exception caught" << std::endl;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // 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;
|
||||
|
||||
ut_detail::framework_shutdown_helper shutdown_helper;
|
||||
boost::ignore_unused(shutdown_helper);
|
||||
|
||||
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();
|
||||
|
||||
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_CATCH( std::logic_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;
|
||||
}
|
||||
|
||||
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
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
// (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 {
|
||||
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(unit_test_monitor_t)
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** unit_test_monitor ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
unit_test_monitor_t::error_level
|
||||
unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func, unsigned long int timeout_microseconds )
|
||||
{
|
||||
BOOST_TEST_I_TRY {
|
||||
p_catch_system_errors.value = runtime_config::get<bool>( runtime_config::btrt_catch_sys_errors );
|
||||
p_timeout.value = timeout_microseconds;
|
||||
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_unit() );
|
||||
|
||||
// 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
|
||||
+771
@@ -0,0 +1,771 @@
|
||||
// (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/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 = "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 = "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::default_value = true,
|
||||
rt::help = "Produces color output for logs, reports and help. "
|
||||
"Defaults to true. "
|
||||
));
|
||||
|
||||
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 = "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 = "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 = "Lists the test suites and cases "
|
||||
"of the test module instead of executing the test cases. The format of the "
|
||||
"desired output can be passed to the command. 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 = "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 the logging level of the test execution.",
|
||||
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 = "Set the framework's log level. "
|
||||
"The log level defines the verbosity of the testing logs produced by a test "
|
||||
"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 = "Sets the log sink - the location "
|
||||
"where Boost.Test writes the logs of the test execution. 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 = "Combines an effect of " + btrt_report_format +
|
||||
" and " + btrt_log_format + " parameters. 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[:log_format,log_level,log_sink]",
|
||||
rt::help = "Specify one or more logging definition, which include the logger type, level and sink. "
|
||||
"The log format, level and sink follow the same format as for the argument '--" + btrt_log_format +
|
||||
"', '--" + btrt_log_level + "' and '--" + btrt_log_sink + "' respetively. "
|
||||
"This command can take several logging definition separated by a ':', or be repeated "
|
||||
"on the command line."
|
||||
));
|
||||
|
||||
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 = "Instructs the framework to execute the "
|
||||
"test cases in random order. This parameter accepts an optional unsigned "
|
||||
"integer argument. 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. "
|
||||
"By default, the test cases are executed in an "
|
||||
"order defined by their declaration and the optional dependencies among the test units."
|
||||
));
|
||||
|
||||
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 the test 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 = "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 test 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 = "Set the verbosity level of the "
|
||||
"result report generated by the testing framework. Use value 'no' to "
|
||||
"disable 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 = "Sets the result report sink - "
|
||||
"the location where the framework writes the result report to. "
|
||||
"The sink may be a a file or a standard "
|
||||
"stream. The default is 'stderr': 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 tests to execute.",
|
||||
rt::env_var = "BOOST_TEST_RUN_FILTERS",
|
||||
rt::value_hint = "<test unit filter>",
|
||||
rt::help = "Filters which test units to execute. "
|
||||
"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. Boost.test 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 = "Instructs the framework to display the progress of the tests. "
|
||||
"This feature is turned off by default."
|
||||
));
|
||||
|
||||
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 = "Instructs the framework to use an alternative "
|
||||
"stack for operating system's signals handling (on platforms where this is supported). "
|
||||
"The feature is enabled by default, but can be disabled using this command line switch."
|
||||
));
|
||||
|
||||
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 = "Instructs the framework to pause before starting "
|
||||
"test units execution, so that you can attach a debugger to the test module process. "
|
||||
"This feature is turned off by default."
|
||||
));
|
||||
|
||||
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 = "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 );
|
||||
|
||||
// check if colorized output is enabled
|
||||
bool use_color = true;
|
||||
if( s_arguments_store.has(btrt_color_output ) ) {
|
||||
use_color = runtime_config::get<bool>(runtime_config::btrt_color_output);
|
||||
}
|
||||
|
||||
// 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, runtime::cstring(), use_color );
|
||||
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 ),
|
||||
use_color );
|
||||
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
|
||||
+225
@@ -0,0 +1,225 @@
|
||||
// (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, bool log_build_info )
|
||||
{
|
||||
if( log_build_info ) {
|
||||
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.get()
|
||||
<< " 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, log_level )
|
||||
{
|
||||
ostr << BOOST_TEST_L( "</Context>" );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::log_entry_context( std::ostream& ostr, log_level, 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
|
||||
+117
@@ -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 : $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_timed_out )
|
||||
descr = "timed-out";
|
||||
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
|
||||
<< " test_cases_timed_out" << utils::attr_value() << tr.p_test_cases_timed_out
|
||||
<< " test_suites_timed_out"<< utils::attr_value() << tr.p_test_suites_timed_out
|
||||
;
|
||||
}
|
||||
|
||||
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
|
||||
+21
@@ -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
|
||||
+25
@@ -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
|
||||
+40
@@ -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 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_framework_init_observer.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
|
||||
+40
@@ -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 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_framework_init_observer.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>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
#endif // BOOST_INCLUDED_UNIT_TEST_FRAMEWORK_HPP_071894GER
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
// (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/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/included/unit_test.hpp>" )
|
||||
|
||||
|
||||
#include <boost/test/included/unit_test.hpp>
|
||||
+162
@@ -0,0 +1,162 @@
|
||||
// (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
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/included/unit_test.hpp>" )
|
||||
#if defined(BOOST_ALLOW_DEPRECATED_HEADERS)
|
||||
BOOST_PRAGMA_MESSAGE( "Boost.Test minimal is deprecated. Please convert to the header only variant of Boost.Test." )
|
||||
#endif
|
||||
|
||||
#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
|
||||
+73
@@ -0,0 +1,73 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
/// @file
|
||||
/// @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/utils/setcolor.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 ), m_color_state() {}
|
||||
|
||||
// Formatter interface
|
||||
void log_start( std::ostream&, counter_t test_cases_amount ) BOOST_OVERRIDE;
|
||||
void log_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
void log_build_info( std::ostream&, bool ) BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_start( std::ostream&, test_unit const& tu ) BOOST_OVERRIDE;
|
||||
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) BOOST_OVERRIDE;
|
||||
void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason ) BOOST_OVERRIDE;
|
||||
|
||||
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex ) BOOST_OVERRIDE;
|
||||
void log_exception_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
|
||||
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) BOOST_OVERRIDE;
|
||||
void log_entry_value( std::ostream&, const_string value ) BOOST_OVERRIDE;
|
||||
void log_entry_value( std::ostream&, lazy_ostream const& value ) BOOST_OVERRIDE;
|
||||
void log_entry_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
|
||||
void entry_context_start( std::ostream&, log_level ) BOOST_OVERRIDE;
|
||||
void log_entry_context( std::ostream&, log_level l, const_string ) BOOST_OVERRIDE;
|
||||
void entry_context_finish( std::ostream&, log_level l ) BOOST_OVERRIDE;
|
||||
|
||||
protected:
|
||||
virtual void print_prefix( std::ostream&, const_string file, std::size_t line );
|
||||
|
||||
// Data members
|
||||
bool m_color_output;
|
||||
utils::setcolor::state m_color_state;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_COMPILER_LOG_FORMATTER_HPP_020105GER
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
// (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 ) BOOST_OVERRIDE;
|
||||
void log_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
void log_build_info( std::ostream&, bool ) BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_start( std::ostream&, test_unit const& tu ) BOOST_OVERRIDE;
|
||||
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) BOOST_OVERRIDE;
|
||||
void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason ) BOOST_OVERRIDE;
|
||||
void test_unit_aborted( std::ostream& os, test_unit const& tu ) BOOST_OVERRIDE;
|
||||
void test_unit_timed_out( std::ostream& os, test_unit const& tu) BOOST_OVERRIDE;
|
||||
|
||||
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex ) BOOST_OVERRIDE;
|
||||
void log_exception_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
|
||||
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) BOOST_OVERRIDE;
|
||||
|
||||
using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
|
||||
void log_entry_value( std::ostream&, const_string value ) BOOST_OVERRIDE;
|
||||
void log_entry_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
|
||||
void entry_context_start( std::ostream&, log_level ) BOOST_OVERRIDE;
|
||||
void log_entry_context( std::ostream&, log_level, const_string ) BOOST_OVERRIDE;
|
||||
void entry_context_finish( std::ostream&, log_level ) BOOST_OVERRIDE;
|
||||
|
||||
//! Discards changes in the log level
|
||||
void set_log_level(log_level ll) BOOST_OVERRIDE
|
||||
{
|
||||
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.
|
||||
std::string get_default_stream_description() const BOOST_OVERRIDE;
|
||||
|
||||
|
||||
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__
|
||||
+59
@@ -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 ) BOOST_OVERRIDE;
|
||||
void results_report_finish( std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_report_start( test_unit const&, std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
void test_unit_report_finish( test_unit const&, std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
|
||||
void do_confirmation_report( test_unit const&, std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
|
||||
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
|
||||
+72
@@ -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 ) BOOST_OVERRIDE;
|
||||
void log_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
void log_build_info( std::ostream&, bool ) BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_start( std::ostream&, test_unit const& tu ) BOOST_OVERRIDE;
|
||||
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed ) BOOST_OVERRIDE;
|
||||
void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason ) BOOST_OVERRIDE;
|
||||
|
||||
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex ) BOOST_OVERRIDE;
|
||||
void log_exception_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
|
||||
void log_entry_start( std::ostream&, log_entry_data const&, log_entry_types let ) BOOST_OVERRIDE;
|
||||
using unit_test_log_formatter::log_entry_value; // bring base class functions into overload set
|
||||
void log_entry_value( std::ostream&, const_string value ) BOOST_OVERRIDE;
|
||||
void log_entry_finish( std::ostream& ) BOOST_OVERRIDE;
|
||||
|
||||
void entry_context_start( std::ostream&, log_level ) BOOST_OVERRIDE;
|
||||
void log_entry_context( std::ostream&, log_level, const_string ) BOOST_OVERRIDE;
|
||||
void entry_context_finish( std::ostream&, log_level ) BOOST_OVERRIDE;
|
||||
|
||||
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
|
||||
+52
@@ -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 ) BOOST_OVERRIDE;
|
||||
void results_report_finish( std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_report_start( test_unit const&, std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
void test_unit_report_finish( test_unit const&, std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
|
||||
void do_confirmation_report( test_unit const&, std::ostream& ostr ) BOOST_OVERRIDE;
|
||||
};
|
||||
|
||||
} // namespace output
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_XML_REPORT_FORMATTER_HPP_020105GER
|
||||
+18
@@ -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 boost/test/tools/output_test_stream.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/tools/output_test_stream.hpp>" )
|
||||
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/output_test_stream.hpp>
|
||||
+176
@@ -0,0 +1,176 @@
|
||||
// (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>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
|
||||
#include <boost/bind/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 )
|
||||
, m_index( 0 )
|
||||
{}
|
||||
|
||||
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 + "_" + utils::string_cast(m_index), m_tc_file, m_tc_line, boost::bind( m_test_func, *m_par_begin ) );
|
||||
|
||||
++m_par_begin;
|
||||
++m_index;
|
||||
|
||||
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;
|
||||
mutable std::size_t m_index;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
|
||||
+18
@@ -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 boost/test/tools/assertion_result.hpp instead
|
||||
// ***************************************************************************
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/tools/assertion_result.hpp>" )
|
||||
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/assertion_result.hpp>
|
||||
+81
@@ -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
|
||||
+65
@@ -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
|
||||
/// @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>
|
||||
|
||||
// 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:
|
||||
/// @name Test observer interface
|
||||
/// @{
|
||||
void test_start( counter_t test_cases_amount, test_unit_id ) BOOST_OVERRIDE;
|
||||
void test_aborted() BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_finish( test_unit const&, unsigned long ) BOOST_OVERRIDE;
|
||||
void test_unit_skipped( test_unit const&, const_string ) BOOST_OVERRIDE;
|
||||
|
||||
int priority() BOOST_OVERRIDE { return 4; }
|
||||
/// @}
|
||||
|
||||
/// @name Configuration
|
||||
/// @{
|
||||
void set_stream( std::ostream& );
|
||||
/// @}
|
||||
|
||||
/// Singleton pattern
|
||||
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
|
||||
|
||||
+153
@@ -0,0 +1,153 @@
|
||||
// (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/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_test_suites; //!< Number of test suites
|
||||
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_test_cases_timed_out; //!< Number of timed out test cases
|
||||
counter_prop p_test_suites_timed_out; //!< Number of timed out test suites
|
||||
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
|
||||
bool_prop p_timed_out; //!< Indicates that the test unit has timed out
|
||||
|
||||
/// Returns true if test unit passed
|
||||
bool passed() const;
|
||||
|
||||
/// Returns true if test unit skipped
|
||||
///
|
||||
/// For test suites, this indicates if the test suite itself has been marked as
|
||||
/// skipped, and not if the test suite contains any skipped test.
|
||||
bool skipped() const;
|
||||
|
||||
/// Returns true if the test unit was aborted (hard failure)
|
||||
bool aborted() 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 (including 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:
|
||||
|
||||
void test_start( counter_t, test_unit_id ) BOOST_OVERRIDE;
|
||||
|
||||
void test_unit_start( test_unit const& ) BOOST_OVERRIDE;
|
||||
void test_unit_finish( test_unit const&, unsigned long ) BOOST_OVERRIDE;
|
||||
void test_unit_skipped( test_unit const&, const_string ) BOOST_OVERRIDE;
|
||||
void test_unit_aborted( test_unit const& ) BOOST_OVERRIDE;
|
||||
void test_unit_timed_out( test_unit const& ) BOOST_OVERRIDE;
|
||||
|
||||
void assertion_result( unit_test::assertion_result ) BOOST_OVERRIDE;
|
||||
void exception_caught( execution_exception const& ) BOOST_OVERRIDE;
|
||||
|
||||
int priority() BOOST_OVERRIDE { return 3; }
|
||||
|
||||
/// Results access per test unit
|
||||
///
|
||||
/// @param[in] tu_id id of a test unit
|
||||
test_results const& results( test_unit_id tu_id ) const;
|
||||
|
||||
/// Singleton pattern
|
||||
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
|
||||
+122
@@ -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
|
||||
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
// (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/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "<boost/test/unit_test.hpp>" )
|
||||
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
+53
@@ -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
|
||||
+61
@@ -0,0 +1,61 @@
|
||||
// (c) Copyright Raffi Enficiaud 2017.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt 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 an observer that monitors the init of the unit test framework
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_FRAMEWORK_INIT_OBSERVER_HPP_071894GER
|
||||
#define BOOST_TEST_FRAMEWORK_INIT_OBSERVER_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/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
// ************************************************************************** //
|
||||
/// @brief Monitors the init of the framework
|
||||
///
|
||||
/// This class collects the state of the init/termination of the unit test framework.
|
||||
///
|
||||
/// @see boost::unit_test::test_observer
|
||||
class BOOST_TEST_DECL framework_init_observer_t : public test_observer {
|
||||
public:
|
||||
|
||||
framework_init_observer_t(): m_has_failure( false ) {}
|
||||
|
||||
void test_start( counter_t, test_unit_id ) BOOST_OVERRIDE;
|
||||
|
||||
void assertion_result( unit_test::assertion_result ) BOOST_OVERRIDE;
|
||||
void exception_caught( execution_exception const& ) BOOST_OVERRIDE;
|
||||
void test_aborted() BOOST_OVERRIDE;
|
||||
|
||||
int priority() BOOST_OVERRIDE { return 0; }
|
||||
|
||||
void clear();
|
||||
|
||||
/// Indicates if a failure has been recorded so far
|
||||
bool has_failed( ) const;
|
||||
|
||||
private:
|
||||
bool m_has_failure;
|
||||
};
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_FRAMEWORK_INIT_OBSERVER_HPP_071894GER
|
||||
+68
@@ -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
|
||||
+424
@@ -0,0 +1,424 @@
|
||||
// (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, >=, GE ) \
|
||||
action( <=, LE, > , GT ) \
|
||||
action( > , GT, <=, LE ) \
|
||||
action( >=, GE, < , LT ) \
|
||||
action( ==, EQ, !=, NE ) \
|
||||
action( !=, NE, ==, EQ ) \
|
||||
/**/
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#ifndef BOOST_NO_CXX11_DECLTYPE
|
||||
|
||||
#define BOOST_TEST_FOR_EACH_CONST_OP(action)\
|
||||
action(->*, MEMP, ->*, MEMP ) \
|
||||
\
|
||||
action( * , MUL , * , MUL ) \
|
||||
action( / , DIV , / , DIV ) \
|
||||
action( % , MOD , % , MOD ) \
|
||||
\
|
||||
action( + , ADD , + , ADD ) \
|
||||
action( - , SUB , - , SUB ) \
|
||||
\
|
||||
action( <<, LSH , << , LSH ) \
|
||||
action( >>, RSH , >> , RSH ) \
|
||||
\
|
||||
BOOST_TEST_FOR_EACH_COMP_OP(action) \
|
||||
\
|
||||
action( & , BAND, & , BAND ) \
|
||||
action( ^ , XOR , ^ , XOR ) \
|
||||
action( | , BOR , | , 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 , = , SET ) \
|
||||
action( +=, IADD, += , IADD ) \
|
||||
action( -=, ISUB, -= , ISUB ) \
|
||||
action( *=, IMUL, *= , IMUL ) \
|
||||
action( /=, IDIV, /= , IDIV ) \
|
||||
action( %=, IMOD, %= , IMOD ) \
|
||||
action(<<=, ILSH, <<=, ILSH ) \
|
||||
action(>>=, IRSH, >>=, IRSH ) \
|
||||
action( &=, IAND, &= , IAND ) \
|
||||
action( ^=, IXOR, ^= , IXOR ) \
|
||||
action( |=, IOR , |= , 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_FWD_DECL( oper, name, rev, name_inverse ) \
|
||||
template<typename Lhs, typename Rhs, \
|
||||
typename Enabler=void> \
|
||||
struct name; \
|
||||
/**/
|
||||
|
||||
BOOST_TEST_FOR_EACH_CONST_OP( DEFINE_CONST_OPER_FWD_DECL )
|
||||
|
||||
#define DEFINE_CONST_OPER( oper, name, rev, name_inverse ) \
|
||||
template<typename Lhs, typename Rhs, \
|
||||
typename Enabler> \
|
||||
struct name { \
|
||||
typedef DEDUCE_RESULT_TYPE( oper ) result_type; \
|
||||
typedef name_inverse<Lhs, Rhs> inverse; \
|
||||
\
|
||||
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* forward() \
|
||||
{ return " " #oper " "; } \
|
||||
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, _, _i ) \
|
||||
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, _, _i ) \
|
||||
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( value() );
|
||||
}
|
||||
|
||||
// Mutating operators
|
||||
#define ADD_OP_SUPPORT( OPER, ID, _, _i)\
|
||||
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 << "['" << tt_detail::print_helper(v) << "' evaluates to 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
|
||||
+90
@@ -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
|
||||
+458
@@ -0,0 +1,458 @@
|
||||
// (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/mpl/if.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_ {};
|
||||
|
||||
template <typename T>
|
||||
struct is_c_array : public mpl::false_ {};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct is_c_array<T [N]> : public mpl::true_ {};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct is_c_array<T (&)[N]> : public mpl::true_ {};
|
||||
|
||||
#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_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 )
|
||||
{
|
||||
assertion_result ar( true );
|
||||
|
||||
typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator;
|
||||
typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator;
|
||||
|
||||
typename t_Lhs_iterator::const_iterator first1 = t_Lhs_iterator::begin(lhs);
|
||||
typename t_Rhs_iterator::const_iterator first2 = t_Rhs_iterator::begin(rhs);
|
||||
typename t_Lhs_iterator::const_iterator last1 = t_Lhs_iterator::end(lhs);
|
||||
typename t_Rhs_iterator::const_iterator last2 = t_Rhs_iterator::end(rhs);
|
||||
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 << ":";
|
||||
ar.message() << "\n - condition [" << tt_detail::print_helper(*first1) << OP::forward() << tt_detail::print_helper(*first2) << "] is false";
|
||||
if(!element_ar.has_empty_message())
|
||||
ar.message() << ": " << element_ar.message();
|
||||
ar.message() << "\n - inverse condition [" << tt_detail::print_helper(*first2) << OP::forward() << tt_detail::print_helper(*first1) << "] is true";
|
||||
if(!reverse_ar.has_empty_message())
|
||||
ar.message() << ": " << reverse_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_cstring<Lhs>::value || unit_test::is_cstring<Rhs>::value),
|
||||
assertion_result>::type
|
||||
lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
{
|
||||
typedef typename unit_test::deduce_cstring_transform<Lhs>::type lhs_char_type;
|
||||
typedef typename unit_test::deduce_cstring_transform<Rhs>::type rhs_char_type;
|
||||
|
||||
return lexicographic_compare<OP, can_be_equal, prefer_shorter>(
|
||||
lhs_char_type(lhs),
|
||||
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_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 unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator;
|
||||
typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator;
|
||||
|
||||
assertion_result ar( true );
|
||||
|
||||
if( t_Lhs_iterator::size(lhs) != t_Rhs_iterator::size(rhs) ) {
|
||||
ar = false;
|
||||
ar.message() << "\nCollections size mismatch: " << t_Lhs_iterator::size(lhs) << " != " << t_Rhs_iterator::size(rhs);
|
||||
return ar;
|
||||
}
|
||||
|
||||
typename t_Lhs_iterator::const_iterator left = t_Lhs_iterator::begin(lhs);
|
||||
typename t_Rhs_iterator::const_iterator right = t_Rhs_iterator::begin(rhs);
|
||||
std::size_t pos = 0;
|
||||
|
||||
for( ; pos < t_Lhs_iterator::size(lhs); ++left, ++right, ++pos ) {
|
||||
assertion_result const element_ar = OP::eval( *left, *right );
|
||||
if( element_ar )
|
||||
continue;
|
||||
|
||||
ar = false;
|
||||
ar.message() << "\n - mismatch at position " << pos << ": ["
|
||||
<< tt_detail::print_helper(*left)
|
||||
<< OP::forward()
|
||||
<< tt_detail::print_helper(*right)
|
||||
<< "] is false";
|
||||
if(!element_ar.has_empty_message())
|
||||
ar.message() << ": " << 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_cstring<Lhs>::value || unit_test::is_cstring<Rhs>::value),
|
||||
assertion_result>::type
|
||||
element_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
{
|
||||
typedef typename unit_test::deduce_cstring_transform<Lhs>::type lhs_char_type;
|
||||
typedef typename unit_test::deduce_cstring_transform<Rhs>::type rhs_char_type;
|
||||
|
||||
return element_compare<OP>(lhs_char_type(lhs),
|
||||
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 )
|
||||
{
|
||||
typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator;
|
||||
typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator;
|
||||
|
||||
assertion_result ar( true );
|
||||
|
||||
if( t_Lhs_iterator::size(lhs) != t_Rhs_iterator::size(rhs) )
|
||||
return ar;
|
||||
|
||||
typename t_Lhs_iterator::const_iterator left = t_Lhs_iterator::begin(lhs);
|
||||
typename t_Rhs_iterator::const_iterator right = t_Rhs_iterator::begin(rhs);
|
||||
typename t_Lhs_iterator::const_iterator end = t_Lhs_iterator::end(lhs);
|
||||
|
||||
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, name_inverse ) \
|
||||
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_comparable<Lhs>::value \
|
||||
&& unit_test::is_forward_iterable<Rhs>::value \
|
||||
&& !unit_test::is_cstring_comparable<Rhs>::value>::type> { \
|
||||
public: \
|
||||
typedef assertion_result result_type; \
|
||||
typedef name_inverse<Lhs, Rhs> inverse; \
|
||||
typedef unit_test::bt_iterator_traits<Lhs> t_Lhs_iterator_helper; \
|
||||
typedef unit_test::bt_iterator_traits<Rhs> t_Rhs_iterator_helper; \
|
||||
\
|
||||
typedef name<Lhs, Rhs> OP; \
|
||||
\
|
||||
typedef typename \
|
||||
mpl::if_c< \
|
||||
mpl::or_< \
|
||||
typename is_c_array<Lhs>::type, \
|
||||
typename is_c_array<Rhs>::type \
|
||||
>::value, \
|
||||
mpl::true_, \
|
||||
typename \
|
||||
mpl::if_c<is_same<typename decay<Lhs>::type, \
|
||||
typename decay<Rhs>::type>::value, \
|
||||
typename cctraits<OP>::is_specialized, \
|
||||
mpl::false_>::type \
|
||||
>::type is_specialized; \
|
||||
\
|
||||
typedef name<typename t_Lhs_iterator_helper::value_type, \
|
||||
typename t_Rhs_iterator_helper::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* forward() \
|
||||
{ return " " #oper " "; } \
|
||||
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
|
||||
+96
@@ -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 : $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/pp_variadic.hpp>
|
||||
|
||||
#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/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_INFO_SCOPE( context_descr ) \
|
||||
::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 ) ) \
|
||||
/**/
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
|
||||
#define BOOST_CONTEXT_PARAM(r, ctx, i, context_descr) \
|
||||
if( ::boost::test_tools::tt_detail::context_frame BOOST_PP_CAT(ctx, i) = \
|
||||
::boost::test_tools::tt_detail::context_frame(BOOST_TEST_LAZY_MSG( context_descr ) ) ) \
|
||||
/**/
|
||||
|
||||
#define BOOST_CONTEXT_PARAMS( params ) \
|
||||
BOOST_PP_SEQ_FOR_EACH_I(BOOST_CONTEXT_PARAM, \
|
||||
BOOST_JOIN( context_frame_, __LINE__ ), \
|
||||
params) \
|
||||
/**/
|
||||
|
||||
#define BOOST_TEST_CONTEXT( ... ) \
|
||||
BOOST_CONTEXT_PARAMS( BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
|
||||
/**/
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace tt_detail
|
||||
} // namespace test_tools
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_TOOLS_CONTEXT_HPP_111712GER
|
||||
+91
@@ -0,0 +1,91 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//!@file
|
||||
//!@brief C string comparison with enhanced reporting
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
|
||||
#define BOOST_TEST_TOOLS_CSTRING_COMPARISON_OP_HPP_050815GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tools/assertion.hpp>
|
||||
|
||||
#include <boost/test/utils/is_cstring.hpp>
|
||||
#include <boost/test/utils/basic_cstring/compare.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
namespace assertion {
|
||||
namespace op {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** string_compare ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#define DEFINE_CSTRING_COMPARISON( oper, name, rev, name_inverse ) \
|
||||
template<typename Lhs,typename Rhs> \
|
||||
struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
( unit_test::is_cstring_comparable<Lhs>::value \
|
||||
&& unit_test::is_cstring_comparable<Rhs>::value) \
|
||||
>::type > \
|
||||
{ \
|
||||
typedef typename unit_test::deduce_cstring_transform<Lhs>::type lhs_char_type; \
|
||||
typedef typename unit_test::deduce_cstring_transform<Rhs>::type rhs_char_type; \
|
||||
public: \
|
||||
typedef assertion_result result_type; \
|
||||
typedef name_inverse<Lhs, Rhs> inverse; \
|
||||
\
|
||||
typedef name< \
|
||||
typename lhs_char_type::value_type, \
|
||||
typename rhs_char_type::value_type> elem_op; \
|
||||
\
|
||||
static bool \
|
||||
eval( Lhs const& lhs, Rhs const& rhs) \
|
||||
{ \
|
||||
return lhs_char_type(lhs) oper 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* forward() \
|
||||
{ return " " #oper " "; } \
|
||||
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
|
||||
|
||||
+129
@@ -0,0 +1,129 @@
|
||||
// (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
|
||||
//! This is a terminal for the expression
|
||||
struct bitwise {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
inline unit_test::lazy_ostream &
|
||||
operator<<( unit_test::lazy_ostream &o, bitwise ) { return o; }
|
||||
|
||||
// needed for the lazy evaluation in lazy_ostream as bitwise is a terminal
|
||||
inline std::ostream&
|
||||
operator<<( std::ostream& o, bitwise ) { return o; }
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 assertion_type
|
||||
operator<<( assertion_type const& , bitwise )
|
||||
{
|
||||
return assertion_type(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
|
||||
+121
@@ -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
|
||||
+125
@@ -0,0 +1,125 @@
|
||||
// (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/utils/lazy_ostream.hpp>
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <list>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
namespace tt_detail {
|
||||
|
||||
struct assertion_evaluation_context
|
||||
{
|
||||
assertion_evaluation_context(bool has_report = false)
|
||||
: m_has_report(has_report)
|
||||
{}
|
||||
|
||||
bool m_has_report;
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** assertion_evaluate indirection ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename E>
|
||||
struct assertion_evaluate_t {
|
||||
|
||||
typedef shared_ptr<assertion_evaluation_context> context_holder;
|
||||
|
||||
assertion_evaluate_t( E const& e ) : m_e( e ), m_evaluate( true )
|
||||
{}
|
||||
|
||||
operator assertion_result() { return m_e.evaluate( m_evaluate ); }
|
||||
|
||||
assertion_evaluate_t<E>
|
||||
stack_context(context_holder context) const {
|
||||
assertion_evaluate_t<E> added_context(*this);
|
||||
|
||||
added_context.m_context_holder.push_back(context);
|
||||
added_context.m_evaluate = !context->m_has_report;
|
||||
return added_context;
|
||||
}
|
||||
|
||||
E const& m_e;
|
||||
std::list< context_holder > m_context_holder;
|
||||
bool m_evaluate;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
inline unit_test::lazy_ostream const&
|
||||
assertion_text( unit_test::lazy_ostream const& et, unit_test::lazy_ostream const& s) {
|
||||
if(!s.empty())
|
||||
return s;
|
||||
return et;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** assertion_evaluate indirection ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
struct assertion_type {
|
||||
assertion_type(check_type ct = CHECK_MSG) : m_check_type(ct)
|
||||
{}
|
||||
|
||||
operator check_type() { return m_check_type; }
|
||||
check_type m_check_type;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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
|
||||
+74
@@ -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
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// (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/utils/lazy_ostream.hpp>
|
||||
#include <boost/test/tools/collection_comparison_op.hpp>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** per element comparison manipulator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Lexicographic comparison manipulator, for containers
|
||||
//! This is a terminal that involves evaluation of the expression
|
||||
struct lexicographic {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
inline unit_test::lazy_ostream&
|
||||
operator<<( unit_test::lazy_ostream & o, lexicographic ) { return o; }
|
||||
|
||||
// needed for the lazy evaluation in lazy_ostream as lexicographic is a terminal
|
||||
inline std::ostream&
|
||||
operator<<( std::ostream& o, lexicographic ) { return o; }
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 assertion_type
|
||||
operator<<( assertion_type const&, lexicographic )
|
||||
{
|
||||
return assertion_type(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
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
// (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/utils/lazy_ostream.hpp>
|
||||
#include <boost/test/tools/assertion.hpp>
|
||||
#include <boost/test/tools/collection_comparison_op.hpp>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** per element comparison manipulator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Per element comparison manipulator, for containers
|
||||
//! This is a terminal that involves evaluation of the expression
|
||||
struct per_element {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
inline unit_test::lazy_ostream&
|
||||
operator<<( unit_test::lazy_ostream &o, per_element ) { return o; }
|
||||
|
||||
// needed for the lazy evaluation in lazy_ostream as per_element is a terminal
|
||||
inline std::ostream&
|
||||
operator<<( std::ostream& o, per_element ) { return o; }
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 assertion_type
|
||||
operator<<( assertion_type const&, per_element )
|
||||
{
|
||||
return assertion_type(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
|
||||
+254
@@ -0,0 +1,254 @@
|
||||
// (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>
|
||||
|
||||
// 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 <ios>
|
||||
#include <iostream>
|
||||
#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(BOOST_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<wchar_t> {
|
||||
void operator()( std::ostream& ostr, wchar_t 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 print_log_value<std::nullptr_t> {
|
||||
// declaration and definition is here because of #12969 https://svn.boost.org/trac10/ticket/12969
|
||||
void operator()( std::ostream& ostr, std::nullptr_t /*t*/ ) {
|
||||
ostr << "nullptr";
|
||||
}
|
||||
};
|
||||
#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(BOOST_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
|
||||
+154
@@ -0,0 +1,154 @@
|
||||
// (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/utils/lazy_ostream.hpp>
|
||||
#include <boost/test/tools/fpc_tolerance.hpp>
|
||||
#include <boost/test/tools/floating_point_comparison.hpp>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace test_tools {
|
||||
namespace tt_detail {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** fpc tolerance manipulator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//! Tolerance manipulator, not to be used directly
|
||||
//! This is not a terminal of the expression
|
||||
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 FPT>
|
||||
struct tolerance_evaluation_context: assertion_evaluation_context {
|
||||
tolerance_evaluation_context(FPT tol)
|
||||
: assertion_evaluation_context( true ) // has report
|
||||
, m_tolerance_context(tol)
|
||||
{}
|
||||
|
||||
local_fpc_tolerance<FPT> m_tolerance_context;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename E, typename FPT>
|
||||
inline assertion_evaluate_t<E>
|
||||
operator<<(assertion_evaluate_t<E> const& ae, tolerance_manip<FPT> const& tol)
|
||||
{
|
||||
return ae.stack_context(
|
||||
typename assertion_evaluate_t<E>::context_holder(
|
||||
new tolerance_evaluation_context<FPT>( tol.m_value ))
|
||||
);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
unit_test::lazy_ostream &
|
||||
operator<<( unit_test::lazy_ostream &o, tolerance_manip<FPT> const& ) { return o; }
|
||||
|
||||
// needed for the lazy evaluation in lazy_ostream as for commutativity with other arguments
|
||||
template<typename FPT>
|
||||
std::ostream&
|
||||
operator<<( std::ostream& o, tolerance_manip<FPT> const& ) { return o; }
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename FPT>
|
||||
inline assertion_type
|
||||
operator<<( assertion_type const& /*at*/, tolerance_manip<FPT> const& ) {
|
||||
return assertion_type(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
|
||||
+336
@@ -0,0 +1,336 @@
|
||||
// (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/is_reference.hpp>
|
||||
#include <boost/type_traits/is_void.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_ {};
|
||||
|
||||
// from https://stackoverflow.com/a/16509511/1617295
|
||||
template<typename T>
|
||||
class is_abstract_class_or_function
|
||||
{
|
||||
typedef char (&Two)[2];
|
||||
template<typename U> static char test(U(*)[1]);
|
||||
template<typename U> static Two test(...);
|
||||
|
||||
public:
|
||||
static const bool value =
|
||||
!is_reference<T>::value
|
||||
&& !is_void<T>::value
|
||||
&& (sizeof(test<T>(0)) == sizeof(Two));
|
||||
};
|
||||
|
||||
// warning: we cannot instanciate std::numeric_limits for incomplete types, we use is_abstract_class_or_function
|
||||
// prior to the specialization below
|
||||
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 && !is_abstract_class_or_function<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( (fpt_abs(f1) <= fpt_limits<FPT>::min_value()) ||
|
||||
((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 difference, 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.
|
||||
*
|
||||
* This predicate is not suitable for comparing to 0 or to infinity.
|
||||
*/
|
||||
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
|
||||
+244
@@ -0,0 +1,244 @@
|
||||
// (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/type_traits/is_arithmetic.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 {
|
||||
// indicate if we should perform the operation with a "logical OR"
|
||||
// with the "equality under tolerance".
|
||||
static const bool equality_logical_disjunction = true;
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct fpctraits<op::LT<Lhs,Rhs> > {
|
||||
static const bool equality_logical_disjunction = false;
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct fpctraits<op::GT<Lhs,Rhs> > {
|
||||
static const bool equality_logical_disjunction = 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* cmp_operator)
|
||||
{
|
||||
assertion_result result_direct_compare = cmp_operator->eval_direct(lhs, rhs);
|
||||
if(fpctraits<OP>::equality_logical_disjunction) {
|
||||
// this look like this can be simplified, but combining result && compare_fpv
|
||||
// looses the message in the return value of compare_fpv
|
||||
if( result_direct_compare ) {
|
||||
result_direct_compare.message() << "operation" << OP::forward() << "on arguments yields 'true'.";
|
||||
return result_direct_compare;
|
||||
}
|
||||
// result || compare_fpv(EQ)
|
||||
assertion_result result_eq = compare_fpv<FPT>(lhs, rhs, (op::EQ<Lhs, Rhs>*)0);
|
||||
result_direct_compare = result_direct_compare || result_eq;
|
||||
if( !result_eq ) {
|
||||
result_direct_compare.message() << "operation" << op::EQ<Lhs, Rhs>::forward() << "on arguments yields 'false': " << result_eq.message() << ".";
|
||||
}
|
||||
return result_direct_compare;
|
||||
}
|
||||
if( !result_direct_compare ) {
|
||||
result_direct_compare.message() << "operation" << OP::forward() << " on arguments yields 'false'.";
|
||||
return result_direct_compare;
|
||||
}
|
||||
// result && compare_fpv(NE)
|
||||
assertion_result result_neq = compare_fpv<FPT>(lhs, rhs, (op::NE<Lhs, Rhs>*)0);
|
||||
result_direct_compare = result_direct_compare && result_neq;
|
||||
if( !result_neq ) {
|
||||
result_direct_compare.message() << "operation" << op::NE<Lhs, Rhs>::forward() << "on arguments yields 'false': " << result_neq.message() << ".";
|
||||
}
|
||||
return result_direct_compare;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template <typename FPT, typename Lhs, typename Rhs>
|
||||
inline assertion_result
|
||||
compare_fpv_near_zero( FPT const& fpv, op::EQ<Lhs,Rhs>* )
|
||||
{
|
||||
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_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::EQ<Lhs,Rhs>* )
|
||||
{
|
||||
if( lhs == 0 ) {
|
||||
return compare_fpv_near_zero<FPT>( rhs, (op::EQ<Lhs,Rhs>*)0 );
|
||||
}
|
||||
else if( rhs == 0) {
|
||||
return compare_fpv_near_zero<FPT>( lhs, (op::EQ<Lhs,Rhs>*)0 );
|
||||
}
|
||||
else {
|
||||
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 Lhs, typename Rhs>
|
||||
inline assertion_result
|
||||
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
|
||||
{
|
||||
if( lhs == 0 ) {
|
||||
return compare_fpv_near_zero<FPT>( rhs, (op::NE<Lhs,Rhs>*)0 );
|
||||
}
|
||||
else if( rhs == 0 ) {
|
||||
return compare_fpv_near_zero<FPT>( lhs, (op::NE<Lhs,Rhs>*)0 );
|
||||
}
|
||||
else {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#define DEFINE_FPV_COMPARISON( oper, name, rev, name_inverse ) \
|
||||
template<typename Lhs,typename Rhs> \
|
||||
struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
(fpc::tolerance_based<Lhs>::value && \
|
||||
fpc::tolerance_based<Rhs>::value) || \
|
||||
(fpc::tolerance_based<Lhs>::value && \
|
||||
boost::is_arithmetic<Rhs>::value) || \
|
||||
(boost::is_arithmetic<Lhs>::value && \
|
||||
fpc::tolerance_based<Rhs>::value) \
|
||||
>::type> { \
|
||||
public: \
|
||||
typedef typename common_type<Lhs,Rhs>::type FPT; \
|
||||
typedef name<Lhs,Rhs> OP; \
|
||||
typedef name_inverse<Lhs, Rhs> inverse; \
|
||||
\
|
||||
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( fpc_tolerance<FPT>() == FPT(0) \
|
||||
|| (std::numeric_limits<Lhs>::has_infinity \
|
||||
&& (lhs == std::numeric_limits<Lhs>::infinity())) \
|
||||
|| (std::numeric_limits<Rhs>::has_infinity \
|
||||
&& (rhs == std::numeric_limits<Rhs>::infinity()))) \
|
||||
{ \
|
||||
return eval_direct( lhs, rhs ); \
|
||||
} \
|
||||
\
|
||||
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* forward() \
|
||||
{ return " " #oper " "; } \
|
||||
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
|
||||
+103
@@ -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
|
||||
+366
@@ -0,0 +1,366 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $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
|
||||
|
||||
#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
|
||||
+359
@@ -0,0 +1,359 @@
|
||||
// (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 )
|
||||
BOOST_TEST_DECL assertion_result 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
|
||||
{
|
||||
typedef typename tt_detail::comp_supertype<FPT1,FPT2>::type super_type;
|
||||
fpc::close_at_tolerance<super_type> pred( tolerance, fpc::FPC_STRONG );
|
||||
|
||||
assertion_result ar( pred( static_cast<super_type>(left), static_cast<super_type>(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
|
||||
+284
@@ -0,0 +1,284 @@
|
||||
// (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/core/ignore_unused.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::ignore_unused( 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
|
||||
+107
@@ -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
|
||||
~output_test_stream() BOOST_OVERRIDE;
|
||||
|
||||
//! 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
|
||||
+54
@@ -0,0 +1,54 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision: 74640 $
|
||||
//
|
||||
// Description : defines 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_t& 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_t& decorators );
|
||||
explicit auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector_t& decorators );
|
||||
explicit auto_test_unit_registrar( boost::shared_ptr<test_unit_generator> tc_gen, decorator::collector_t& 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