updated boost on windows
This commit is contained in:
@@ -37,6 +37,11 @@
|
||||
|
||||
#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 ) )
|
||||
|
||||
@@ -77,7 +77,7 @@ invoke_action( Action const& action, T&& args, std::true_type /* is_tuple */ )
|
||||
|
||||
template<typename DataSet, typename Action>
|
||||
inline typename std::enable_if<monomorphic::is_dataset<DataSet>::value,void>::type
|
||||
for_each_sample( DataSet && samples,
|
||||
for_each_sample( DataSet const & samples,
|
||||
Action const& act,
|
||||
data::size_t number_of_samples = BOOST_TEST_DS_INFINITE_SIZE )
|
||||
{
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//!@file
|
||||
//!@brief specific generators
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
#define BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/data/monomorphic/generators/xrange.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DATA_MONOMORPHIC_GENERATORS_HPP_112011GER
|
||||
|
||||
@@ -49,6 +49,11 @@ 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;
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#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
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ struct is_dataset<collection<C>> : mpl::true_ {};
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename C>
|
||||
inline typename std::enable_if<is_forward_iterable<C>::value,monomorphic::collection<C>>::type
|
||||
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) );
|
||||
|
||||
124
winx64/include/boost/test/data/monomorphic/delayed.hpp
Normal file
124
winx64/include/boost/test/data/monomorphic/delayed.hpp
Normal file
@@ -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:
|
||||
enum { 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
|
||||
@@ -43,9 +43,6 @@ namespace monomorphic {
|
||||
|
||||
#if !defined(BOOST_TEST_DOXYGEN_DOC__)
|
||||
|
||||
template<typename T, typename Specific>
|
||||
class dataset;
|
||||
|
||||
template<typename T>
|
||||
class singleton;
|
||||
|
||||
@@ -58,6 +55,12 @@ 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
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -73,6 +76,8 @@ 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> {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -80,6 +85,18 @@ struct is_dataset<DataSet&> : is_dataset<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
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -119,7 +136,7 @@ make(DataSet&& ds)
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename T>
|
||||
inline typename std::enable_if<!is_forward_iterable<T>::value &&
|
||||
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
|
||||
@@ -129,7 +146,7 @@ make( T&& v );
|
||||
|
||||
//! @overload boost::unit_test::data::make()
|
||||
template<typename C>
|
||||
inline typename std::enable_if<is_forward_iterable<C>::value,monomorphic::collection<C>>::type
|
||||
inline typename std::enable_if<is_container_forward_iterable<C>::value,monomorphic::collection<C>>::type
|
||||
make( C&& c );
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -160,6 +177,31 @@ 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.
|
||||
|
||||
@@ -16,6 +16,8 @@
|
||||
#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>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -25,9 +25,9 @@ namespace unit_test {
|
||||
namespace data {
|
||||
|
||||
namespace {
|
||||
nfp::keyword<struct begin_t> begin;
|
||||
nfp::keyword<struct end_t> end;
|
||||
nfp::keyword<struct step_t> step;
|
||||
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
|
||||
|
||||
@@ -22,6 +22,9 @@
|
||||
#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>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -102,7 +105,10 @@ public:
|
||||
{}
|
||||
|
||||
// dataset interface
|
||||
data::size_t size() const { return m_ds1.size() * m_ds2.size(); }
|
||||
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:
|
||||
@@ -138,8 +144,6 @@ inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_datase
|
||||
>::type
|
||||
operator*( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
BOOST_TEST_DS_ASSERT( !ds1.size().is_inf() && !ds2.size().is_inf(), "Grid axes can't have infinite size" );
|
||||
|
||||
return grid<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ), std::forward<DataSet2>( ds2 ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -16,6 +16,10 @@
|
||||
#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>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -26,23 +30,35 @@ namespace data {
|
||||
namespace monomorphic {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** array ************** //
|
||||
// ************** initializer_list ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// Dataset view of a C array
|
||||
/// 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:
|
||||
typedef T sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
typedef T const* iterator;
|
||||
typedef typename std::vector<T>::const_iterator iterator;
|
||||
|
||||
//! Constructor swallows initializer_list
|
||||
init_list( std::initializer_list<T>&& il )
|
||||
: m_data( std::forward<std::initializer_list<T>>( il ) )
|
||||
//! 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(); }
|
||||
@@ -50,7 +66,39 @@ public:
|
||||
|
||||
private:
|
||||
// Data members
|
||||
std::initializer_list<T> m_data;
|
||||
std::vector<T> m_data;
|
||||
};
|
||||
|
||||
//! Specialization of init_list for type bool
|
||||
template <>
|
||||
class init_list<bool> {
|
||||
public:
|
||||
typedef bool sample;
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
typedef std::vector<bool>::const_iterator iterator;
|
||||
|
||||
//! 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
|
||||
|
||||
//! 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;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -71,6 +119,20 @@ 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
|
||||
|
||||
@@ -16,6 +16,9 @@
|
||||
#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>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -40,22 +43,33 @@ class join {
|
||||
|
||||
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:
|
||||
typedef typename dataset1_decay::sample sample;
|
||||
|
||||
enum { 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 )
|
||||
explicit iterator( dataset1_iter&& it1, dataset2_iter&& it2, data::size_t first_size )
|
||||
: m_it1( std::move( it1 ) )
|
||||
, m_it2( std::move( it2 ) )
|
||||
, m_first_size( first_size )
|
||||
{}
|
||||
|
||||
// forward iterator interface
|
||||
sample const& operator*() const { return m_first_size > 0 ? *m_it1 : *m_it2; }
|
||||
void operator++() { if( m_first_size > 0 ) { --m_first_size; ++m_it1; } else ++m_it2; }
|
||||
// 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
|
||||
|
||||
@@ -32,9 +32,11 @@ namespace monomorphic {
|
||||
/// Models a single element data set
|
||||
template<typename T>
|
||||
class singleton {
|
||||
public:
|
||||
private:
|
||||
typedef typename boost::decay<T>::type sample;
|
||||
|
||||
public:
|
||||
|
||||
enum { arity = 1 };
|
||||
|
||||
struct iterator {
|
||||
@@ -81,7 +83,7 @@ struct is_dataset<singleton<T>> : mpl::true_ {};
|
||||
|
||||
/// @overload boost::unit_test::data::make()
|
||||
template<typename T>
|
||||
inline typename std::enable_if<!is_forward_iterable<T>::value &&
|
||||
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>
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
#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>
|
||||
|
||||
|
||||
@@ -70,33 +73,50 @@ public:
|
||||
dataset2_iter m_iter2;
|
||||
};
|
||||
|
||||
typedef typename iterator::iterator_sample sample;
|
||||
|
||||
//! Constructor
|
||||
//!
|
||||
//! The datasets are moved and not copied.
|
||||
zip( DataSet1&& ds1, DataSet2&& ds2, data::size_t size )
|
||||
zip( DataSet1&& ds1, DataSet2&& ds2/*, data::size_t size*/ )
|
||||
: m_ds1( std::forward<DataSet1>( ds1 ) )
|
||||
, m_ds2( std::forward<DataSet2>( ds2 ) )
|
||||
, m_size( size )
|
||||
//, 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 )
|
||||
//, m_size( j.m_size )
|
||||
{}
|
||||
|
||||
// dataset interface
|
||||
data::size_t size() const { return m_size; }
|
||||
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;
|
||||
//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" );
|
||||
}
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -107,32 +127,6 @@ struct is_dataset<zip<DataSet1,DataSet2>> : mpl::true_ {};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace ds_detail {
|
||||
|
||||
//! Handles the sise of the resulting zipped dataset.
|
||||
template<typename DataSet1, typename DataSet2>
|
||||
inline data::size_t
|
||||
zip_size( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
data::size_t ds1_size = ds1.size();
|
||||
data::size_t ds2_size = ds2.size();
|
||||
|
||||
if( ds1_size == ds2_size )
|
||||
return ds1_size;
|
||||
|
||||
if( ds1_size == 1 || ds1_size.is_inf() )
|
||||
return ds2_size;
|
||||
|
||||
if( ds2_size == 1 || ds2_size.is_inf() )
|
||||
return ds1_size;
|
||||
|
||||
BOOST_TEST_DS_ERROR( "Can't zip datasets of different sizes" );
|
||||
}
|
||||
|
||||
} // namespace ds_detail
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace result_of {
|
||||
|
||||
//! Result type of the zip operator.
|
||||
@@ -153,8 +147,8 @@ inline typename boost::lazy_enable_if_c<is_dataset<DataSet1>::value && is_datase
|
||||
operator^( DataSet1&& ds1, DataSet2&& ds2 )
|
||||
{
|
||||
return zip<DataSet1,DataSet2>( std::forward<DataSet1>( ds1 ),
|
||||
std::forward<DataSet2>( ds2 ),
|
||||
ds_detail::zip_size( ds1, ds2 ) );
|
||||
std::forward<DataSet2>( ds2 )/*,
|
||||
ds_detail::zip_size( ds1, ds2 )*/ );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#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>
|
||||
@@ -32,13 +33,16 @@
|
||||
#include <boost/preprocessor/comparison/equal.hpp>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
#include <boost/type_traits/is_copy_constructible.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
#include <boost/test/tools/detail/print_helper.hpp>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
|
||||
#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
|
||||
@@ -122,15 +126,17 @@ public:
|
||||
// Constructor
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
|
||||
: m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
|
||||
: m_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 )
|
||||
{
|
||||
data::for_each_sample( std::forward<DataSet>( ds ), *this );
|
||||
}
|
||||
{}
|
||||
test_case_gen( test_case_gen&& gen )
|
||||
: m_tc_name( gen.m_tc_name )
|
||||
: 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 )
|
||||
@@ -138,17 +144,23 @@ public:
|
||||
{}
|
||||
#else
|
||||
test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
|
||||
: m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
|
||||
, m_tc_file( tc_file )
|
||||
: m_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 )
|
||||
{
|
||||
data::for_each_sample( ds, *this );
|
||||
}
|
||||
{}
|
||||
#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;
|
||||
|
||||
@@ -158,8 +170,10 @@ public:
|
||||
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 \
|
||||
@@ -178,8 +192,8 @@ public:
|
||||
new test_case( genTestCaseName(),
|
||||
m_tc_file,
|
||||
m_tc_line,
|
||||
boost::bind( &TestCase::template test_method<Arg...>,
|
||||
boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
|
||||
std::bind( &TestCase::template test_method<Arg...>,
|
||||
boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -190,6 +204,8 @@ private:
|
||||
}
|
||||
|
||||
// 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;
|
||||
@@ -201,10 +217,10 @@ private:
|
||||
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
template<typename TestCase,typename DataSet>
|
||||
test_case_gen<TestCase,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 test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, std::forward<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>
|
||||
@@ -236,20 +252,29 @@ struct BOOST_PP_CAT(test_name, case) : public F { \
|
||||
template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
|
||||
static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
|
||||
{ \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry.");\
|
||||
BOOST_PP_CAT(test_name, case) t; \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
|
||||
BOOST_TEST_CONTEXT( "" \
|
||||
BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
|
||||
t._impl(BOOST_PP_SEQ_ENUM(params)); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
|
||||
{ \
|
||||
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_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< \
|
||||
@@ -257,7 +282,7 @@ BOOST_AUTO_TU_REGISTRAR( BOOST_PP_CAT(test_name, case) )( \
|
||||
BOOST_STRINGIZE( test_name ), \
|
||||
__FILE__, __LINE__, \
|
||||
boost::unit_test::data::ds_detail::seed{} ->* dataset ), \
|
||||
boost::unit_test::decorator::collector::instance() ); \
|
||||
boost::unit_test::decorator::collector_t::instance() ); \
|
||||
\
|
||||
BOOST_AUTO_TEST_SUITE_END() \
|
||||
\
|
||||
|
||||
@@ -78,10 +78,27 @@ class type_info;
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// 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
|
||||
@@ -90,12 +107,12 @@ class type_info;
|
||||
# define BOOST_TEST_ALTERNATIVE_INIT_API
|
||||
|
||||
# ifdef BOOST_TEST_SOURCE
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_EXPORT
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_EXPORT BOOST_SYMBOL_VISIBLE
|
||||
# else
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_IMPORT
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_IMPORT BOOST_SYMBOL_VISIBLE
|
||||
# endif // BOOST_TEST_SOURCE
|
||||
#else
|
||||
# define BOOST_TEST_DECL
|
||||
# define BOOST_TEST_DECL BOOST_SYMBOL_VISIBLE
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_TEST_MAIN) && defined(BOOST_AUTO_TEST_MAIN)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#if BOOST_CLANG
|
||||
#if defined(BOOST_CLANG) && (BOOST_CLANG == 1)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
||||
|
||||
@@ -26,6 +26,8 @@ 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;
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#define BOOST_TEST_GLOBAL_TYPEDEF_HPP_021005GER
|
||||
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
|
||||
#define BOOST_TEST_L( s ) ::boost::unit_test::const_string( s, sizeof( s ) - 1 )
|
||||
#define BOOST_TEST_STRINGIZE( s ) BOOST_TEST_L( BOOST_STRINGIZE( s ) )
|
||||
@@ -71,6 +70,21 @@ 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
|
||||
@@ -86,6 +100,45 @@ 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
|
||||
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
#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 {
|
||||
|
||||
@@ -20,7 +22,7 @@ namespace unit_test {
|
||||
// ************************************************************************** //
|
||||
|
||||
// each log level includes all subsequent higher loging levels
|
||||
enum log_level {
|
||||
enum BOOST_TEST_ENUM_SYMBOL_VISIBLE log_level {
|
||||
invalid_log_level = -1,
|
||||
log_successful_tests = 0,
|
||||
log_test_units = 1,
|
||||
|
||||
@@ -26,13 +26,15 @@
|
||||
# pragma warning(disable: 4511) // 'class' : copy constructor could not be generated
|
||||
#endif
|
||||
|
||||
#if BOOST_CLANG
|
||||
#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"
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ namespace ut_detail {
|
||||
|
||||
template<typename E>
|
||||
BOOST_NORETURN inline void
|
||||
throw_exception(E const& e) { abort(); }
|
||||
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;)
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//!@file
|
||||
//!@brief contains mics. workarounds
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_WORKAROUND_HPP_021005GER
|
||||
#define BOOST_TEST_WORKAROUND_HPP_021005GER
|
||||
|
||||
// Boost
|
||||
#include <boost/config.hpp> // compilers workarounds and std::ptrdiff_t
|
||||
|
||||
// STL
|
||||
#include <iterator> // for std::distance
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace ut_detail {
|
||||
|
||||
#ifdef BOOST_NO_STD_DISTANCE
|
||||
template <class T>
|
||||
std::ptrdiff_t distance( T const& x_, T const& y_ )
|
||||
{
|
||||
std::ptrdiff_t res = 0;
|
||||
|
||||
std::distance( x_, y_, res );
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#else
|
||||
using std::distance;
|
||||
#endif
|
||||
|
||||
template <class T> inline void ignore_unused_variable_warning(const T&) {}
|
||||
|
||||
} // namespace ut_detail
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_WORKAROUND_HPP_021005GER
|
||||
@@ -111,7 +111,8 @@ namespace boost {
|
||||
///
|
||||
/// @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.
|
||||
/// 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,
|
||||
@@ -237,7 +238,7 @@ protected:
|
||||
/// this class never allocates any memory and assumes that strings it refers to are either some constants or live in a some kind of persistent (preallocated) memory.
|
||||
// ************************************************************************** //
|
||||
|
||||
class BOOST_TEST_DECL execution_exception {
|
||||
class BOOST_SYMBOL_VISIBLE execution_exception {
|
||||
typedef boost::unit_test::const_string const_string;
|
||||
public:
|
||||
/// These values are sometimes used as program return codes.
|
||||
@@ -270,6 +271,7 @@ public:
|
||||
/// 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
|
||||
@@ -336,9 +338,9 @@ public:
|
||||
|
||||
/// Specifies the seconds that elapse before a timer_error occurs.
|
||||
///
|
||||
/// The @em p_timeout property is an integer timeout (in seconds) for monitored function execution. Use this parameter to monitor code with possible deadlocks
|
||||
/// or indefinite loops. This feature is only available for some operating systems (not yet Microsoft Windows).
|
||||
unit_test::readwrite_property<unsigned> p_timeout;
|
||||
/// 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.
|
||||
///
|
||||
@@ -514,8 +516,12 @@ enum masks {
|
||||
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)
|
||||
|
||||
@@ -18,8 +18,6 @@
|
||||
#include <boost/test/detail/fwd_decl.hpp>
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
// STL
|
||||
@@ -74,7 +72,7 @@ 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();
|
||||
BOOST_TEST_DECL void shutdown();
|
||||
/// @}
|
||||
|
||||
/// @name Test unit registration
|
||||
@@ -132,12 +130,28 @@ BOOST_TEST_DECL void clear();
|
||||
/// @param[in] to test observer object to add
|
||||
BOOST_TEST_DECL void register_observer( test_observer& to );
|
||||
|
||||
/// Excldes the observer object form the framework's list of test observers
|
||||
/// 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
|
||||
@@ -178,6 +192,15 @@ BOOST_TEST_DECL context_generator get_context();
|
||||
/// @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.
|
||||
@@ -231,6 +254,8 @@ BOOST_TEST_DECL void assertion_result( unit_test::assertion_resul
|
||||
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 {
|
||||
|
||||
@@ -52,7 +52,7 @@ namespace {
|
||||
std::string
|
||||
test_phase_identifier()
|
||||
{
|
||||
return framework::test_in_progress() ? framework::current_test_case().full_name() : std::string( "Test setup" );
|
||||
return framework::test_in_progress() ? framework::current_test_unit().full_name() : std::string( "Test setup" );
|
||||
}
|
||||
|
||||
} // local namespace
|
||||
@@ -80,14 +80,16 @@ compiler_log_formatter::log_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
compiler_log_formatter::log_build_info( std::ostream& output )
|
||||
compiler_log_formatter::log_build_info( std::ostream& output, bool 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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -182,30 +184,25 @@ compiler_log_formatter::log_entry_start( std::ostream& output, log_entry_data co
|
||||
switch( let ) {
|
||||
case BOOST_UTL_ET_INFO:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::GREEN );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::GREEN );
|
||||
output << "info: ";
|
||||
break;
|
||||
case BOOST_UTL_ET_MESSAGE:
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::CYAN );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::CYAN );
|
||||
break;
|
||||
case BOOST_UTL_ET_WARNING:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::YELLOW );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::YELLOW );
|
||||
output << "warning: in \"" << test_phase_identifier() << "\": ";
|
||||
break;
|
||||
case BOOST_UTL_ET_ERROR:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::BRIGHT, term_color::RED );
|
||||
output << setcolor( m_color_output, term_attr::BRIGHT, term_color::RED );
|
||||
output << "error: in \"" << test_phase_identifier() << "\": ";
|
||||
break;
|
||||
case BOOST_UTL_ET_FATAL_ERROR:
|
||||
print_prefix( output, entry_data.m_file_name, entry_data.m_line_num );
|
||||
if( m_color_output )
|
||||
output << setcolor( term_attr::UNDERLINE, term_color::RED );
|
||||
output << setcolor( m_color_output, term_attr::UNDERLINE, term_color::RED );
|
||||
output << "fatal error: in \"" << test_phase_identifier() << "\": ";
|
||||
break;
|
||||
}
|
||||
@@ -233,7 +230,7 @@ void
|
||||
compiler_log_formatter::log_entry_finish( std::ostream& output )
|
||||
{
|
||||
if( m_color_output )
|
||||
output << utils::setcolor();
|
||||
output << utils::setcolor(m_color_output);
|
||||
|
||||
output << std::endl;
|
||||
}
|
||||
@@ -260,21 +257,29 @@ compiler_log_formatter::print_prefix( std::ostream& output, const_string file_na
|
||||
void
|
||||
compiler_log_formatter::entry_context_start( std::ostream& output, log_level l )
|
||||
{
|
||||
output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:";
|
||||
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 )
|
||||
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, const_string context_descr )
|
||||
compiler_log_formatter::log_entry_context( std::ostream& output, log_level /*l*/, const_string context_descr )
|
||||
{
|
||||
output << "\n " << context_descr;
|
||||
}
|
||||
|
||||
@@ -17,12 +17,13 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
|
||||
#include <boost/test/debug.hpp>
|
||||
#include <boost/test/debug_config.hpp>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
// Implementation on Windows
|
||||
#if defined(_WIN32) && !defined(UNDER_CE) && !defined(BOOST_DISABLE_WIN32) // ******* WIN32
|
||||
|
||||
@@ -768,7 +769,7 @@ struct safe_handle_helper
|
||||
}
|
||||
}
|
||||
|
||||
~safe_handle_helper()
|
||||
~safe_handle_helper()
|
||||
{
|
||||
close_handle();
|
||||
}
|
||||
@@ -804,7 +805,7 @@ attach_debugger( bool break_or_continue )
|
||||
|
||||
if( !dbg_init_done_ev )
|
||||
return false;
|
||||
|
||||
|
||||
safe_handle_helper safe_handle_obj( dbg_init_done_ev );
|
||||
|
||||
// *************************************************** //
|
||||
@@ -822,7 +823,7 @@ attach_debugger( bool break_or_continue )
|
||||
DWORD format_size = MAX_CMD_LINE;
|
||||
DWORD type = REG_SZ;
|
||||
|
||||
bool b_read_key = s_info.m_reg_query_value &&
|
||||
bool b_read_key = s_info.m_reg_query_value &&
|
||||
((*s_info.m_reg_query_value)(
|
||||
reg_key, // handle of open key
|
||||
"Debugger", // name of subkey to query
|
||||
@@ -833,7 +834,7 @@ attach_debugger( bool break_or_continue )
|
||||
|
||||
if( !s_info.m_reg_close_key || (*s_info.m_reg_close_key)( reg_key ) != ERROR_SUCCESS )
|
||||
return false;
|
||||
|
||||
|
||||
if( !b_read_key )
|
||||
return false;
|
||||
|
||||
@@ -938,7 +939,7 @@ attach_debugger( bool break_or_continue )
|
||||
return true;
|
||||
|
||||
#else // ****************************************************** default
|
||||
|
||||
(void) break_or_continue; // silence 'unused variable' warning
|
||||
return false;
|
||||
|
||||
#endif
|
||||
@@ -953,7 +954,7 @@ attach_debugger( bool break_or_continue )
|
||||
void
|
||||
detect_memory_leaks( bool on_off, unit_test::const_string report_file )
|
||||
{
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( on_off );
|
||||
boost::ignore_unused( on_off );
|
||||
|
||||
#ifdef BOOST_MS_CRT_BASED_DEBUG
|
||||
int flags = _CrtSetDbgFlag( _CRTDBG_REPORT_FLAG );
|
||||
@@ -975,7 +976,7 @@ detect_memory_leaks( bool on_off, unit_test::const_string report_file )
|
||||
|
||||
_CrtSetDbgFlag ( flags );
|
||||
#else
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( report_file );
|
||||
boost::ignore_unused( report_file );
|
||||
#endif // BOOST_MS_CRT_BASED_DEBUG
|
||||
}
|
||||
|
||||
@@ -989,7 +990,7 @@ detect_memory_leaks( bool on_off, unit_test::const_string report_file )
|
||||
void
|
||||
break_memory_alloc( long mem_alloc_order_num )
|
||||
{
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( mem_alloc_order_num );
|
||||
boost::ignore_unused( mem_alloc_order_num );
|
||||
|
||||
#ifdef BOOST_MS_CRT_BASED_DEBUG
|
||||
// only set the value if one was supplied (do not use default used by UTF just as a indicator to enable leak detection)
|
||||
@@ -1006,4 +1007,3 @@ break_memory_alloc( long mem_alloc_order_num )
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_DEBUG_API_IPP_112006GER
|
||||
|
||||
|
||||
@@ -5,10 +5,6 @@
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description : unit test decorators implementation
|
||||
// ***************************************************************************
|
||||
|
||||
@@ -35,13 +31,17 @@ namespace unit_test {
|
||||
namespace decorator {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::collector ************** //
|
||||
// ************** decorator::collector_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector&
|
||||
collector::operator*( base const& d )
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(collector_t)
|
||||
|
||||
|
||||
collector_t&
|
||||
collector_t::operator*( base const& d )
|
||||
{
|
||||
m_tu_decorators.push_back( d.clone() );
|
||||
m_tu_decorators_stack.begin()->push_back( d.clone() );
|
||||
|
||||
return *this;
|
||||
}
|
||||
@@ -49,17 +49,41 @@ collector::operator*( base const& d )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
collector::store_in( test_unit& tu )
|
||||
collector_t::store_in( test_unit& tu )
|
||||
{
|
||||
tu.p_decorators.value.insert( tu.p_decorators.value.end(), m_tu_decorators.begin(), m_tu_decorators.end() );
|
||||
tu.p_decorators.value.insert(
|
||||
tu.p_decorators.value.end(),
|
||||
m_tu_decorators_stack.begin()->begin(),
|
||||
m_tu_decorators_stack.begin()->end() );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
collector::reset()
|
||||
collector_t::reset()
|
||||
{
|
||||
m_tu_decorators.clear();
|
||||
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();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -68,10 +92,28 @@ collector::reset()
|
||||
// ************** decorator::base ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
collector&
|
||||
collector_t&
|
||||
base::operator*() const
|
||||
{
|
||||
return collector::instance() * *this;
|
||||
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
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
#include <boost/test/debug.hpp>
|
||||
@@ -35,6 +34,7 @@
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
#include <boost/exception/get_error_info.hpp> // for get_error_info
|
||||
#include <boost/exception/current_exception_cast.hpp> // for current_exception_cast
|
||||
#include <boost/exception/diagnostic_information.hpp>
|
||||
#endif
|
||||
|
||||
// STL
|
||||
@@ -47,28 +47,32 @@
|
||||
#include <cassert> // for assert
|
||||
#include <cstddef> // for NULL
|
||||
#include <cstdio> // for vsnprintf
|
||||
#include <stdio.h>
|
||||
#include <cstdarg> // for varargs
|
||||
#include <stdarg.h>
|
||||
#include <cmath> // for ceil
|
||||
|
||||
#include <iostream> // for varargs
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::strerror; using ::strlen; using ::strncat; }
|
||||
namespace std { using ::strerror; using ::strlen; using ::strncat; using ::ceil; }
|
||||
#endif
|
||||
|
||||
// to use vsnprintf
|
||||
#if defined(__SUNPRO_CC) || defined(__SunOS)
|
||||
# include <stdio.h>
|
||||
# include <stdarg.h>
|
||||
#if defined(__SUNPRO_CC) || defined(__SunOS) || defined(__QNXNTO__) || defined(__VXWORKS__)
|
||||
using std::va_list;
|
||||
#endif
|
||||
|
||||
// to use vsnprintf
|
||||
#if defined(__QNXNTO__)
|
||||
# include <stdio.h>
|
||||
using std::va_list;
|
||||
#if defined(__VXWORKS__)
|
||||
# define BOOST_TEST_LIMITED_SIGNAL_DETAILS
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_SEH_BASED_SIGNAL_HANDLING
|
||||
|
||||
# if !defined(_WIN32_WINNT) // WinXP
|
||||
# define _WIN32_WINNT 0x0501
|
||||
# endif
|
||||
|
||||
# include <windows.h>
|
||||
|
||||
# if defined(__MWERKS__) || (defined(_MSC_VER) && !defined(UNDER_CE))
|
||||
@@ -102,6 +106,10 @@ using std::va_list;
|
||||
# define BOOST_TEST_CRT_SET_HOOK(H) (void*)(H)
|
||||
# endif
|
||||
|
||||
# if defined(_WIN32_WINNT) && (_WIN32_WINNT >= 0x0501) /* WinXP */
|
||||
# define BOOST_TEST_WIN32_WAITABLE_TIMERS
|
||||
# endif
|
||||
|
||||
# if (!BOOST_WORKAROUND(_MSC_VER, >= 1400 ) && \
|
||||
!defined(BOOST_COMO)) || defined(UNDER_CE)
|
||||
|
||||
@@ -210,7 +218,8 @@ namespace detail {
|
||||
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) std::vsnprintf( (a1), (a2), (a3), (a4) )
|
||||
#elif BOOST_WORKAROUND(_MSC_VER, <= 1310) || \
|
||||
BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3000)) || \
|
||||
defined(UNDER_CE)
|
||||
defined(UNDER_CE) || \
|
||||
(defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR))
|
||||
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) _vsnprintf( (a1), (a2), (a3), (a4) )
|
||||
#else
|
||||
# define BOOST_TEST_VSNPRINTF( a1, a2, a3, a4 ) vsnprintf( (a1), (a2), (a3), (a4) )
|
||||
@@ -363,11 +372,17 @@ system_signal_exception::report() const
|
||||
return; // no error actually occur?
|
||||
|
||||
switch( m_sig_info->si_code ) {
|
||||
#ifdef __VXWORKS__
|
||||
// a bit of a hack to adapt code to small m_sig_info VxWorks uses
|
||||
#define si_addr si_value.sival_int
|
||||
#define si_band si_value.sival_int
|
||||
#else
|
||||
case SI_USER:
|
||||
report_error( execution_exception::system_error,
|
||||
"signal: generated by kill() (or family); uid=%d; pid=%d",
|
||||
(int)m_sig_info->si_uid, (int)m_sig_info->si_pid );
|
||||
break;
|
||||
#endif
|
||||
case SI_QUEUE:
|
||||
report_error( execution_exception::system_error,
|
||||
"signal: sent by sigqueue()" );
|
||||
@@ -686,7 +701,7 @@ signal_action::~signal_action()
|
||||
class signal_handler {
|
||||
public:
|
||||
// Constructor
|
||||
explicit signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout, bool attach_dbg, char* alt_stack );
|
||||
explicit signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout_microseconds, bool attach_dbg, char* alt_stack );
|
||||
|
||||
// Destructor
|
||||
~signal_handler();
|
||||
@@ -709,7 +724,7 @@ public:
|
||||
private:
|
||||
// Data members
|
||||
signal_handler* m_prev_handler;
|
||||
unsigned m_timeout;
|
||||
unsigned m_timeout_microseconds;
|
||||
|
||||
// Note: We intentionality do not catch SIGCHLD. Users have to deal with it themselves
|
||||
signal_action m_ILL_action;
|
||||
@@ -733,24 +748,24 @@ signal_handler* signal_handler::s_active_handler = signal_handler_ptr();
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
signal_handler::signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout, bool attach_dbg, char* alt_stack )
|
||||
signal_handler::signal_handler( bool catch_system_errors, bool detect_fpe, unsigned timeout_microseconds, bool attach_dbg, char* alt_stack )
|
||||
: m_prev_handler( s_active_handler )
|
||||
, m_timeout( timeout )
|
||||
, m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_FPE_action ( SIGFPE , detect_fpe , attach_dbg, alt_stack )
|
||||
, m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_timeout_microseconds( timeout_microseconds )
|
||||
, m_ILL_action ( SIGILL , catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_FPE_action ( SIGFPE , detect_fpe , attach_dbg, alt_stack )
|
||||
, m_SEGV_action( SIGSEGV, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_BUS_action ( SIGBUS , catch_system_errors, attach_dbg, alt_stack )
|
||||
#ifdef BOOST_TEST_CATCH_SIGPOLL
|
||||
, m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_POLL_action( SIGPOLL, catch_system_errors, attach_dbg, alt_stack )
|
||||
#endif
|
||||
, m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_ALRM_action( SIGALRM, timeout > 0 , attach_dbg, alt_stack )
|
||||
, m_ABRT_action( SIGABRT, catch_system_errors, attach_dbg, alt_stack )
|
||||
, m_ALRM_action( SIGALRM, timeout_microseconds > 0, attach_dbg, alt_stack )
|
||||
{
|
||||
s_active_handler = this;
|
||||
|
||||
if( m_timeout > 0 ) {
|
||||
if( m_timeout_microseconds > 0 ) {
|
||||
::alarm( 0 );
|
||||
::alarm( timeout );
|
||||
::alarm( static_cast<unsigned int>(std::ceil(timeout_microseconds / 1E6) )); // alarm has a precision to the seconds
|
||||
}
|
||||
|
||||
#ifdef BOOST_TEST_USE_ALT_STACK
|
||||
@@ -776,7 +791,7 @@ signal_handler::~signal_handler()
|
||||
{
|
||||
assert( s_active_handler == this );
|
||||
|
||||
if( m_timeout > 0 )
|
||||
if( m_timeout_microseconds > 0 )
|
||||
::alarm( 0 );
|
||||
|
||||
#ifdef BOOST_TEST_USE_ALT_STACK
|
||||
@@ -892,8 +907,10 @@ public:
|
||||
, m_se_id( 0 )
|
||||
, m_fault_address( 0 )
|
||||
, m_dir( false )
|
||||
, m_timeout( false )
|
||||
{}
|
||||
|
||||
void set_timed_out();
|
||||
void report() const;
|
||||
int operator()( unsigned id, _EXCEPTION_POINTERS* exps );
|
||||
|
||||
@@ -904,6 +921,7 @@ private:
|
||||
unsigned m_se_id;
|
||||
void* m_fault_address;
|
||||
bool m_dir;
|
||||
bool m_timeout;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -918,6 +936,14 @@ seh_catch_preventer( unsigned /* id */, _EXCEPTION_POINTERS* /* exps */ )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
system_signal_exception::set_timed_out()
|
||||
{
|
||||
m_timeout = true;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
int
|
||||
system_signal_exception::operator()( unsigned id, _EXCEPTION_POINTERS* exps )
|
||||
{
|
||||
@@ -1069,7 +1095,12 @@ system_signal_exception::report() const
|
||||
break;
|
||||
|
||||
default:
|
||||
detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id );
|
||||
if( m_timeout ) {
|
||||
detail::report_error(execution_exception::timeout_error, "timeout while executing function");
|
||||
}
|
||||
else {
|
||||
detail::report_error( execution_exception::system_error, "unrecognized exception. Id: 0x%08lx", m_se_id );
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1128,6 +1159,31 @@ execution_monitor::catch_signals( boost::function<int ()> const& F )
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(BOOST_TEST_WIN32_WAITABLE_TIMERS)
|
||||
HANDLE htimer = INVALID_HANDLE_VALUE;
|
||||
BOOL bTimerSuccess = FALSE;
|
||||
|
||||
if( p_timeout ) {
|
||||
htimer = ::CreateWaitableTimer(
|
||||
NULL,
|
||||
TRUE,
|
||||
TEXT("Boost.Test timer"));
|
||||
|
||||
if( htimer != INVALID_HANDLE_VALUE ) {
|
||||
LARGE_INTEGER liDueTime;
|
||||
liDueTime.QuadPart = - static_cast<signed long int>(p_timeout) * 10; // resolution of 100 ns
|
||||
|
||||
bTimerSuccess = ::SetWaitableTimer(
|
||||
htimer,
|
||||
&liDueTime,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
FALSE); // Do not restore a suspended system
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
detail::system_signal_exception SSE( this );
|
||||
|
||||
int ret_val = 0;
|
||||
@@ -1141,8 +1197,26 @@ execution_monitor::catch_signals( boost::function<int ()> const& F )
|
||||
__except( SSE( GetExceptionCode(), GetExceptionInformation() ) ) {
|
||||
throw SSE;
|
||||
}
|
||||
|
||||
// we check for time outs: we do not have any signaling facility on Win32
|
||||
// however, we signal a timeout as a hard error as for the other operating systems
|
||||
// and throw the signal error handler
|
||||
if( bTimerSuccess && htimer != INVALID_HANDLE_VALUE) {
|
||||
if (::WaitForSingleObject(htimer, 0) == WAIT_OBJECT_0) {
|
||||
SSE.set_timed_out();
|
||||
throw SSE;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
__finally {
|
||||
|
||||
#if defined(BOOST_TEST_WIN32_WAITABLE_TIMERS)
|
||||
if( htimer != INVALID_HANDLE_VALUE ) {
|
||||
::CloseHandle(htimer);
|
||||
}
|
||||
#endif
|
||||
|
||||
if( l_catch_system_errors ) {
|
||||
BOOST_TEST_CRT_SET_HOOK( old_crt_hook );
|
||||
|
||||
@@ -1198,7 +1272,7 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
|
||||
BOOST_TEST_I_TRY {
|
||||
detail::fpe_except_guard G( p_detect_fp_exceptions );
|
||||
unit_test::ut_detail::ignore_unused_variable_warning( G );
|
||||
boost::ignore_unused( G );
|
||||
|
||||
return catch_signals( F );
|
||||
}
|
||||
@@ -1217,6 +1291,16 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
"std::string: %s", ex.c_str() ); }
|
||||
|
||||
// boost::exception (before std::exception, with extended diagnostic)
|
||||
catch( boost::exception const& ex )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
&ex,
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
"unknown boost::exception" ); }
|
||||
#else
|
||||
boost::diagnostic_information(ex).c_str() ); }
|
||||
#endif
|
||||
|
||||
// std:: exceptions
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
#define CATCH_AND_REPORT_STD_EXCEPTION( ex_name ) \
|
||||
@@ -1235,15 +1319,8 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
#endif
|
||||
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_alloc )
|
||||
|
||||
#if BOOST_WORKAROUND(__BORLANDC__, <= 0x0551)
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
|
||||
#else
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_cast )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_typeid )
|
||||
#endif
|
||||
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::bad_exception )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::domain_error )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::invalid_argument )
|
||||
@@ -1257,15 +1334,6 @@ execution_monitor::execute( boost::function<int ()> const& F )
|
||||
CATCH_AND_REPORT_STD_EXCEPTION( std::exception )
|
||||
#undef CATCH_AND_REPORT_STD_EXCEPTION
|
||||
|
||||
catch( boost::exception const& ex )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
&ex,
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
"unknown boost::exception" ); }
|
||||
#else
|
||||
typeid(ex).name() ); }
|
||||
#endif
|
||||
|
||||
// system errors
|
||||
catch( system_error const& ex )
|
||||
{ detail::report_error( execution_exception::cpp_exception_error,
|
||||
@@ -1342,6 +1410,12 @@ execution_exception::location::location( char const* file_name, size_t line_num,
|
||||
, m_function( func )
|
||||
{}
|
||||
|
||||
execution_exception::location::location(const_string file_name, size_t line_num, char const* func )
|
||||
: m_file_name( file_name )
|
||||
, m_line_num( line_num )
|
||||
, m_function( func )
|
||||
{}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
|
||||
@@ -27,12 +27,14 @@
|
||||
#include <boost/test/results_collector.hpp>
|
||||
#include <boost/test/progress_monitor.hpp>
|
||||
#include <boost/test/results_reporter.hpp>
|
||||
#include <boost/test/test_framework_init_observer.hpp>
|
||||
|
||||
#include <boost/test/tree/observer.hpp>
|
||||
#include <boost/test/tree/test_unit.hpp>
|
||||
#include <boost/test/tree/visitor.hpp>
|
||||
#include <boost/test/tree/traverse.hpp>
|
||||
#include <boost/test/tree/test_case_counter.hpp>
|
||||
#include <boost/test/tree/global_fixture.hpp>
|
||||
|
||||
#if BOOST_TEST_SUPPORT_TOKEN_ITERATOR
|
||||
#include <boost/test/utils/iterator/token_iterator.hpp>
|
||||
@@ -46,7 +48,7 @@
|
||||
#include <boost/test/detail/throw_exception.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/timer.hpp>
|
||||
#include <boost/test/utils/timer.hpp>
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
// STL
|
||||
@@ -56,6 +58,10 @@
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <numeric>
|
||||
#include <cmath>
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
#include <iterator>
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::time; using ::srand; }
|
||||
@@ -68,6 +74,7 @@ namespace std { using ::time; using ::srand; }
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace framework {
|
||||
|
||||
namespace impl {
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -342,12 +349,10 @@ public:
|
||||
, m_dep_collector( dep_collector )
|
||||
{}
|
||||
|
||||
private:
|
||||
// test_tree_visitor interface
|
||||
virtual bool visit( test_unit const& tu )
|
||||
{
|
||||
const_cast<test_unit&>(tu).p_run_status.value = m_new_status == test_unit::RS_INVALID ? tu.p_default_status : m_new_status;
|
||||
|
||||
if( m_dep_collector ) {
|
||||
BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) {
|
||||
test_unit const& dep = framework::get( dep_id, TUT_ANY );
|
||||
@@ -364,6 +369,7 @@ private:
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
test_unit::run_status m_new_status;
|
||||
test_unit_id_list* m_dep_collector;
|
||||
@@ -435,18 +441,59 @@ parse_filters( test_unit_id master_tu_id, test_unit_id_list& tu_to_enable, test_
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
|
||||
// a poor man's implementation of random_shuffle
|
||||
template< class RandomIt, class RandomFunc >
|
||||
void random_shuffle( RandomIt first, RandomIt last, RandomFunc &r )
|
||||
{
|
||||
typedef typename std::iterator_traits<RandomIt>::difference_type difference_type;
|
||||
difference_type n = last - first;
|
||||
for (difference_type i = n-1; i > 0; --i) {
|
||||
difference_type j = r(i+1);
|
||||
if (j != i) {
|
||||
using std::swap;
|
||||
swap(first[i], first[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// A simple handle for registering the global fixtures to the master test suite
|
||||
// without deleting an existing static object (the global fixture itself) when the program
|
||||
// terminates (shared_ptr).
|
||||
class global_fixture_handle : public test_unit_fixture {
|
||||
public:
|
||||
global_fixture_handle(test_unit_fixture* fixture) : m_global_fixture(fixture) {}
|
||||
~global_fixture_handle() {}
|
||||
|
||||
virtual void setup() {
|
||||
m_global_fixture->setup();
|
||||
}
|
||||
virtual void teardown() {
|
||||
m_global_fixture->teardown();
|
||||
}
|
||||
|
||||
private:
|
||||
test_unit_fixture* m_global_fixture;
|
||||
};
|
||||
|
||||
|
||||
} // namespace impl
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** framework::state ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
unsigned const TIMEOUT_EXCEEDED = static_cast<unsigned>( -1 );
|
||||
unsigned long int const TIMEOUT_EXCEEDED = static_cast<unsigned long int>( -1 );
|
||||
|
||||
class state {
|
||||
public:
|
||||
state()
|
||||
: m_curr_test_case( INV_TEST_UNIT_ID )
|
||||
: m_master_test_suite( 0 )
|
||||
, m_curr_test_unit( INV_TEST_UNIT_ID )
|
||||
, m_next_test_case_id( MIN_TEST_CASE_ID )
|
||||
, m_next_test_suite_id( MIN_TEST_SUITE_ID )
|
||||
, m_test_in_progress( false )
|
||||
@@ -565,13 +612,27 @@ public:
|
||||
|
||||
tu_to_enable.pop_back();
|
||||
|
||||
// 35. Ignore test units which already enabled
|
||||
// 35. Ignore test units which are already enabled
|
||||
if( tu.is_enabled() )
|
||||
continue;
|
||||
|
||||
// set new status and add all dependencies into tu_to_enable
|
||||
set_run_status enabler( test_unit::RS_ENABLED, &tu_to_enable );
|
||||
traverse_test_tree( tu.p_id, enabler, true );
|
||||
|
||||
// Add the dependencies of the parent suites, see trac #13149
|
||||
test_unit_id parent_id = tu.p_parent_id;
|
||||
while( parent_id != INV_TEST_UNIT_ID
|
||||
&& parent_id != master_tu_id )
|
||||
{
|
||||
// we do not use the traverse_test_tree as otherwise it would enable the sibblings and subtree
|
||||
// of the test case we want to enable (we need to enable the parent suites and their dependencies only)
|
||||
// the parent_id needs to be enabled in order to be properly parsed by finalize_run_status, the visit
|
||||
// does the job
|
||||
test_unit& tu_parent = framework::get( parent_id, TUT_ANY );
|
||||
enabler.visit( tu_parent );
|
||||
parent_id = tu_parent.p_parent_id;
|
||||
}
|
||||
}
|
||||
|
||||
// 40. Apply all disablers
|
||||
@@ -603,9 +664,9 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
// Executed the test tree with the root at specified test unit
|
||||
// Executes the test tree with the root at specified test unit
|
||||
execution_result execute_test_tree( test_unit_id tu_id,
|
||||
unsigned timeout = 0,
|
||||
unsigned long int timeout_microseconds = 0,
|
||||
random_generator_helper const * const p_random_generator = 0)
|
||||
{
|
||||
test_unit const& tu = framework::get( tu_id, TUT_ANY );
|
||||
@@ -617,15 +678,16 @@ public:
|
||||
|
||||
// 10. Check preconditions, including zero time left for execution and
|
||||
// successful execution of all dependencies
|
||||
if( timeout == TIMEOUT_EXCEEDED ) {
|
||||
if( timeout_microseconds == TIMEOUT_EXCEEDED ) {
|
||||
// notify all observers about skipped test unit
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
|
||||
to->test_unit_skipped( tu, "timeout for the test unit is exceeded" );
|
||||
|
||||
return unit_test_monitor_t::os_timeout;
|
||||
}
|
||||
else if( timeout == 0 || timeout > tu.p_timeout ) // deduce timeout for this test unit
|
||||
timeout = tu.p_timeout;
|
||||
else if( timeout_microseconds == 0 || (tu.p_timeout > 0 && timeout_microseconds > (tu.p_timeout * 1000000) ) ) // deduce timeout for this test unit
|
||||
timeout_microseconds = tu.p_timeout * 1000000;
|
||||
|
||||
|
||||
test_tools::assertion_result const precondition_res = tu.check_preconditions();
|
||||
if( !precondition_res ) {
|
||||
@@ -633,7 +695,10 @@ public:
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers )
|
||||
to->test_unit_skipped( tu, precondition_res.message() );
|
||||
|
||||
return unit_test_monitor_t::precondition_failure;
|
||||
// It is not an error to skip the test if any of the parent tests
|
||||
// have failed. This one should be reported as skipped as if it was
|
||||
// disabled
|
||||
return unit_test_monitor_t::test_ok;
|
||||
}
|
||||
|
||||
// 20. Notify all observers about the start of the test unit
|
||||
@@ -642,17 +707,27 @@ public:
|
||||
|
||||
// 30. Execute setup fixtures if any; any failure here leads to test unit abortion
|
||||
BOOST_TEST_FOREACH( test_unit_fixture_ptr, F, tu.p_fixtures.get() ) {
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(m_curr_test_unit, tu.p_id);
|
||||
result = unit_test_monitor.execute_and_translate( boost::bind( &test_unit_fixture::setup, F ) );
|
||||
if( result != unit_test_monitor_t::test_ok )
|
||||
break;
|
||||
test_results const& test_rslt = unit_test::results_collector.results( m_curr_test_unit );
|
||||
if( test_rslt.aborted() ) {
|
||||
result = unit_test_monitor_t::test_setup_failure;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// This is the time we are going to spend executing the test unit
|
||||
unsigned long elapsed = 0;
|
||||
// This is the time we are going to spend executing the test unit (in microseconds
|
||||
// as expected by test_observer::test_unit_finish)
|
||||
unsigned long elapsed_microseconds = 0;
|
||||
|
||||
if( result == unit_test_monitor_t::test_ok ) {
|
||||
// 40. We are going to time the execution
|
||||
boost::timer tu_timer;
|
||||
boost::unit_test::timer::timer tu_timer;
|
||||
|
||||
// we pass the random generator
|
||||
const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper();
|
||||
|
||||
if( tu.p_type == TUT_SUITE ) {
|
||||
test_suite const& ts = static_cast<test_suite const&>( tu );
|
||||
@@ -661,16 +736,33 @@ public:
|
||||
typedef std::pair<counter_t,test_unit_id> value_type;
|
||||
|
||||
BOOST_TEST_FOREACH( value_type, chld, ts.m_ranked_children ) {
|
||||
unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
|
||||
// tu_timer.elapsed() returns nanosec, timeout and child_timeout in microsec
|
||||
unsigned long int chld_timeout = child_timeout(
|
||||
timeout_microseconds,
|
||||
static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) ));
|
||||
|
||||
result = (std::min)( result, execute_test_tree( chld.second, chld_timeout ) );
|
||||
result = (std::min)( result, execute_test_tree( chld.second, chld_timeout, &rand_gen ) );
|
||||
|
||||
if( unit_test_monitor.is_critical_error( result ) )
|
||||
break;
|
||||
|
||||
// we check for the time elapsed. If this is too high, we fail the current suite and return from here
|
||||
elapsed_microseconds = static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) );
|
||||
|
||||
if( (timeout_microseconds > 0) && (elapsed_microseconds > timeout_microseconds) && (timeout_microseconds != TIMEOUT_EXCEEDED ) ) {
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers ) {
|
||||
to->test_unit_timed_out(tu);
|
||||
}
|
||||
result = (std::min)( result, unit_test_monitor_t::os_timeout );
|
||||
timeout_microseconds = TIMEOUT_EXCEEDED;
|
||||
//break;
|
||||
// we continue to explore the children, such that we can at least update their
|
||||
// status to skipped
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Go through ranges of chldren with the same dependency rank and shuffle them
|
||||
// Go through ranges of children with the same dependency rank and shuffle them
|
||||
// independently. Execute each subtree in this order
|
||||
test_unit_id_list children_with_the_same_rank;
|
||||
|
||||
@@ -686,22 +778,37 @@ public:
|
||||
it++;
|
||||
}
|
||||
|
||||
const random_generator_helper& rand_gen = p_random_generator ? *p_random_generator : random_generator_helper();
|
||||
|
||||
#ifdef BOOST_NO_CXX98_RANDOM_SHUFFLE
|
||||
impl::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end(), rand_gen );
|
||||
#else
|
||||
std::random_shuffle( children_with_the_same_rank.begin(), children_with_the_same_rank.end(), rand_gen );
|
||||
#endif
|
||||
|
||||
BOOST_TEST_FOREACH( test_unit_id, chld, children_with_the_same_rank ) {
|
||||
unsigned chld_timeout = child_timeout( timeout, tu_timer.elapsed() );
|
||||
unsigned long int chld_timeout = child_timeout(
|
||||
timeout_microseconds,
|
||||
static_cast<unsigned long int>(microsecond_wall_time(tu_timer.elapsed())) );
|
||||
|
||||
result = (std::min)( result, execute_test_tree( chld, chld_timeout, &rand_gen ) );
|
||||
|
||||
if( unit_test_monitor.is_critical_error( result ) )
|
||||
break;
|
||||
|
||||
// we check for the time elapsed. If this is too high, we fail the current suite and return from here
|
||||
elapsed_microseconds = static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) );
|
||||
if( (timeout_microseconds > 0) && (elapsed_microseconds > timeout_microseconds) && (timeout_microseconds != TIMEOUT_EXCEEDED ) ) {
|
||||
BOOST_TEST_FOREACH( test_observer*, to, m_observers ) {
|
||||
to->test_unit_timed_out(tu);
|
||||
}
|
||||
result = (std::min)( result, unit_test_monitor_t::os_timeout );
|
||||
timeout_microseconds = TIMEOUT_EXCEEDED;
|
||||
//break;
|
||||
// we continue to explore the children, such that we can at least update their
|
||||
// status to skipped
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elapsed = static_cast<unsigned long>( tu_timer.elapsed() * 1e6 );
|
||||
}
|
||||
else { // TUT_CASE
|
||||
test_case const& tc = static_cast<test_case const&>( tu );
|
||||
@@ -710,18 +817,16 @@ public:
|
||||
m_context_idx = 0;
|
||||
|
||||
// setup current test case
|
||||
test_unit_id bkup = m_curr_test_case;
|
||||
m_curr_test_case = tc.p_id;
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(m_curr_test_unit, tc.p_id);
|
||||
|
||||
// execute the test case body
|
||||
result = unit_test_monitor.execute_and_translate( tc.p_test_func, timeout );
|
||||
elapsed = static_cast<unsigned long>( tu_timer.elapsed() * 1e6 );
|
||||
// execute the test case body, transforms the time out to seconds
|
||||
result = unit_test_monitor.execute_and_translate( tc.p_test_func, timeout_microseconds );
|
||||
elapsed_microseconds = static_cast<unsigned long int>( microsecond_wall_time(tu_timer.elapsed()) );
|
||||
|
||||
// cleanup leftover context
|
||||
m_context.clear();
|
||||
|
||||
// restore state and abort if necessary
|
||||
m_curr_test_case = bkup;
|
||||
// restore state (scope exit) and abort if necessary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -729,6 +834,7 @@ public:
|
||||
if( !unit_test_monitor.is_critical_error( result ) ) {
|
||||
// execute teardown fixtures if any in reverse order
|
||||
BOOST_TEST_REVERSE_FOREACH( test_unit_fixture_ptr, F, tu.p_fixtures.get() ) {
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(m_curr_test_unit, tu.p_id);
|
||||
result = (std::min)( result, unit_test_monitor.execute_and_translate( boost::bind( &test_unit_fixture::teardown, F ), 0 ) );
|
||||
|
||||
if( unit_test_monitor.is_critical_error( result ) )
|
||||
@@ -744,21 +850,21 @@ public:
|
||||
|
||||
// notify all observers about completion
|
||||
BOOST_TEST_REVERSE_FOREACH( test_observer*, to, m_observers )
|
||||
to->test_unit_finish( tu, elapsed );
|
||||
to->test_unit_finish( tu, elapsed_microseconds );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
unsigned child_timeout( unsigned tu_timeout, double elapsed )
|
||||
unsigned long int child_timeout( unsigned long tu_timeout_microseconds, unsigned long elpsed_microsec )
|
||||
{
|
||||
if( tu_timeout == 0U )
|
||||
return 0U;
|
||||
if( tu_timeout_microseconds == 0UL || tu_timeout_microseconds == TIMEOUT_EXCEEDED)
|
||||
return tu_timeout_microseconds;
|
||||
|
||||
unsigned elpsed_sec = static_cast<unsigned>(elapsed); // rounding to number of whole seconds
|
||||
|
||||
return tu_timeout > elpsed_sec ? tu_timeout - elpsed_sec : TIMEOUT_EXCEEDED;
|
||||
return tu_timeout_microseconds > elpsed_microsec ?
|
||||
tu_timeout_microseconds - elpsed_microsec
|
||||
: TIMEOUT_EXCEEDED;
|
||||
}
|
||||
|
||||
struct priority_order {
|
||||
@@ -787,7 +893,7 @@ public:
|
||||
master_test_suite_t* m_master_test_suite;
|
||||
std::vector<test_suite*> m_auto_test_suites;
|
||||
|
||||
test_unit_id m_curr_test_case;
|
||||
test_unit_id m_curr_test_unit;
|
||||
test_unit_store m_test_units;
|
||||
|
||||
test_unit_id m_next_test_case_id;
|
||||
@@ -799,6 +905,8 @@ public:
|
||||
context_data m_context;
|
||||
int m_context_idx;
|
||||
|
||||
std::set<global_fixture*> m_global_fixtures;
|
||||
|
||||
boost::execution_monitor m_aux_em;
|
||||
|
||||
std::map<output_format, runtime_config::stream_holder> m_log_sinks;
|
||||
@@ -838,6 +946,30 @@ struct sum_to_first_only {
|
||||
bool is_first;
|
||||
};
|
||||
|
||||
void
|
||||
shutdown_loggers_and_reports()
|
||||
{
|
||||
s_frk_state().m_log_sinks.clear();
|
||||
s_frk_state().m_report_sink.setup( "stderr" );
|
||||
}
|
||||
|
||||
void
|
||||
unregister_global_fixture_and_configuration()
|
||||
{
|
||||
// we make a copy as the set will change in the iteration
|
||||
std::set<global_fixture*> gfixture_copy(s_frk_state().m_global_fixtures);
|
||||
BOOST_TEST_FOREACH( global_fixture*, tuf, gfixture_copy ) {
|
||||
tuf->unregister_from_framework();
|
||||
}
|
||||
s_frk_state().m_global_fixtures.clear();
|
||||
|
||||
state::observer_store gobserver_copy(s_frk_state().m_observers);
|
||||
BOOST_TEST_FOREACH( test_observer*, to, gobserver_copy ) {
|
||||
framework::deregister_observer( *to );
|
||||
}
|
||||
s_frk_state().m_observers.clear();
|
||||
}
|
||||
|
||||
void
|
||||
setup_loggers()
|
||||
{
|
||||
@@ -857,8 +989,15 @@ setup_loggers()
|
||||
unit_test_log.set_format( format );
|
||||
|
||||
runtime_config::stream_holder& stream_logger = s_frk_state().m_log_sinks[format];
|
||||
if( runtime_config::has( runtime_config::btrt_log_sink ) )
|
||||
stream_logger.setup( runtime_config::get<std::string>( runtime_config::btrt_log_sink ) );
|
||||
if( runtime_config::has( runtime_config::btrt_log_sink ) ) {
|
||||
// we remove all streams in this case, so we do not specify the format
|
||||
boost::function< void () > log_cleaner = boost::bind( &unit_test_log_t::set_stream,
|
||||
&unit_test_log,
|
||||
boost::ref(std::cout)
|
||||
);
|
||||
stream_logger.setup( runtime_config::get<std::string>( runtime_config::btrt_log_sink ),
|
||||
log_cleaner );
|
||||
}
|
||||
unit_test_log.set_stream( stream_logger.ref() );
|
||||
}
|
||||
else
|
||||
@@ -970,7 +1109,6 @@ setup_loggers()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOST_TEST_I_ASSRT( formatter_log_level != invalid_log_level,
|
||||
boost::runtime::access_to_missing_argument()
|
||||
<< "Unable to determine the log level from '"
|
||||
@@ -985,12 +1123,18 @@ setup_loggers()
|
||||
unit_test_log.set_threshold_level( format, formatter_log_level );
|
||||
|
||||
runtime_config::stream_holder& stream_logger = s_frk_state().m_log_sinks[format];
|
||||
boost::function< void () > log_cleaner = boost::bind( &unit_test_log_t::set_stream,
|
||||
&unit_test_log,
|
||||
format,
|
||||
boost::ref(std::cout) );
|
||||
if( ++current_format_specs != utils::string_token_iterator() &&
|
||||
current_format_specs->size() ) {
|
||||
stream_logger.setup( *current_format_specs );
|
||||
stream_logger.setup( *current_format_specs,
|
||||
log_cleaner );
|
||||
}
|
||||
else {
|
||||
stream_logger.setup( formatter->get_default_stream_description() );
|
||||
stream_logger.setup( formatter->get_default_stream_description(),
|
||||
log_cleaner );
|
||||
}
|
||||
unit_test_log.set_stream( format, stream_logger.ref() );
|
||||
}
|
||||
@@ -1036,13 +1180,20 @@ init( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
results_reporter::set_level( runtime_config::get<report_level>( runtime_config::btrt_report_level ) );
|
||||
results_reporter::set_format( runtime_config::get<output_format>( runtime_config::btrt_report_format ) );
|
||||
|
||||
if( runtime_config::has( runtime_config::btrt_report_sink ) )
|
||||
s_frk_state().m_report_sink.setup( runtime_config::get<std::string>( runtime_config::btrt_report_sink ) );
|
||||
if( runtime_config::has( runtime_config::btrt_report_sink ) ) {
|
||||
boost::function< void () > report_cleaner = boost::bind( &results_reporter::set_stream,
|
||||
boost::ref(std::cerr)
|
||||
);
|
||||
s_frk_state().m_report_sink.setup( runtime_config::get<std::string>( runtime_config::btrt_report_sink ),
|
||||
report_cleaner );
|
||||
}
|
||||
|
||||
results_reporter::set_stream( s_frk_state().m_report_sink.ref() );
|
||||
|
||||
// 40. Register default test observers
|
||||
register_observer( results_collector );
|
||||
register_observer( unit_test_log );
|
||||
register_observer( framework_init_observer );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_show_progress ) ) {
|
||||
progress_monitor.set_stream( std::cout ); // defaults to stdout
|
||||
@@ -1078,9 +1229,18 @@ finalize_setup_phase( test_unit_id master_tu_id )
|
||||
master_tu_id = master_test_suite().p_id;
|
||||
|
||||
// 10. Apply all decorators to the auto test units
|
||||
// 10. checks for consistency (duplicate names, etc)
|
||||
class apply_decorators : public test_tree_visitor {
|
||||
private:
|
||||
// test_tree_visitor interface
|
||||
|
||||
virtual bool test_suite_start( test_suite const& ts)
|
||||
{
|
||||
const_cast<test_suite&>(ts).generate();
|
||||
const_cast<test_suite&>(ts).check_for_duplicate_test_cases();
|
||||
return test_tree_visitor::test_suite_start(ts);
|
||||
}
|
||||
|
||||
virtual bool visit( test_unit const& tu )
|
||||
{
|
||||
BOOST_TEST_FOREACH( decorator::base_ptr, d, tu.p_decorators.get() )
|
||||
@@ -1116,6 +1276,13 @@ test_in_progress()
|
||||
void
|
||||
shutdown()
|
||||
{
|
||||
// shuts down the loggers singleton to avoid any further reference to the
|
||||
// framework during the destruction of those
|
||||
impl::shutdown_loggers_and_reports();
|
||||
|
||||
// unregisters any global fixture and configuration object
|
||||
impl::unregister_global_fixture_and_configuration();
|
||||
|
||||
// eliminating some fake memory leak reports. See for more details:
|
||||
// http://connect.microsoft.com/VisualStudio/feedback/details/106937/memory-leaks-reported-by-debug-crt-inside-typeinfo-name
|
||||
|
||||
@@ -1235,6 +1402,30 @@ deregister_observer( test_observer& to )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** register_global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
register_global_fixture( global_fixture& tuf )
|
||||
{
|
||||
impl::s_frk_state().m_global_fixtures.insert( &tuf );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** deregister_global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
deregister_global_fixture( global_fixture &tuf )
|
||||
{
|
||||
impl::s_frk_state().m_global_fixtures.erase( &tuf );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** add_context ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -1363,7 +1554,14 @@ current_auto_test_suite( test_suite* ts, bool push_or_pop )
|
||||
test_case const&
|
||||
current_test_case()
|
||||
{
|
||||
return get<test_case>( impl::s_frk_state().m_curr_test_case );
|
||||
return get<test_case>( impl::s_frk_state().m_curr_test_unit );
|
||||
}
|
||||
|
||||
|
||||
test_unit const&
|
||||
current_test_unit()
|
||||
{
|
||||
return *impl::s_frk_state().m_test_units[impl::s_frk_state().m_curr_test_unit];
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -1371,7 +1569,7 @@ current_test_case()
|
||||
test_unit_id
|
||||
current_test_case_id()
|
||||
{
|
||||
return impl::s_frk_state().m_curr_test_case;
|
||||
return impl::s_frk_state().m_curr_test_unit;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -1396,6 +1594,17 @@ get( test_unit_id id, test_unit_type t )
|
||||
// ************** framework::run ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template <class Cont>
|
||||
struct swap_on_delete {
|
||||
swap_on_delete(Cont& c1, Cont& c2) : m_c1(c1), m_c2(c2){}
|
||||
~swap_on_delete() {
|
||||
m_c1.swap(m_c2);
|
||||
}
|
||||
|
||||
Cont& m_c1;
|
||||
Cont& m_c2;
|
||||
};
|
||||
|
||||
void
|
||||
run( test_unit_id id, bool continue_test )
|
||||
{
|
||||
@@ -1414,39 +1623,93 @@ run( test_unit_id id, bool continue_test )
|
||||
|
||||
bool was_in_progress = framework::test_in_progress();
|
||||
bool call_start_finish = !continue_test || !was_in_progress;
|
||||
|
||||
impl::s_frk_state().m_test_in_progress = true;
|
||||
bool init_ok = true;
|
||||
const_string setup_error;
|
||||
|
||||
if( call_start_finish ) {
|
||||
// indicates the framework that no test is in progress now if observers need to be notified
|
||||
impl::s_frk_state().m_test_in_progress = false;
|
||||
// unit_test::framework_init_observer will get cleared first
|
||||
BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers ) {
|
||||
BOOST_TEST_I_TRY {
|
||||
impl::s_frk_state().m_aux_em.vexecute( boost::bind( &test_observer::test_start, to, tcc.p_count ) );
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(impl::s_frk_state().m_curr_test_unit, id);
|
||||
unit_test_monitor_t::error_level result = unit_test_monitor.execute_and_translate( boost::bind( &test_observer::test_start, to, tcc.p_count ) );
|
||||
if( init_ok ) {
|
||||
if( result != unit_test_monitor_t::test_ok ) {
|
||||
init_ok = false;
|
||||
}
|
||||
else {
|
||||
if( unit_test::framework_init_observer.has_failed() ) {
|
||||
init_ok = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BOOST_TEST_I_CATCH( execution_exception, ex ) {
|
||||
BOOST_TEST_SETUP_ASSERT( false, ex.what() );
|
||||
if( init_ok ) {
|
||||
// log only the first error
|
||||
init_ok = false;
|
||||
setup_error = ex.what();
|
||||
}
|
||||
// break; // we should continue otherwise loggers may have improper structure (XML start missing for instance)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned seed = runtime_config::get<unsigned>( runtime_config::btrt_random_seed );
|
||||
switch( seed ) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
seed = static_cast<unsigned>( std::rand() ^ std::time( 0 ) ); // better init using std::rand() ^ ...
|
||||
default:
|
||||
BOOST_TEST_FRAMEWORK_MESSAGE( "Test cases order is shuffled using seed: " << seed );
|
||||
std::srand( seed );
|
||||
if( init_ok ) {
|
||||
|
||||
// attaching the global fixtures to the main entry point
|
||||
test_unit& entry_test_unit = framework::get( id, TUT_ANY );
|
||||
std::vector<test_unit_fixture_ptr> v_saved_fixture(entry_test_unit.p_fixtures.value.begin(),
|
||||
entry_test_unit.p_fixtures.value.end());
|
||||
|
||||
BOOST_TEST_FOREACH( test_unit_fixture*, tuf, impl::s_frk_state().m_global_fixtures ) {
|
||||
entry_test_unit.p_fixtures.value.insert( entry_test_unit.p_fixtures.value.begin(),
|
||||
test_unit_fixture_ptr(new impl::global_fixture_handle(tuf)) );
|
||||
}
|
||||
|
||||
swap_on_delete< std::vector<test_unit_fixture_ptr> > raii_fixture(v_saved_fixture, entry_test_unit.p_fixtures.value);
|
||||
|
||||
// now work in progress
|
||||
impl::s_frk_state().m_test_in_progress = true;
|
||||
unsigned seed = runtime_config::get<unsigned>( runtime_config::btrt_random_seed );
|
||||
switch( seed ) {
|
||||
case 0:
|
||||
break;
|
||||
case 1:
|
||||
seed = static_cast<unsigned>( std::rand() ^ std::time( 0 ) ); // better init using std::rand() ^ ...
|
||||
BOOST_FALLTHROUGH;
|
||||
default:
|
||||
BOOST_TEST_FRAMEWORK_MESSAGE( "Test cases order is shuffled using seed: " << seed );
|
||||
std::srand( seed );
|
||||
}
|
||||
|
||||
// executing the test tree
|
||||
impl::s_frk_state().execute_test_tree( id );
|
||||
|
||||
// removing previously added global fixtures: dtor raii_fixture
|
||||
}
|
||||
|
||||
impl::s_frk_state().execute_test_tree( id );
|
||||
impl::s_frk_state().m_test_in_progress = false;
|
||||
|
||||
results_reporter::make_report( INV_REPORT_LEVEL, id );
|
||||
|
||||
unit_test::framework_init_observer.clear();
|
||||
if( call_start_finish ) {
|
||||
BOOST_TEST_REVERSE_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
|
||||
// indicates the framework that no test is in progress anymore if observers need to be notified
|
||||
// and this is a teardown, so assertions should not raise any exception otherwise an exception
|
||||
// might be raised in a dtor of a global fixture
|
||||
impl::s_frk_state().m_test_in_progress = false;
|
||||
BOOST_TEST_REVERSE_FOREACH( test_observer*, to, impl::s_frk_state().m_observers ) {
|
||||
ut_detail::test_unit_id_restore restore_current_test_unit(impl::s_frk_state().m_curr_test_unit, id);
|
||||
to->test_finish();
|
||||
}
|
||||
}
|
||||
|
||||
impl::s_frk_state().m_test_in_progress = was_in_progress;
|
||||
|
||||
// propagates the init/teardown error if any
|
||||
BOOST_TEST_SETUP_ASSERT( init_ok && !unit_test::framework_init_observer.has_failed(), setup_error );
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -1496,6 +1759,18 @@ test_unit_aborted( test_unit const& tu )
|
||||
to->test_unit_aborted( tu );
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** test_aborted ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
test_aborted( )
|
||||
{
|
||||
BOOST_TEST_FOREACH( test_observer*, to, impl::s_frk_state().m_observers )
|
||||
to->test_aborted( );
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace framework
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
|
||||
// Boost
|
||||
#include <boost/version.hpp>
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
@@ -69,6 +70,12 @@ inline std::string tu_name_normalize(std::string full_name)
|
||||
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( "\\/" );
|
||||
@@ -86,7 +93,7 @@ const_string file_basename(const_string filename) {
|
||||
// ************************************************************************** //
|
||||
|
||||
void
|
||||
junit_log_formatter::log_start( std::ostream& ostr, counter_t test_cases_amount)
|
||||
junit_log_formatter::log_start( std::ostream& /*ostr*/, counter_t /*test_cases_amount*/)
|
||||
{
|
||||
map_tests.clear();
|
||||
list_path_to_root.clear();
|
||||
@@ -96,6 +103,11 @@ junit_log_formatter::log_start( std::ostream& ostr, counter_t test_cases_amount)
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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,
|
||||
@@ -111,10 +123,19 @@ public:
|
||||
, m_display_build_info(display_build_info)
|
||||
{ }
|
||||
|
||||
void add_log_entry(std::string const& entry_type,
|
||||
test_case const& tc,
|
||||
junit_impl::junit_log_helper::assertion_entry const& log) const
|
||||
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
|
||||
@@ -159,24 +180,24 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
std::list<std::string> build_skipping_chain(test_case const & tc) const
|
||||
std::list<std::string> build_skipping_chain(test_unit const & tu) const
|
||||
{
|
||||
// we enter here because we know that the tc has been skipped.
|
||||
// either junit has not seen this tc, or it is indicated as disabled
|
||||
assert(m_map_test.count(tc.p_id) == 0 || results_collector.results( tc.p_id ).p_skipped);
|
||||
// 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(tc.p_id);
|
||||
test_unit_id id(tu.p_id);
|
||||
while( id != m_ts.p_id && id != INV_TEST_UNIT_ID) {
|
||||
test_unit const& tu = boost::unit_test::framework::get( id, TUT_ANY );
|
||||
out.push_back("- disabled test unit: '" + tu.full_name() + "'\n");
|
||||
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.p_parent_id;
|
||||
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() )
|
||||
@@ -188,9 +209,9 @@ public:
|
||||
return out;
|
||||
}
|
||||
|
||||
std::string get_class_name(test_case const & tc) const {
|
||||
std::string get_class_name(test_unit const & tu_class) const {
|
||||
std::string classname;
|
||||
test_unit_id id(tc.p_parent_id);
|
||||
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;
|
||||
@@ -205,39 +226,50 @@ public:
|
||||
return classname;
|
||||
}
|
||||
|
||||
void write_testcase_header(test_case const & tc,
|
||||
test_results const *tr = 0) const
|
||||
void write_testcase_header(test_unit const & tu,
|
||||
test_results const *tr,
|
||||
int nb_assertions) const
|
||||
{
|
||||
//
|
||||
// test case header
|
||||
std::string name;
|
||||
std::string classname;
|
||||
|
||||
// total number of assertions
|
||||
m_stream << "<testcase assertions" << utils::attr_value() << tr->p_assertions_passed + tr->p_assertions_failed;
|
||||
if(tu.p_id == m_ts.p_id ) {
|
||||
name = "boost_test";
|
||||
}
|
||||
else {
|
||||
classname = get_class_name(tu);
|
||||
name = tu_name_normalize(tu.p_name);
|
||||
}
|
||||
|
||||
// class name
|
||||
const std::string classname = get_class_name(tc);
|
||||
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() << tu_name_normalize(tc.p_name)
|
||||
<< " 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_case const * tc,
|
||||
bool skipped,
|
||||
test_results const *tr = 0) const
|
||||
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(*tc);
|
||||
for(std::list<std::string>::const_iterator it(skipping_decision_chain.begin()), ite(skipping_decision_chain.end());
|
||||
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)
|
||||
{
|
||||
@@ -246,7 +278,7 @@ public:
|
||||
}
|
||||
|
||||
// stdout
|
||||
for(std::list<std::string>::const_iterator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end());
|
||||
for(list_str_citerator it(detailed_log.system_out.begin()), ite(detailed_log.system_out.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
@@ -254,25 +286,24 @@ public:
|
||||
}
|
||||
|
||||
// warning/info message last
|
||||
for(std::vector< junit_impl::junit_log_helper::assertion_entry >::const_iterator it(detailed_log.assertion_entries.begin());
|
||||
for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
if(it->log_entry != junit_impl::junit_log_helper::assertion_entry::log_entry_info)
|
||||
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_case const * tc,
|
||||
test_results const *tr = 0) const
|
||||
test_unit const * tu,
|
||||
test_results const *tr) const
|
||||
{
|
||||
// system-err output + test case informations
|
||||
bool has_failed = (tr != 0) ? !tr->passed() : false;
|
||||
bool has_failed = (tr != 0) ? !tr->p_skipped && !tr->passed() : false;
|
||||
if(!detailed_log.system_err.empty() || has_failed)
|
||||
{
|
||||
conditional_cdata_helper system_err_helper(m_stream, "system-err");
|
||||
std::ostringstream o;
|
||||
if(has_failed) {
|
||||
o << "Failures detected in:" << std::endl;
|
||||
@@ -281,58 +312,89 @@ public:
|
||||
o << "ERROR STREAM:" << std::endl;
|
||||
}
|
||||
|
||||
o << "- test case: " << tc->full_name() << std::endl;
|
||||
if(!tc->p_description.value.empty())
|
||||
o << " '" << tc->p_description << "'";
|
||||
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(tc->p_file_name) << std::endl
|
||||
<< "- line: " << tc->p_line_num << std::endl
|
||||
;
|
||||
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;
|
||||
|
||||
system_err_helper(o.str());
|
||||
for(std::list<std::string>::const_iterator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end());
|
||||
for(list_str_citerator it(detailed_log.system_err.begin()), ite(detailed_log.system_err.end());
|
||||
it != ite;
|
||||
++it)
|
||||
{
|
||||
system_err_helper(*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_case const & tc,
|
||||
test_unit const & tu,
|
||||
bool skipped,
|
||||
test_results const *tr = 0) const
|
||||
test_results const *tr) const
|
||||
{
|
||||
write_testcase_header(tc, tr);
|
||||
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(std::vector< junit_impl::junit_log_helper::assertion_entry >::const_iterator it(detailed_log.assertion_entries.begin());
|
||||
for(vect_assertion_entry_citerator it(detailed_log.assertion_entries.begin());
|
||||
it != detailed_log.assertion_entries.end();
|
||||
++it)
|
||||
{
|
||||
if(it->log_entry == junit_impl::junit_log_helper::assertion_entry::log_entry_failure) {
|
||||
add_log_entry("failure", tc, *it);
|
||||
}
|
||||
else if(it->log_entry == junit_impl::junit_log_helper::assertion_entry::log_entry_error) {
|
||||
add_log_entry("error", tc, *it);
|
||||
}
|
||||
add_log_entry(*it);
|
||||
}
|
||||
}
|
||||
|
||||
write_testcase_system_out(detailed_log, &tc, skipped, tr);
|
||||
write_testcase_system_err(detailed_log, &tc, tr);
|
||||
write_testcase_system_out(detailed_log, &tu, skipped);
|
||||
write_testcase_system_err(detailed_log, &tu, tr);
|
||||
m_stream << "</testcase>" << std::endl;
|
||||
}
|
||||
|
||||
@@ -353,35 +415,58 @@ public:
|
||||
|
||||
bool test_suite_start( test_suite const& ts )
|
||||
{
|
||||
// unique test suite, without s, nesting not supported in CI
|
||||
if( m_ts.p_id != ts.p_id )
|
||||
return true;
|
||||
|
||||
test_results const& tr = results_collector.results( ts.p_id );
|
||||
m_stream << "<testsuite";
|
||||
|
||||
m_stream
|
||||
// << "disabled=\"" << tr.p_test_cases_skipped << "\" "
|
||||
<< " tests" << utils::attr_value() << tr.p_test_cases_passed
|
||||
<< " skipped" << utils::attr_value() << tr.p_test_cases_skipped
|
||||
<< " errors" << utils::attr_value() << tr.p_test_cases_aborted
|
||||
<< " failures" << utils::attr_value() << tr.p_test_cases_failed
|
||||
<< " id" << utils::attr_value() << m_id++
|
||||
<< " name" << utils::attr_value() << tu_name_normalize(ts.p_name)
|
||||
<< " time" << utils::attr_value() << (tr.p_duration_microseconds * 1E-6)
|
||||
<< ">" << std::endl;
|
||||
// unique test suite, without s, nesting not supported in CI
|
||||
if( m_ts.p_id == ts.p_id ) {
|
||||
m_stream << "<testsuite";
|
||||
|
||||
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;
|
||||
// think about: maybe we should add the number of fixtures of a test_suite as
|
||||
// independant 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;
|
||||
|
||||
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(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
|
||||
@@ -389,13 +474,13 @@ public:
|
||||
|
||||
virtual void test_suite_finish( test_suite const& ts )
|
||||
{
|
||||
if( m_ts.p_id != ts.p_id )
|
||||
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;
|
||||
|
||||
write_testcase_system_out(runner_log, 0, false, 0);
|
||||
write_testcase_system_err(runner_log, 0, 0);
|
||||
|
||||
m_stream << "</testsuite>";
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
@@ -439,15 +524,15 @@ junit_log_formatter::log_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_build_info( std::ostream& ostr )
|
||||
junit_log_formatter::log_build_info( std::ostream& /*ostr*/, bool log_build_info )
|
||||
{
|
||||
m_display_build_info = true;
|
||||
m_display_build_info = log_build_info;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu )
|
||||
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
|
||||
@@ -457,17 +542,20 @@ junit_log_formatter::test_unit_start( std::ostream& ostr, test_unit const& tu )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_finish( std::ostream& ostr, test_unit const& tu, unsigned long elapsed )
|
||||
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& os, test_unit const& tu )
|
||||
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();
|
||||
}
|
||||
@@ -475,7 +563,26 @@ junit_log_formatter::test_unit_aborted( std::ostream& os, test_unit const& tu )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu, const_string reason )
|
||||
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.
|
||||
@@ -487,7 +594,7 @@ junit_log_formatter::test_unit_skipped( std::ostream& ostr, test_unit const& tu,
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_data const& checkpoint_data, execution_exception const& ex )
|
||||
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();
|
||||
@@ -555,7 +662,7 @@ junit_log_formatter::log_exception_start( std::ostream& ostr, log_checkpoint_dat
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_exception_finish( std::ostream& ostr )
|
||||
junit_log_formatter::log_exception_finish( std::ostream& /*ostr*/ )
|
||||
{
|
||||
// sealing the last entry
|
||||
assert(!get_current_log_entry().assertion_entries.back().sealed);
|
||||
@@ -565,7 +672,7 @@ junit_log_formatter::log_exception_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const& entry_data, log_entry_types let )
|
||||
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;
|
||||
@@ -578,7 +685,7 @@ junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const&
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
// no break on purpose
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_MESSAGE:
|
||||
{
|
||||
@@ -586,7 +693,7 @@ junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const&
|
||||
last_entry.skipping = true;
|
||||
break;
|
||||
}
|
||||
// no break on purpose
|
||||
BOOST_FALLTHROUGH;
|
||||
}
|
||||
case unit_test_log_formatter::BOOST_UTL_ET_WARNING:
|
||||
{
|
||||
@@ -638,7 +745,7 @@ junit_log_formatter::log_entry_start( std::ostream& ostr, log_entry_data const&
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
|
||||
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)
|
||||
@@ -662,7 +769,7 @@ junit_log_formatter::log_entry_value( std::ostream& ostr, const_string value )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_finish( std::ostream& ostr )
|
||||
junit_log_formatter::log_entry_finish( std::ostream& /*ostr*/ )
|
||||
{
|
||||
junit_impl::junit_log_helper& last_entry = get_current_log_entry();
|
||||
if(!last_entry.skipping)
|
||||
@@ -685,7 +792,7 @@ junit_log_formatter::log_entry_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::entry_context_start( std::ostream& ostr, log_level )
|
||||
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)
|
||||
@@ -708,7 +815,7 @@ junit_log_formatter::entry_context_start( std::ostream& ostr, log_level )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
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();
|
||||
@@ -720,7 +827,7 @@ junit_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
junit_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr )
|
||||
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)
|
||||
|
||||
@@ -108,6 +108,8 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
|
||||
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
|
||||
@@ -122,8 +124,9 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
|
||||
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;
|
||||
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:";
|
||||
@@ -134,6 +137,8 @@ plain_report_formatter::test_unit_report_start( test_unit const& tu, std::ostrea
|
||||
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" );
|
||||
@@ -174,6 +179,12 @@ plain_report_formatter::do_confirmation_report( test_unit const& tu, std::ostrea
|
||||
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";
|
||||
|
||||
@@ -52,7 +52,7 @@ struct progress_display {
|
||||
<< "\n|----|----|----|----|----|----|----|----|----|----|"
|
||||
<< std::endl;
|
||||
|
||||
if( !m_expected_count )
|
||||
if( !m_expected_count )
|
||||
m_expected_count = 1; // prevent divide by zero
|
||||
}
|
||||
|
||||
@@ -63,7 +63,7 @@ struct progress_display {
|
||||
|
||||
// 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.
|
||||
// to suppress spurious compiler warnings.
|
||||
unsigned int tics_needed = static_cast<unsigned int>(
|
||||
(static_cast<double>(m_count)/m_expected_count)*50.0 );
|
||||
|
||||
@@ -121,6 +121,10 @@ progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; retu
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(progress_monitor_t)
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
progress_monitor_t::test_start( counter_t test_cases_amount )
|
||||
{
|
||||
|
||||
@@ -5,11 +5,9 @@
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description : implements Unit Test results collecting facility.
|
||||
/// @file
|
||||
/// Test results collecting facility.
|
||||
///
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
|
||||
@@ -19,6 +17,7 @@
|
||||
#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>
|
||||
@@ -52,11 +51,31 @@ test_results::test_results()
|
||||
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_aborted;
|
||||
// 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;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -65,7 +84,7 @@ int
|
||||
test_results::result_code() const
|
||||
{
|
||||
return passed() ? exit_success
|
||||
: ( (p_assertions_failed > p_expected_failures || p_skipped )
|
||||
: ( (p_assertions_failed > p_expected_failures || p_skipped || p_timed_out || p_test_cases_timed_out )
|
||||
? exit_test_failure
|
||||
: exit_exception_failure );
|
||||
}
|
||||
@@ -75,6 +94,7 @@ test_results::result_code() const
|
||||
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;
|
||||
@@ -83,6 +103,8 @@ test_results::operator+=( test_results const& tr )
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -91,6 +113,7 @@ test_results::operator+=( test_results const& tr )
|
||||
void
|
||||
test_results::clear()
|
||||
{
|
||||
p_test_suites.value = 0;
|
||||
p_assertions_passed.value = 0;
|
||||
p_assertions_failed.value = 0;
|
||||
p_warnings_failed.value = 0;
|
||||
@@ -100,9 +123,12 @@ test_results::clear()
|
||||
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;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -123,6 +149,10 @@ results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; re
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL( results_collector_t )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::test_start( counter_t )
|
||||
{
|
||||
@@ -159,6 +189,8 @@ public:
|
||||
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 )
|
||||
m_tr.p_test_cases_skipped.value++;
|
||||
else {
|
||||
@@ -174,6 +206,10 @@ public:
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -192,6 +228,8 @@ results_collector_t::test_unit_finish( test_unit const& tu, unsigned long elapse
|
||||
results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
|
||||
|
||||
traverse_test_tree( tu, ch );
|
||||
|
||||
s_rc_impl().m_results_store[tu.p_id].p_duration_microseconds.value = elapsed_in_microseconds;
|
||||
}
|
||||
else {
|
||||
test_results & tr = s_rc_impl().m_results_store[tu.p_id];
|
||||
@@ -213,7 +251,6 @@ 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;
|
||||
@@ -228,6 +265,15 @@ results_collector_t::test_unit_skipped( test_unit const& tu, const_string /*reas
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
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 )
|
||||
{
|
||||
@@ -246,11 +292,14 @@ results_collector_t::assertion_result( unit_test::assertion_result ar )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
results_collector_t::exception_caught( execution_exception const& )
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
117
winx64/include/boost/test/impl/test_framework_init_observer.ipp
Normal file
117
winx64/include/boost/test/impl/test_framework_init_observer.ipp
Normal file
@@ -0,0 +1,117 @@
|
||||
// (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 ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace {
|
||||
|
||||
struct test_init_observer_check {
|
||||
bool has_failure;
|
||||
|
||||
void clear()
|
||||
{
|
||||
has_failure = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
test_init_observer_check& s_tioc_impl() { static test_init_observer_check the_inst; return the_inst; }
|
||||
|
||||
} // local namespace
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL(framework_init_observer_t)
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::clear()
|
||||
{
|
||||
if(!framework::test_in_progress())
|
||||
s_tioc_impl().clear();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::test_start( counter_t )
|
||||
{
|
||||
clear();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::assertion_result( unit_test::assertion_result ar )
|
||||
{
|
||||
test_init_observer_check& tr = s_tioc_impl();
|
||||
switch( ar ) {
|
||||
case AR_TRIGGERED: break;
|
||||
case AR_PASSED: break;
|
||||
case AR_FAILED: tr.has_failure = true; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
framework_init_observer_t::exception_caught( execution_exception const& )
|
||||
{
|
||||
test_init_observer_check& tr = s_tioc_impl();
|
||||
tr.has_failure = true;
|
||||
}
|
||||
|
||||
void
|
||||
framework_init_observer_t::test_aborted()
|
||||
{
|
||||
s_tioc_impl().has_failure = true;
|
||||
}
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
bool
|
||||
framework_init_observer_t::has_failed() const
|
||||
{
|
||||
return s_tioc_impl().has_failure;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_FRAMEWORK_INIT_OBSERVER_IPP_021105GER
|
||||
@@ -16,6 +16,7 @@
|
||||
#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>
|
||||
@@ -59,6 +60,13 @@ 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 {
|
||||
@@ -119,14 +127,6 @@ print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const*
|
||||
ostr << ( t ? t : L"null string" );
|
||||
}
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
void
|
||||
print_log_value<std::nullptr_t>::operator()( std::ostream& ostr, std::nullptr_t p )
|
||||
{
|
||||
ostr << "nullptr";
|
||||
}
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -310,8 +310,19 @@ report_assertion( assertion_result const& ar,
|
||||
{
|
||||
using namespace unit_test;
|
||||
|
||||
BOOST_TEST_I_ASSRT( framework::current_test_case_id() != INV_TEST_UNIT_ID,
|
||||
std::runtime_error( "Can't use testing tools outside of test case implementation." ) );
|
||||
if( !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;
|
||||
@@ -369,10 +380,11 @@ report_assertion( assertion_result const& ar,
|
||||
|
||||
case REQUIRE:
|
||||
framework::assertion_result( AR_FAILED );
|
||||
|
||||
framework::test_unit_aborted( framework::current_test_case() );
|
||||
|
||||
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_UNREACHABLE_RETURN(false);
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -493,7 +505,7 @@ struct output_test_stream::Impl
|
||||
|
||||
char get_char()
|
||||
{
|
||||
char res;
|
||||
char res = 0;
|
||||
do {
|
||||
m_pattern.get( res );
|
||||
} while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );
|
||||
@@ -619,6 +631,7 @@ output_test_stream::match_pattern( bool flush_stream )
|
||||
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 ) {
|
||||
@@ -698,7 +711,7 @@ output_test_stream::match_pattern( bool flush_stream )
|
||||
if( last_elements_ordered[pattern_start_index + k] == sub_str_suffix[stream_start_index + k] )
|
||||
nb_char_in_common ++;
|
||||
else
|
||||
break; // we take fully macthing substring only
|
||||
break; // we take fully matching substring only
|
||||
}
|
||||
|
||||
if( nb_char_in_common > max_nb_char_in_common ) {
|
||||
@@ -709,20 +722,32 @@ output_test_stream::match_pattern( bool flush_stream )
|
||||
}
|
||||
}
|
||||
|
||||
// indicates with more precision the location of the mismatchs in ascii arts ...
|
||||
// indicates with more precision the location of the mismatchs in "ascii arts" ...
|
||||
result.message() << " ...\n... ";
|
||||
for( std::string::size_type j = 0; j < sub_str_prefix.size(); j++) {
|
||||
result.message() << ' ';
|
||||
}
|
||||
|
||||
for( std::size_t k = 0; k < (std::max)(best_pattern_start_index, best_stream_start_index); k++ ) { // 1 is for the current char c
|
||||
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 = (std::max)(s1.size(), s2.size()); h > 0; h--)
|
||||
result.message() << "~";
|
||||
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];
|
||||
|
||||
@@ -30,12 +30,10 @@
|
||||
|
||||
#include <boost/test/unit_test_parameters.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/timer.hpp>
|
||||
|
||||
// STL
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
@@ -124,7 +122,7 @@ test_unit::check_preconditions() const
|
||||
test_results const& test_rslt = unit_test::results_collector.results( dep_id );
|
||||
if( !test_rslt.passed() ) {
|
||||
test_tools::assertion_result res(false);
|
||||
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << "\" has failed";
|
||||
res.message() << "dependency test " << dep.p_type_name << " \"" << dep.full_name() << (test_rslt.skipped() ? "\" was skipped":"\" has failed");
|
||||
return res;
|
||||
}
|
||||
|
||||
@@ -223,7 +221,7 @@ test_case::test_case( const_string name, const_string file_name, std::size_t lin
|
||||
//____________________________________________________________________________//
|
||||
|
||||
test_suite::test_suite( const_string name, const_string file_name, std::size_t line_num )
|
||||
: test_unit( name, file_name, line_num, static_cast<test_unit_type>(type) )
|
||||
: test_unit( ut_detail::normalize_test_case_name( name ), file_name, line_num, static_cast<test_unit_type>(type) )
|
||||
{
|
||||
framework::register_test_unit( this );
|
||||
}
|
||||
@@ -266,19 +264,80 @@ test_suite::add( test_unit_generator const& gen, unsigned timeout )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
test_suite::add( test_unit_generator const& gen, decorator::collector& decorators )
|
||||
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 )
|
||||
{
|
||||
@@ -380,9 +439,25 @@ normalize_test_case_name( const_string name )
|
||||
|
||||
if( name[0] == '&' )
|
||||
norm_name = norm_name.substr( 1 );
|
||||
|
||||
std::replace(norm_name.begin(), norm_name.end(), ' ', '_');
|
||||
std::replace(norm_name.begin(), norm_name.end(), ':', '_');
|
||||
|
||||
// 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;
|
||||
}
|
||||
@@ -393,7 +468,7 @@ normalize_test_case_name( const_string name )
|
||||
// ************** auto_test_unit_registrar ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail )
|
||||
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 );
|
||||
|
||||
@@ -403,7 +478,7 @@ auto_test_unit_registrar::auto_test_unit_registrar( test_case* tc, decorator::co
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators )
|
||||
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 );
|
||||
|
||||
@@ -426,11 +501,19 @@ auto_test_unit_registrar::auto_test_unit_registrar( const_string ts_name, const_
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators )
|
||||
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 )
|
||||
@@ -446,9 +529,49 @@ auto_test_unit_registrar::auto_test_unit_registrar( int )
|
||||
// ************** global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
global_fixture::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();
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -159,6 +159,10 @@ unit_test_log_impl& s_log_impl() { static unit_test_log_impl the_inst; return th
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
BOOST_TEST_SINGLETON_CONS_IMPL( unit_test_log_t )
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
unit_test_log_t::test_start( counter_t test_cases_amount )
|
||||
{
|
||||
@@ -168,8 +172,11 @@ unit_test_log_t::test_start( counter_t test_cases_amount )
|
||||
|
||||
current_logger_data.m_log_formatter->log_start( current_logger_data.stream(), test_cases_amount );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_build_info ) )
|
||||
current_logger_data.m_log_formatter->log_build_info( current_logger_data.stream() );
|
||||
current_logger_data.m_log_formatter->log_build_info(
|
||||
current_logger_data.stream(),
|
||||
runtime_config::get<bool>( runtime_config::btrt_build_info ));
|
||||
|
||||
//current_logger_data.stream().flush();
|
||||
|
||||
current_logger_data.m_entry_in_progress = false;
|
||||
}
|
||||
@@ -261,6 +268,20 @@ unit_test_log_t::test_unit_aborted( test_unit const& 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();
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( !current_logger_data.m_enabled || current_logger_data.get_log_level() > log_test_units )
|
||||
continue;
|
||||
|
||||
current_logger_data.m_log_formatter->test_unit_timed_out(current_logger_data.stream(), tu );
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
@@ -472,14 +493,14 @@ unit_test_log_t::log_entry_context( log_level l )
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), frame );
|
||||
current_logger_data.m_log_formatter->log_entry_context( current_logger_data.stream(), l, frame );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_enabled ) {
|
||||
current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream() );
|
||||
current_logger_data.m_log_formatter->entry_context_finish( current_logger_data.stream(), l );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -523,6 +544,17 @@ unit_test_log_t::set_stream( output_format log_format, std::ostream& str )
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream*
|
||||
unit_test_log_t::get_stream( output_format log_format ) const
|
||||
{
|
||||
BOOST_TEST_FOREACH( unit_test_log_data_helper_impl&, current_logger_data, s_log_impl().m_log_formatter_data ) {
|
||||
if( current_logger_data.m_format == log_format) {
|
||||
return current_logger_data.m_stream;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
#include <iterator>
|
||||
#include <set>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
@@ -174,18 +175,34 @@ private:
|
||||
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_TEST_I_TRY {
|
||||
|
||||
framework::init( init_func, argc, argv );
|
||||
|
||||
if( runtime_config::get<bool>( runtime_config::btrt_wait_for_debugger ) ) {
|
||||
@@ -230,8 +247,6 @@ unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
|
||||
framework::run();
|
||||
|
||||
results_reporter::make_report();
|
||||
|
||||
result_code = !runtime_config::get<bool>( runtime_config::btrt_result_code )
|
||||
? boost::exit_success
|
||||
: results_collector.results( framework::master_test_suite().p_id ).result_code();
|
||||
@@ -249,14 +264,17 @@ unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
framework::shutdown();
|
||||
|
||||
return result_code;
|
||||
}
|
||||
|
||||
|
||||
@@ -29,16 +29,19 @@
|
||||
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 timeout )
|
||||
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;
|
||||
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 );
|
||||
@@ -47,7 +50,7 @@ unit_test_monitor_t::execute_and_translate( boost::function<void ()> const& func
|
||||
}
|
||||
BOOST_TEST_I_CATCH( execution_exception, ex ) {
|
||||
framework::exception_caught( ex );
|
||||
framework::test_unit_aborted( framework::current_test_case() );
|
||||
framework::test_unit_aborted( framework::current_test_unit() );
|
||||
|
||||
// translate execution_exception::error_code to error_level
|
||||
switch( ex.code() ) {
|
||||
|
||||
@@ -43,7 +43,6 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
#include <boost/optional.hpp>
|
||||
#include <boost/cstdlib.hpp>
|
||||
|
||||
// STL
|
||||
@@ -112,7 +111,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Automatically attaches debugger in case of system level failure (signal).",
|
||||
rt::env_var = "BOOST_TEST_AUTO_START_DBG",
|
||||
|
||||
rt::help = "Option " + btrt_auto_start_dbg + " specifies whether Boost.Test should attempt "
|
||||
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 "
|
||||
@@ -145,7 +144,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option build_info( btrt_build_info, (
|
||||
rt::description = "Displays library build information.",
|
||||
rt::env_var = "BOOST_TEST_BUILD_INFO",
|
||||
rt::help = "Option " + btrt_build_info + " displays library build information, including: platform, "
|
||||
rt::help = "Displays library build information, including: platform, "
|
||||
"compiler, STL version and Boost version."
|
||||
));
|
||||
|
||||
@@ -164,7 +163,7 @@ register_parameters( rt::parameters_store& store )
|
||||
#else
|
||||
true,
|
||||
#endif
|
||||
rt::help = "If option " + btrt_catch_sys_errors + " has value no the frameworks does not attempt to catch "
|
||||
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
|
||||
@@ -183,9 +182,9 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option color_output( btrt_color_output, (
|
||||
rt::description = "Enables color output of the framework log and report messages.",
|
||||
rt::env_var = "BOOST_TEST_COLOR_OUTPUT",
|
||||
rt::help = "The framework is able to produce color output on systems which supports it. "
|
||||
"To enable this behavior set this option to yes. By default the framework "
|
||||
"does not produces color output."
|
||||
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 );
|
||||
@@ -197,7 +196,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option detect_fp_except( btrt_detect_fp_except, (
|
||||
rt::description = "Enables/disables floating point exceptions traps.",
|
||||
rt::env_var = "BOOST_TEST_DETECT_FP_EXCEPTIONS",
|
||||
rt::help = "Option " + btrt_detect_fp_except + " enables/disables hardware traps for the floating "
|
||||
rt::help = "Enables/disables hardware traps for the floating "
|
||||
"point exceptions (if supported on your platfrom)."
|
||||
));
|
||||
|
||||
@@ -212,7 +211,7 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::default_value = 1L,
|
||||
rt::optional_value = 1L,
|
||||
rt::value_hint = "<alloc order number>",
|
||||
rt::help = "Parameter " + btrt_detect_mem_leaks + " enables/disables memory leaks detection. "
|
||||
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 "
|
||||
@@ -242,9 +241,9 @@ register_parameters( rt::parameters_store& store )
|
||||
( "DOT", OF_DOT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_list_content + " instructs the framework to list the content "
|
||||
"of the test module instead of executing the test cases. Parameter accepts "
|
||||
"optional string value indicating the format of the output. Currently the "
|
||||
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."
|
||||
));
|
||||
@@ -285,7 +284,7 @@ register_parameters( rt::parameters_store& store )
|
||||
( "JUNIT", OF_JUNIT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_log_format + " allows to set the frameowrk's log format to one "
|
||||
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 "
|
||||
@@ -300,7 +299,7 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::log_level> log_level( btrt_log_level, (
|
||||
rt::description = "Specifies 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 =
|
||||
@@ -333,8 +332,8 @@ register_parameters( rt::parameters_store& store )
|
||||
( "nothing" , log_nothing )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_log_level + " allows to set the framework's log level. "
|
||||
"Log level defines the verbosity of testing log produced by a testing "
|
||||
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 "
|
||||
@@ -348,11 +347,11 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string> log_sink( btrt_log_sink, (
|
||||
rt::description = "Specifies log sink: stdout(default), stderr or file name.",
|
||||
rt::description = "Specifies log sink: stdout (default), stderr or file name.",
|
||||
rt::env_var = "BOOST_TEST_LOG_SINK",
|
||||
rt::value_hint = "<stderr|stdout|file name>",
|
||||
rt::help = "Parameter " + btrt_log_sink + " allows to set the log sink - location "
|
||||
"where we report the log to, thus it allows to easily redirect the "
|
||||
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."
|
||||
));
|
||||
@@ -380,9 +379,8 @@ register_parameters( rt::parameters_store& store )
|
||||
( "XML", OF_XML )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_output_format + " combines an effect of " + btrt_report_format +
|
||||
" and " + btrt_log_format + " parameters. This parameter has higher priority "
|
||||
"than either one of them. In other words if this parameter is specified "
|
||||
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 "
|
||||
@@ -398,9 +396,12 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::parameter<std::string,rt::REPEATABLE_PARAM> combined_logger( btrt_combined_logger, (
|
||||
rt::description = "Specifies log level and sink for one or several log format",
|
||||
rt::env_var = "BOOST_TEST_LOGGER",
|
||||
rt::value_hint = "log_format:log_level:log_sink",
|
||||
rt::help = "Parameter " + btrt_combined_logger + " allows to specify the logger type, level and sink\n"
|
||||
"in one command."
|
||||
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, "=" );
|
||||
@@ -415,14 +416,14 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::default_value = 0U,
|
||||
rt::optional_value = 1U,
|
||||
rt::value_hint = "<seed>",
|
||||
rt::help = "Parameter " + btrt_random_seed + " instructs the framework to execute the "
|
||||
"test cases in random order. This parameter accepts optional unsigned "
|
||||
"integer argument. By default test cases are executed in some specific "
|
||||
"order defined by order of test units in test files and dependency between "
|
||||
"test units. If parameter is specified without the argument value testing "
|
||||
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."
|
||||
"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, "=" );
|
||||
@@ -431,7 +432,7 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::output_format> report_format( btrt_report_format, (
|
||||
rt::description = "Specifies 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 =
|
||||
@@ -448,7 +449,7 @@ register_parameters( rt::parameters_store& store )
|
||||
( "XML", OF_XML )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_report_format + " allows to set the framework's report format "
|
||||
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 "
|
||||
@@ -463,7 +464,7 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::enum_parameter<unit_test::report_level> report_level( btrt_report_level, (
|
||||
rt::description = "Specifies 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 =
|
||||
@@ -482,9 +483,9 @@ register_parameters( rt::parameters_store& store )
|
||||
( "no", NO_REPORT )
|
||||
,
|
||||
#endif
|
||||
rt::help = "Parameter " + btrt_report_level + " allows to set the verbosity level of the "
|
||||
"testing result report generated by the framework. Use value 'no' to "
|
||||
"eliminate the results report completely."
|
||||
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, "=" );
|
||||
@@ -512,10 +513,10 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Specifies report sink: stderr(default), stdout or file name.",
|
||||
rt::env_var = "BOOST_TEST_REPORT_SINK",
|
||||
rt::value_hint = "<stderr|stdout|file name>",
|
||||
rt::help = "Parameter " + btrt_report_sink + " allows to set the result report sink - "
|
||||
"the location where the framework writes the result report to, thus it "
|
||||
"allows to easily redirect the result report to a file or a standard "
|
||||
"stream. By default the testing result report is directed to the "
|
||||
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."
|
||||
));
|
||||
|
||||
@@ -541,13 +542,13 @@ register_parameters( rt::parameters_store& store )
|
||||
///////////////////////////////////////////////
|
||||
|
||||
rt::parameter<std::string,rt::REPEATABLE_PARAM> tests_to_run( btrt_run_filters, (
|
||||
rt::description = "Filters, which test units to include or exclude from test module execution.",
|
||||
rt::description = "Filters which tests to execute.",
|
||||
rt::env_var = "BOOST_TEST_RUN_FILTERS",
|
||||
rt::value_hint = "<test unit filter>",
|
||||
rt::help = "Parameter " + btrt_run_filters + " allows to filter which test units to execute during "
|
||||
"testing. The framework supports both 'selection filters', which allow to select "
|
||||
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. The __UTF__ also supports "
|
||||
"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."
|
||||
@@ -576,8 +577,8 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option show_progress( btrt_show_progress, (
|
||||
rt::description = "Turns on progress display.",
|
||||
rt::env_var = "BOOST_TEST_SHOW_PROGRESS",
|
||||
rt::help = "Parameter " + btrt_show_progress + " instructs the framework to display test progress "
|
||||
"information. By default the test progress is not shown."
|
||||
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, "=" );
|
||||
@@ -590,9 +591,9 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Turns on/off usage of an alternative stack for signal handling.",
|
||||
rt::env_var = "BOOST_TEST_USE_ALT_STACK",
|
||||
rt::default_value = true,
|
||||
rt::help = "Parameter " + btrt_use_alt_stack + " instructs the framework to use alternative "
|
||||
"stack for signals processing, on platforms where they are supported. The feature "
|
||||
"is enabled by default, but can be disabled using this parameter."
|
||||
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 );
|
||||
@@ -603,9 +604,9 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::option wait_for_debugger( btrt_wait_for_debugger, (
|
||||
rt::description = "Forces test module to wait for button to be pressed before starting test run.",
|
||||
rt::env_var = "BOOST_TEST_WAIT_FOR_DEBUGGER",
|
||||
rt::help = "Parameter " + btrt_wait_for_debugger + " instructs the framework to pause before starting "
|
||||
"test units execution, so that you can attach a debugger to running test module. By "
|
||||
"default this parameters turned off."
|
||||
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, "=" );
|
||||
@@ -618,10 +619,10 @@ register_parameters( rt::parameters_store& store )
|
||||
rt::description = "Help for framework parameters.",
|
||||
rt::optional_value = std::string(),
|
||||
rt::value_hint = "<parameter name>",
|
||||
rt::help = "Parameter " + btrt_help + " displays help on the framework's parameters. "
|
||||
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 "
|
||||
"'--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."
|
||||
));
|
||||
@@ -675,17 +676,26 @@ init( int& argc, char** argv )
|
||||
// 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 );
|
||||
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 ) );
|
||||
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 ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -63,16 +63,18 @@ xml_log_formatter::log_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::log_build_info( std::ostream& ostr )
|
||||
xml_log_formatter::log_build_info( std::ostream& ostr, bool 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 << '\"'
|
||||
<< "/>";
|
||||
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 << '\"'
|
||||
<< "/>";
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -199,7 +201,7 @@ xml_log_formatter::entry_context_start( std::ostream& ostr, log_level )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
xml_log_formatter::entry_context_finish( std::ostream& ostr, log_level )
|
||||
{
|
||||
ostr << BOOST_TEST_L( "</Context>" );
|
||||
}
|
||||
@@ -207,7 +209,7 @@ xml_log_formatter::entry_context_finish( std::ostream& ostr )
|
||||
//____________________________________________________________________________//
|
||||
|
||||
void
|
||||
xml_log_formatter::log_entry_context( std::ostream& ostr, const_string context_descr )
|
||||
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>" );
|
||||
}
|
||||
|
||||
@@ -59,6 +59,8 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream&
|
||||
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
|
||||
@@ -70,14 +72,18 @@ xml_report_formatter::test_unit_report_start( test_unit const& tu, std::ostream&
|
||||
<< " 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;
|
||||
<< " 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_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 << '>';
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#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>
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
//
|
||||
//!@file
|
||||
//!@brief Included (vs. linked) version of Unit Test Framework
|
||||
// ***************************************************************************
|
||||
@@ -24,6 +25,7 @@
|
||||
#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>
|
||||
@@ -31,7 +33,6 @@
|
||||
#include <boost/test/impl/unit_test_monitor.ipp>
|
||||
#include <boost/test/impl/unit_test_parameters.ipp>
|
||||
#include <boost/test/impl/xml_log_formatter.ipp>
|
||||
#include <boost/test/impl/junit_log_formatter.ipp>
|
||||
#include <boost/test/impl/xml_report_formatter.ipp>
|
||||
|
||||
#include <boost/test/unit_test.hpp>
|
||||
|
||||
@@ -31,6 +31,9 @@
|
||||
#ifndef BOOST_TEST_MINIMAL_HPP_071894GER
|
||||
#define BOOST_TEST_MINIMAL_HPP_071894GER
|
||||
|
||||
#include <boost/config/header_deprecated.hpp>
|
||||
BOOST_HEADER_DEPRECATED( "Boost.Test minimal is deprecated. Please convert to the header only variant of Boost.Test." )
|
||||
|
||||
#define BOOST_CHECK(exp) \
|
||||
( (exp) \
|
||||
? static_cast<void>(0) \
|
||||
|
||||
@@ -36,7 +36,7 @@ public:
|
||||
// Formatter interface
|
||||
void log_start( std::ostream&, counter_t test_cases_amount );
|
||||
void log_finish( std::ostream& );
|
||||
void log_build_info( std::ostream& );
|
||||
void log_build_info( std::ostream&, bool );
|
||||
|
||||
void test_unit_start( std::ostream&, test_unit const& tu );
|
||||
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
|
||||
@@ -51,8 +51,8 @@ public:
|
||||
void log_entry_finish( std::ostream& );
|
||||
|
||||
void entry_context_start( std::ostream&, log_level );
|
||||
void log_entry_context( std::ostream&, const_string );
|
||||
void entry_context_finish( std::ostream& );
|
||||
void log_entry_context( std::ostream&, log_level l, const_string );
|
||||
void entry_context_finish( std::ostream&, log_level l );
|
||||
|
||||
protected:
|
||||
virtual void print_prefix( std::ostream&, const_string file, std::size_t line );
|
||||
|
||||
@@ -101,12 +101,13 @@ public:
|
||||
// Formatter interface
|
||||
void log_start( std::ostream&, counter_t test_cases_amount );
|
||||
void log_finish( std::ostream& );
|
||||
void log_build_info( std::ostream& );
|
||||
void log_build_info( std::ostream&, bool );
|
||||
|
||||
void test_unit_start( std::ostream&, test_unit const& tu );
|
||||
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
|
||||
void test_unit_skipped( std::ostream&, test_unit const& tu, const_string reason );
|
||||
void test_unit_aborted( std::ostream& os, test_unit const& tu );
|
||||
void test_unit_timed_out( std::ostream& os, test_unit const& tu);
|
||||
|
||||
void log_exception_start( std::ostream&, log_checkpoint_data const&, execution_exception const& ex );
|
||||
void log_exception_finish( std::ostream& );
|
||||
@@ -118,8 +119,8 @@ public:
|
||||
void log_entry_finish( std::ostream& );
|
||||
|
||||
void entry_context_start( std::ostream&, log_level );
|
||||
void log_entry_context( std::ostream&, const_string );
|
||||
void entry_context_finish( std::ostream& );
|
||||
void log_entry_context( std::ostream&, log_level, const_string );
|
||||
void entry_context_finish( std::ostream&, log_level );
|
||||
|
||||
//! Discards changes in the log level
|
||||
virtual void set_log_level(log_level ll)
|
||||
|
||||
@@ -39,7 +39,7 @@ public:
|
||||
// Formatter interface
|
||||
void log_start( std::ostream&, counter_t test_cases_amount );
|
||||
void log_finish( std::ostream& );
|
||||
void log_build_info( std::ostream& );
|
||||
void log_build_info( std::ostream&, bool );
|
||||
|
||||
void test_unit_start( std::ostream&, test_unit const& tu );
|
||||
void test_unit_finish( std::ostream&, test_unit const& tu, unsigned long elapsed );
|
||||
@@ -54,8 +54,8 @@ public:
|
||||
void log_entry_finish( std::ostream& );
|
||||
|
||||
void entry_context_start( std::ostream&, log_level );
|
||||
void log_entry_context( std::ostream&, const_string );
|
||||
void entry_context_finish( std::ostream& );
|
||||
void log_entry_context( std::ostream&, log_level, const_string );
|
||||
void entry_context_finish( std::ostream&, log_level );
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/unit_test_suite.hpp>
|
||||
#include <boost/test/utils/string_cast.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
@@ -65,6 +66,7 @@ public:
|
||||
, m_tc_line( tc_line )
|
||||
, m_par_begin( par_begin )
|
||||
, m_par_end( par_end )
|
||||
, m_index( 0 )
|
||||
{}
|
||||
|
||||
virtual test_unit* next() const
|
||||
@@ -72,9 +74,10 @@ public:
|
||||
if( m_par_begin == m_par_end )
|
||||
return (test_unit*)0;
|
||||
|
||||
test_unit* res = new test_case( m_tc_name, m_tc_file, m_tc_line, boost::bind( m_test_func, *m_par_begin ) );
|
||||
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;
|
||||
}
|
||||
@@ -87,6 +90,7 @@ private:
|
||||
std::size_t m_tc_line;
|
||||
mutable ParamIter m_par_begin;
|
||||
ParamIter m_par_end;
|
||||
mutable std::size_t m_index;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/tree/observer.hpp>
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
|
||||
// STL
|
||||
#include <iosfwd> // for std::ostream&
|
||||
@@ -31,7 +30,7 @@ namespace unit_test {
|
||||
// ************************************************************************** //
|
||||
|
||||
/// This class implements test observer interface and updates test progress as test units finish or get aborted
|
||||
class BOOST_TEST_DECL progress_monitor_t : public test_observer, public singleton<progress_monitor_t> {
|
||||
class BOOST_TEST_DECL progress_monitor_t : public test_observer {
|
||||
public:
|
||||
/// @name Test observer interface
|
||||
/// @{
|
||||
@@ -41,7 +40,7 @@ public:
|
||||
virtual void test_unit_finish( test_unit const&, unsigned long );
|
||||
virtual void test_unit_skipped( test_unit const&, const_string );
|
||||
|
||||
virtual int priority() { return 3; }
|
||||
virtual int priority() { return 4; }
|
||||
/// @}
|
||||
|
||||
/// @name Configuration
|
||||
@@ -49,7 +48,7 @@ public:
|
||||
void set_stream( std::ostream& );
|
||||
/// @}
|
||||
|
||||
private:
|
||||
/// Singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS( progress_monitor_t )
|
||||
}; // progress_monitor_t
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
#include <boost/test/detail/fwd_decl.hpp>
|
||||
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
#include <boost/test/utils/class_properties.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
@@ -63,6 +62,7 @@ public:
|
||||
(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
|
||||
@@ -72,13 +72,25 @@ public:
|
||||
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
|
||||
@@ -106,7 +118,7 @@ public:
|
||||
/// of the test tree.
|
||||
///
|
||||
/// @see boost::unit_test::test_observer
|
||||
class BOOST_TEST_DECL results_collector_t : public test_observer, public singleton<results_collector_t> {
|
||||
class BOOST_TEST_DECL results_collector_t : public test_observer {
|
||||
public:
|
||||
|
||||
virtual void test_start( counter_t );
|
||||
@@ -115,18 +127,19 @@ public:
|
||||
virtual void test_unit_finish( test_unit const&, unsigned long );
|
||||
virtual void test_unit_skipped( test_unit const&, const_string );
|
||||
virtual void test_unit_aborted( test_unit const& );
|
||||
virtual void test_unit_timed_out( test_unit const& );
|
||||
|
||||
virtual void assertion_result( unit_test::assertion_result );
|
||||
virtual void exception_caught( execution_exception const& );
|
||||
|
||||
virtual int priority() { return 2; }
|
||||
virtual int priority() { 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;
|
||||
|
||||
private:
|
||||
/// Singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS( results_collector_t )
|
||||
};
|
||||
|
||||
|
||||
61
winx64/include/boost/test/test_framework_init_observer.hpp
Normal file
61
winx64/include/boost/test/test_framework_init_observer.hpp
Normal file
@@ -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:
|
||||
|
||||
virtual void test_start( counter_t );
|
||||
|
||||
virtual void assertion_result( unit_test::assertion_result );
|
||||
virtual void exception_caught( execution_exception const& );
|
||||
virtual void test_aborted();
|
||||
|
||||
virtual int priority() { return 0; }
|
||||
|
||||
void clear();
|
||||
|
||||
/// Indicates if a failure has been recorded so far
|
||||
bool has_failed( ) const;
|
||||
|
||||
/// Singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS( framework_init_observer_t )
|
||||
};
|
||||
|
||||
BOOST_TEST_SINGLETON_INST( framework_init_observer )
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_FRAMEWORK_INIT_OBSERVER_HPP_071894GER
|
||||
@@ -277,7 +277,7 @@ public:
|
||||
}
|
||||
void report( std::ostream& ostr ) const
|
||||
{
|
||||
ostr << tt_detail::print_helper( m_value );
|
||||
ostr << tt_detail::print_helper( value() );
|
||||
}
|
||||
|
||||
// Mutating operators
|
||||
@@ -309,8 +309,11 @@ public:
|
||||
|
||||
private:
|
||||
template<typename U>
|
||||
static void format_message( wrap_stringstream& ostr, U const& v ) { ostr << "[(bool)" << v << " is false]"; }
|
||||
static void format_message( wrap_stringstream& /*ostr*/, bool /*v*/ ) {}
|
||||
static void format_message( wrap_stringstream& ostr, 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
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
// Boost
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/type_traits/decay.hpp>
|
||||
|
||||
@@ -38,6 +39,15 @@ namespace assertion {
|
||||
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<> \
|
||||
@@ -55,17 +65,21 @@ template <typename OP, bool can_be_equal, bool prefer_shorter,
|
||||
typename Lhs, typename Rhs>
|
||||
inline
|
||||
typename boost::enable_if_c<
|
||||
unit_test::is_forward_iterable<Lhs>::value && unit_test::is_forward_iterable<Rhs>::value,
|
||||
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 );
|
||||
|
||||
typename Lhs::const_iterator first1 = lhs.begin();
|
||||
typename Rhs::const_iterator first2 = rhs.begin();
|
||||
typename Lhs::const_iterator last1 = lhs.end();
|
||||
typename Rhs::const_iterator last2 = rhs.end();
|
||||
std::size_t pos = 0;
|
||||
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);
|
||||
@@ -113,8 +127,7 @@ 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),
|
||||
(unit_test::is_cstring<Lhs>::value || unit_test::is_cstring<Rhs>::value),
|
||||
assertion_result>::type
|
||||
lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
{
|
||||
@@ -122,8 +135,8 @@ lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type;
|
||||
|
||||
return lexicographic_compare<OP, can_be_equal, prefer_shorter>(
|
||||
boost::unit_test::basic_cstring<lhs_char_type>(lhs),
|
||||
boost::unit_test::basic_cstring<rhs_char_type>(rhs));
|
||||
lhs_char_type(lhs),
|
||||
rhs_char_type(rhs));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -135,23 +148,27 @@ lexicographic_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
template <typename OP, typename Lhs, typename Rhs>
|
||||
inline
|
||||
typename boost::enable_if_c<
|
||||
unit_test::is_forward_iterable<Lhs>::value && unit_test::is_forward_iterable<Rhs>::value,
|
||||
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( lhs.size() != rhs.size() ) {
|
||||
if( t_Lhs_iterator::size(lhs) != t_Rhs_iterator::size(rhs) ) {
|
||||
ar = false;
|
||||
ar.message() << "\nCollections size mismatch: " << lhs.size() << " != " << rhs.size();
|
||||
ar.message() << "\nCollections size mismatch: " << t_Lhs_iterator::size(lhs) << " != " << t_Rhs_iterator::size(rhs);
|
||||
return ar;
|
||||
}
|
||||
|
||||
typename Lhs::const_iterator left = lhs.begin();
|
||||
typename Rhs::const_iterator right = rhs.begin();
|
||||
std::size_t pos = 0;
|
||||
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 < lhs.size(); ++left, ++right, ++pos ) {
|
||||
for( ; pos < t_Lhs_iterator::size(lhs); ++left, ++right, ++pos ) {
|
||||
assertion_result const element_ar = OP::eval( *left, *right );
|
||||
if( element_ar )
|
||||
continue;
|
||||
@@ -171,16 +188,15 @@ element_compare( Lhs const& lhs, Rhs const& rhs )
|
||||
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),
|
||||
(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<Lhs>::type lhs_char_type;
|
||||
typedef typename unit_test::deduce_cstring<Rhs>::type rhs_char_type;
|
||||
|
||||
return element_compare<OP>(boost::unit_test::basic_cstring<lhs_char_type>(lhs),
|
||||
boost::unit_test::basic_cstring<rhs_char_type>(rhs));
|
||||
return element_compare<OP>(lhs_char_type(lhs),
|
||||
rhs_char_type(rhs));
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -193,14 +209,17 @@ 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( lhs.size() != rhs.size() )
|
||||
if( t_Lhs_iterator::size(lhs) != t_Rhs_iterator::size(rhs) )
|
||||
return ar;
|
||||
|
||||
typename Lhs::const_iterator left = lhs.begin();
|
||||
typename Rhs::const_iterator right = rhs.begin();
|
||||
typename Lhs::const_iterator end = lhs.end();
|
||||
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 ) )
|
||||
@@ -367,22 +386,34 @@ compare_collections( Lhs const& lhs, Rhs const& rhs, boost::type<op::GE<L, R> >*
|
||||
#define DEFINE_COLLECTION_COMPARISON( oper, name, rev ) \
|
||||
template<typename Lhs,typename Rhs> \
|
||||
struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
unit_test::is_forward_iterable<Lhs>::value \
|
||||
&& !unit_test::is_cstring<Lhs>::value \
|
||||
&& unit_test::is_forward_iterable<Rhs>::value \
|
||||
&& !unit_test::is_cstring<Rhs>::value>::type> { \
|
||||
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 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<is_same<typename decay<Lhs>::type, \
|
||||
typename decay<Rhs>::type>::value, \
|
||||
typename cctraits<OP>::is_specialized, \
|
||||
mpl::false_>::type is_specialized; \
|
||||
\
|
||||
typedef name<typename Lhs::value_type, \
|
||||
typename Rhs::value_type> elem_op; \
|
||||
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) \
|
||||
|
||||
@@ -17,6 +17,20 @@
|
||||
|
||||
// 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>
|
||||
|
||||
@@ -47,13 +61,30 @@ private:
|
||||
::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_TEST_CONTEXT( context_descr ) \
|
||||
if( ::boost::test_tools::tt_detail::context_frame BOOST_JOIN( context_frame_, __LINE__ ) = \
|
||||
::boost::test_tools::tt_detail::context_frame( BOOST_TEST_LAZY_MSG( context_descr ) ) ) \
|
||||
|
||||
#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
|
||||
|
||||
@@ -37,8 +37,8 @@ namespace op {
|
||||
#define DEFINE_CSTRING_COMPARISON( oper, name, rev ) \
|
||||
template<typename Lhs,typename Rhs> \
|
||||
struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
( unit_test::is_cstring<Lhs>::value \
|
||||
&& unit_test::is_cstring<Rhs>::value) \
|
||||
( unit_test::is_cstring_comparable<Lhs>::value \
|
||||
&& unit_test::is_cstring_comparable<Rhs>::value) \
|
||||
>::type > \
|
||||
{ \
|
||||
typedef typename unit_test::deduce_cstring<Lhs>::type lhs_char_type; \
|
||||
@@ -46,13 +46,14 @@ struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
public: \
|
||||
typedef assertion_result result_type; \
|
||||
\
|
||||
typedef name<lhs_char_type, rhs_char_type> elem_op; \
|
||||
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 unit_test::basic_cstring<lhs_char_type>(lhs) oper \
|
||||
unit_test::basic_cstring<rhs_char_type>(rhs); \
|
||||
return lhs_char_type(lhs) oper rhs_char_type(rhs); \
|
||||
} \
|
||||
\
|
||||
template<typename PrevExprType> \
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/mpl/or.hpp>
|
||||
@@ -28,6 +27,8 @@
|
||||
#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)
|
||||
@@ -166,8 +167,11 @@ struct BOOST_TEST_DECL print_log_value<wchar_t const*> {
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_NULLPTR)
|
||||
template<>
|
||||
struct BOOST_TEST_DECL print_log_value<std::nullptr_t> {
|
||||
void operator()( std::ostream& ostr, std::nullptr_t t );
|
||||
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
|
||||
|
||||
|
||||
@@ -197,9 +197,11 @@ fraction_tolerance( percent_tolerance_t<FPT> tolerance )
|
||||
/*!@brief Predicate for comparing floating point numbers
|
||||
*
|
||||
* This predicate is used to compare floating point numbers. In addition the comparison produces maximum
|
||||
* related differnce, which can be used to generate detailed error message
|
||||
* 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 {
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
// 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>
|
||||
@@ -38,22 +39,19 @@ namespace op {
|
||||
|
||||
template<typename OP>
|
||||
struct fpctraits {
|
||||
static const bool cmp_direct = true;
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct fpctraits<op::NE<Lhs,Rhs> > {
|
||||
static const bool cmp_direct = false;
|
||||
// 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 cmp_direct = false;
|
||||
static const bool equality_logical_disjunction = false;
|
||||
};
|
||||
|
||||
template <typename Lhs, typename Rhs>
|
||||
struct fpctraits<op::GT<Lhs,Rhs> > {
|
||||
static const bool cmp_direct = false;
|
||||
static const bool equality_logical_disjunction = false;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -62,48 +60,30 @@ struct fpctraits<op::GT<Lhs,Rhs> > {
|
||||
// ************** 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)
|
||||
// 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* )
|
||||
compare_fpv( Lhs const& lhs, Rhs const& rhs, OP* cmp_operator)
|
||||
{
|
||||
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_STRONG );
|
||||
|
||||
assertion_result ar( P( lhs, rhs ) );
|
||||
if( !ar )
|
||||
ar.message() << "Relative difference exceeds tolerance ["
|
||||
<< P.tested_rel_diff() << " > " << P.fraction_tolerance() << ']';
|
||||
return ar;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template <typename FPT, typename OP>
|
||||
inline assertion_result
|
||||
compare_fpv_near_zero( FPT const& fpv, OP* )
|
||||
{
|
||||
fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
|
||||
|
||||
assertion_result ar( P( fpv ) );
|
||||
if( !ar )
|
||||
ar.message() << "Absolute value exceeds tolerance [|" << fpv << "| > "<< fpc_tolerance<FPT>() << ']';
|
||||
|
||||
return ar;
|
||||
bool result = cmp_operator->eval_direct(lhs, rhs);
|
||||
if(fpctraits<OP>::equality_logical_disjunction) {
|
||||
return result || compare_fpv<FPT>(lhs, rhs, (op::EQ<Lhs, Rhs>*)0);
|
||||
}
|
||||
return result && compare_fpv<FPT>(lhs, rhs, (op::NE<Lhs, Rhs>*)0);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template <typename FPT, typename Lhs, typename Rhs>
|
||||
inline assertion_result
|
||||
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
|
||||
compare_fpv_near_zero( FPT const& fpv, op::EQ<Lhs,Rhs>* )
|
||||
{
|
||||
fpc::close_at_tolerance<FPT> P( fpc_tolerance<FPT>(), fpc::FPC_WEAK );
|
||||
fpc::small_with_tolerance<FPT> P( fpc_tolerance<FPT>() );
|
||||
|
||||
assertion_result ar( !P( lhs, rhs ) );
|
||||
assertion_result ar( P( fpv ) );
|
||||
if( !ar )
|
||||
ar.message() << "Relative difference is within tolerance ["
|
||||
<< P.tested_rel_diff() << " < " << fpc_tolerance<FPT>() << ']';
|
||||
ar.message() << "Absolute value exceeds tolerance [|" << fpv << "| > "<< fpc_tolerance<FPT>() << ']';
|
||||
|
||||
return ar;
|
||||
}
|
||||
@@ -126,34 +106,48 @@ compare_fpv_near_zero( FPT const& fpv, op::NE<Lhs,Rhs>* )
|
||||
|
||||
template <typename FPT, typename Lhs, typename Rhs>
|
||||
inline assertion_result
|
||||
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::LT<Lhs,Rhs>* )
|
||||
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::EQ<Lhs,Rhs>* )
|
||||
{
|
||||
return lhs >= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
|
||||
}
|
||||
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 );
|
||||
|
||||
template <typename FPT, typename Lhs, typename Rhs>
|
||||
inline assertion_result
|
||||
compare_fpv_near_zero( FPT const& fpv, op::LT<Lhs,Rhs>* )
|
||||
{
|
||||
return fpv >= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
|
||||
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::GT<Lhs,Rhs>* )
|
||||
compare_fpv( Lhs const& lhs, Rhs const& rhs, op::NE<Lhs,Rhs>* )
|
||||
{
|
||||
return lhs <= rhs ? assertion_result( false ) : compare_fpv<FPT>( lhs, rhs, (op::NE<Lhs,Rhs>*)0 );
|
||||
}
|
||||
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 );
|
||||
|
||||
template <typename FPT, typename Lhs, typename Rhs>
|
||||
inline assertion_result
|
||||
compare_fpv_near_zero( FPT const& fpv, op::GT<Lhs,Rhs>* )
|
||||
{
|
||||
return fpv <= 0 ? assertion_result( false ) : compare_fpv_near_zero( fpv, (op::NE<Lhs,Rhs>*)0 );
|
||||
}
|
||||
assertion_result ar( !P( lhs, rhs ) );
|
||||
if( !ar )
|
||||
ar.message() << "Relative difference is within tolerance ["
|
||||
<< P.tested_rel_diff() << " < " << fpc_tolerance<FPT>() << ']';
|
||||
|
||||
return ar;
|
||||
}
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -161,7 +155,12 @@ compare_fpv_near_zero( FPT const& fpv, op::GT<Lhs,Rhs>* )
|
||||
template<typename Lhs,typename Rhs> \
|
||||
struct name<Lhs,Rhs,typename boost::enable_if_c< \
|
||||
(fpc::tolerance_based<Lhs>::value && \
|
||||
fpc::tolerance_based<Rhs>::value)>::type> { \
|
||||
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; \
|
||||
@@ -177,22 +176,13 @@ public: \
|
||||
static assertion_result \
|
||||
eval( Lhs const& lhs, Rhs const& rhs ) \
|
||||
{ \
|
||||
if( lhs == 0 ) \
|
||||
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 compare_fpv_near_zero( rhs, (OP*)0 ); \
|
||||
} \
|
||||
\
|
||||
if( rhs == 0 ) \
|
||||
{ \
|
||||
return compare_fpv_near_zero( lhs, (OP*)0 ); \
|
||||
} \
|
||||
\
|
||||
bool direct_res = eval_direct( lhs, rhs ); \
|
||||
\
|
||||
if( (direct_res && fpctraits<OP>::cmp_direct) || \
|
||||
fpc_tolerance<FPT>() == FPT(0) ) \
|
||||
{ \
|
||||
return direct_res; \
|
||||
return eval_direct( lhs, rhs ); \
|
||||
} \
|
||||
\
|
||||
return compare_fpv<FPT>( lhs, rhs, (OP*)0 ); \
|
||||
@@ -227,4 +217,3 @@ BOOST_TEST_FOR_EACH_COMP_OP( DEFINE_FPV_COMPARISON )
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_TOOLS_FPC_OP_HPP_050915GER
|
||||
|
||||
|
||||
@@ -114,7 +114,7 @@ inline assertion_result equal_impl( char const* left, char* right ) { return equ
|
||||
inline assertion_result equal_impl( char* left, char* right ) { return equal_impl( static_cast<char const*>(left), static_cast<char const*>(right) ); }
|
||||
|
||||
#if !defined( BOOST_NO_CWCHAR )
|
||||
assertion_result BOOST_TEST_DECL equal_impl( wchar_t const* left, wchar_t const* right );
|
||||
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) ); }
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
#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>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -95,7 +97,7 @@ do {
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#define BOOST_CHECK_THROW_IMPL( S, E, P, postfix, TL ) \
|
||||
#define BOOST_CHECK_THROW_IMPL( S, E, P, postfix, TL ) \
|
||||
do { \
|
||||
try { \
|
||||
BOOST_TEST_PASSPOINT(); \
|
||||
@@ -103,9 +105,9 @@ do {
|
||||
BOOST_TEST_TOOL_IMPL( 2, false, "exception " BOOST_STRINGIZE(E) " expected but not raised", \
|
||||
TL, CHECK_MSG, _ ); \
|
||||
} catch( E const& ex ) { \
|
||||
::boost::unit_test::ut_detail::ignore_unused_variable_warning( ex ); \
|
||||
BOOST_TEST_TOOL_IMPL( 2, P, \
|
||||
"exception \"" BOOST_STRINGIZE( E )"\" raised as expected" postfix, \
|
||||
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() ) \
|
||||
|
||||
@@ -37,9 +37,10 @@ namespace ut_detail {
|
||||
|
||||
struct BOOST_TEST_DECL auto_test_unit_registrar {
|
||||
// Constructors
|
||||
auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail = 0 );
|
||||
explicit auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators );
|
||||
explicit auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators );
|
||||
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 );
|
||||
};
|
||||
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
#include <boost/test/tree/fixture.hpp>
|
||||
|
||||
#include <boost/test/tools/assertion_result.hpp>
|
||||
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/shared_ptr.hpp>
|
||||
@@ -46,35 +44,45 @@ class test_unit;
|
||||
namespace decorator {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::collector ************** //
|
||||
// ************** decorator::collector_t ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class base;
|
||||
typedef boost::shared_ptr<base> base_ptr;
|
||||
|
||||
class BOOST_TEST_DECL collector : public singleton<collector> {
|
||||
class BOOST_TEST_DECL collector_t {
|
||||
|
||||
public:
|
||||
collector& operator*( base const& d );
|
||||
collector_t& operator*( base const& d );
|
||||
|
||||
void store_in( test_unit& tu );
|
||||
|
||||
void reset();
|
||||
|
||||
void stack();
|
||||
|
||||
std::vector<base_ptr> get_lazy_decorators() const;
|
||||
|
||||
// singleton pattern without ctor
|
||||
BOOST_TEST_SINGLETON_CONS_NO_CTOR( collector_t )
|
||||
|
||||
private:
|
||||
BOOST_TEST_SINGLETON_CONS( collector )
|
||||
// Class invariant: minimal size is 1.
|
||||
collector_t() : m_tu_decorators_stack(1) {}
|
||||
|
||||
// Data members
|
||||
std::vector<base_ptr> m_tu_decorators;
|
||||
std::vector< std::vector<base_ptr> > m_tu_decorators_stack;
|
||||
};
|
||||
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::base ************** //
|
||||
// ************** decorator::base ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class BOOST_TEST_DECL base {
|
||||
public:
|
||||
// composition interface
|
||||
collector& operator*() const;
|
||||
virtual collector_t& operator*() const;
|
||||
|
||||
// application interface
|
||||
virtual void apply( test_unit& tu ) = 0;
|
||||
@@ -86,6 +94,30 @@ protected:
|
||||
virtual ~base() {}
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::stack_decorator ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
//!@ A decorator that creates a new stack in the collector
|
||||
//!
|
||||
//! This decorator may be used in places where the currently accumulated decorators
|
||||
//! in the collector should be applied to lower levels of the hierarchy rather
|
||||
//! than the current one. This is for instance for dataset test cases, where the
|
||||
//! macro does not let the user specify decorators for the underlying generated tests
|
||||
//! (but rather on the main generator function), applying the stack_decorator at the
|
||||
//! parent level lets us consume the decorator at the underlying test cases level.
|
||||
class BOOST_TEST_DECL stack_decorator : public decorator::base {
|
||||
public:
|
||||
explicit stack_decorator() {}
|
||||
|
||||
virtual collector_t& operator*() const;
|
||||
|
||||
private:
|
||||
// decorator::base interface
|
||||
virtual void apply( test_unit& tu );
|
||||
virtual base_ptr clone() const { return base_ptr(new stack_decorator()); }
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** decorator::label ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
@@ -5,11 +5,8 @@
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision: 74640 $
|
||||
//
|
||||
// Description : defines fixture interface and object makers
|
||||
/// @file
|
||||
/// Defines fixture interface and object makers
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_TREE_FIXTURE_HPP_100311GER
|
||||
@@ -22,6 +19,7 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
#include <boost/function/function0.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
@@ -45,6 +43,83 @@ public:
|
||||
|
||||
typedef shared_ptr<test_unit_fixture> test_unit_fixture_ptr;
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** fixture helper functions ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
namespace impl_fixture {
|
||||
|
||||
#if defined(BOOST_NO_CXX11_DECLTYPE) || defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
|
||||
|
||||
template<typename U, void (U::*)()> struct fixture_detect {};
|
||||
|
||||
template<typename T>
|
||||
struct has_setup {
|
||||
private:
|
||||
template<typename U> static char Test(fixture_detect<U, &U::setup>*);
|
||||
template<typename U> static int Test(...);
|
||||
public:
|
||||
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct has_teardown {
|
||||
private:
|
||||
template<typename U> static char Test(fixture_detect<U, &U::teardown>*);
|
||||
template<typename U> static int Test(...);
|
||||
public:
|
||||
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template<typename U> struct fixture_detect { typedef char type; };
|
||||
template<typename T>
|
||||
struct has_setup {
|
||||
private:
|
||||
template<typename U> static auto Test(U*) -> typename fixture_detect<decltype(boost::declval<U>().setup())>::type;
|
||||
template<typename U> static int Test(...);
|
||||
public:
|
||||
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct has_teardown {
|
||||
private:
|
||||
template<typename U> static auto Test(U*) -> typename fixture_detect<decltype(boost::declval<U>().teardown())>::type;
|
||||
template<typename U> static int Test(...);
|
||||
public:
|
||||
static const bool value = sizeof(Test<T>(0)) == sizeof(char);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
template <bool has_setup = false>
|
||||
struct call_setup { template <class U> void operator()(U& ) { } };
|
||||
|
||||
template <>
|
||||
struct call_setup<true> { template <class U> void operator()(U& u) { u.setup(); } };
|
||||
|
||||
template <bool has_teardown = false>
|
||||
struct call_teardown { template <class U> void operator()(U& ) { } };
|
||||
|
||||
template <>
|
||||
struct call_teardown<true> { template <class U> void operator()(U& u) { u.teardown(); } };
|
||||
}
|
||||
|
||||
//! Calls the fixture "setup" if detected by the compiler, otherwise does nothing.
|
||||
template <class U>
|
||||
void setup_conditional(U& u) {
|
||||
return impl_fixture::call_setup<impl_fixture::has_setup<U>::value>()(u);
|
||||
}
|
||||
|
||||
//! Calls the fixture "teardown" if detected by the compiler, otherwise does nothing.
|
||||
template <class U>
|
||||
void teardown_conditional(U& u) {
|
||||
return impl_fixture::call_teardown<impl_fixture::has_teardown<U>::value>()(u);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** class_based_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -57,8 +132,8 @@ public:
|
||||
|
||||
private:
|
||||
// Fixture interface
|
||||
virtual void setup() { m_inst.reset( new F( m_arg ) ); }
|
||||
virtual void teardown() { m_inst.reset(); }
|
||||
virtual void setup() { m_inst.reset( new F( m_arg ) ); setup_conditional(*m_inst); }
|
||||
virtual void teardown() { teardown_conditional(*m_inst); m_inst.reset(); }
|
||||
|
||||
// Data members
|
||||
scoped_ptr<F> m_inst;
|
||||
@@ -75,8 +150,8 @@ public:
|
||||
|
||||
private:
|
||||
// Fixture interface
|
||||
virtual void setup() { m_inst.reset( new F ); }
|
||||
virtual void teardown() { m_inst.reset(); }
|
||||
virtual void setup() { m_inst.reset( new F ); setup_conditional(*m_inst); }
|
||||
virtual void teardown() { teardown_conditional(*m_inst); m_inst.reset(); }
|
||||
|
||||
// Data members
|
||||
scoped_ptr<F> m_inst;
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
|
||||
#include <boost/test/tree/observer.hpp>
|
||||
#include <boost/test/tree/fixture.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
@@ -26,14 +27,53 @@
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** global_configuration ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class BOOST_TEST_DECL global_configuration : public test_observer {
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
global_configuration();
|
||||
|
||||
/// Unregisters the global fixture from the framework
|
||||
///
|
||||
/// This is called by the framework at shutdown time
|
||||
void unregister_from_framework();
|
||||
|
||||
// Dtor
|
||||
virtual ~global_configuration();
|
||||
|
||||
// Happens after the framework global observer init has been done
|
||||
virtual int priority() { return 1; }
|
||||
|
||||
private:
|
||||
bool registered;
|
||||
};
|
||||
|
||||
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** global_fixture ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class BOOST_TEST_DECL global_fixture : public test_observer {
|
||||
class BOOST_TEST_DECL global_fixture : public test_unit_fixture {
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
global_fixture();
|
||||
|
||||
/// Unregisters the global fixture from the framework
|
||||
///
|
||||
/// This is called by the framework at shutdown time
|
||||
void unregister_from_framework();
|
||||
|
||||
// Dtor
|
||||
virtual ~global_fixture();
|
||||
|
||||
private:
|
||||
bool registered;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -41,14 +81,48 @@ public:
|
||||
namespace ut_detail {
|
||||
|
||||
template<typename F>
|
||||
struct global_fixture_impl : public global_fixture {
|
||||
struct global_configuration_impl : public global_configuration {
|
||||
// Constructor
|
||||
global_fixture_impl() : m_fixture( 0 ) {}
|
||||
global_configuration_impl() : m_configuration_observer( 0 ) {
|
||||
}
|
||||
|
||||
// test observer interface
|
||||
virtual void test_start( counter_t ) { m_fixture = new F; }
|
||||
virtual void test_finish() { delete m_fixture; m_fixture = 0; }
|
||||
virtual void test_aborted() { delete m_fixture; m_fixture = 0; }
|
||||
virtual void test_start( counter_t ) {
|
||||
m_configuration_observer = new F;
|
||||
}
|
||||
|
||||
// test observer interface
|
||||
virtual void test_finish() {
|
||||
if(m_configuration_observer) {
|
||||
delete m_configuration_observer;
|
||||
m_configuration_observer = 0;
|
||||
}
|
||||
}
|
||||
private:
|
||||
// Data members
|
||||
F* m_configuration_observer;
|
||||
};
|
||||
|
||||
template<typename F>
|
||||
struct global_fixture_impl : public global_fixture {
|
||||
// Constructor
|
||||
global_fixture_impl() : m_fixture( 0 ) {
|
||||
}
|
||||
|
||||
// test fixture interface
|
||||
virtual void setup() {
|
||||
m_fixture = new F;
|
||||
setup_conditional(*m_fixture);
|
||||
}
|
||||
|
||||
// test fixture interface
|
||||
virtual void teardown() {
|
||||
if(m_fixture) {
|
||||
teardown_conditional(*m_fixture);
|
||||
}
|
||||
delete m_fixture;
|
||||
m_fixture = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
|
||||
@@ -34,7 +34,7 @@ namespace unit_test {
|
||||
/// Boost.Test framework on the current execution state.
|
||||
///
|
||||
/// Several observers can be running at the same time, and it is not unusual to
|
||||
/// have interactions among them. The test_observer#priority member function allows the specification
|
||||
/// have interactions among them. The @ref test_observer::priority member function allows the specification
|
||||
/// of a particular order among them (lowest priority executed first, except specified otherwise).
|
||||
///
|
||||
class BOOST_TEST_DECL test_observer {
|
||||
@@ -44,10 +44,8 @@ public:
|
||||
//!
|
||||
//! @param[in] number_of_test_cases indicates the number of test cases. Only active
|
||||
//! test cases are taken into account.
|
||||
//!
|
||||
virtual void test_start( counter_t /* number_of_test_cases */ ) {}
|
||||
|
||||
|
||||
//! Called after the framework ends executing the test cases
|
||||
//!
|
||||
//! @note The call is made with a reversed priority order.
|
||||
@@ -74,6 +72,12 @@ public:
|
||||
virtual void test_unit_skipped( test_unit const& tu, const_string ) { test_unit_skipped( tu ); }
|
||||
virtual void test_unit_skipped( test_unit const& ) {} ///< backward compatibility
|
||||
|
||||
//! Called when the test timed out
|
||||
//!
|
||||
//! This function is called to signal that a test unit (case or suite) timed out.
|
||||
//! A valid test unit is available through boost::unit_test::framework::current_test_unit
|
||||
virtual void test_unit_timed_out( test_unit const& ) {}
|
||||
|
||||
//! Called when a test unit indicates a fatal error.
|
||||
//!
|
||||
//! A fatal error happens when
|
||||
@@ -81,14 +85,8 @@ public:
|
||||
//! - an unexpected exception is caught by the Boost.Test framework
|
||||
virtual void test_unit_aborted( test_unit const& ) {}
|
||||
|
||||
virtual void assertion_result( unit_test::assertion_result ar )
|
||||
virtual void assertion_result( unit_test::assertion_result /* ar */ )
|
||||
{
|
||||
switch( ar ) {
|
||||
case AR_PASSED: assertion_result( true ); break;
|
||||
case AR_FAILED: assertion_result( false ); break;
|
||||
case AR_TRIGGERED: break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
//! Called when an exception is intercepted
|
||||
@@ -98,11 +96,11 @@ public:
|
||||
//! additional data about the exception.
|
||||
virtual void exception_caught( execution_exception const& ) {}
|
||||
|
||||
//! The priority indicates the order at which this observer is initialized
|
||||
//! and tore down in the UTF framework. The order is lowest to highest priority.
|
||||
virtual int priority() { return 0; }
|
||||
|
||||
protected:
|
||||
//! Deprecated
|
||||
virtual void assertion_result( bool /* passed */ ) {}
|
||||
|
||||
BOOST_TEST_PROTECTED_VIRTUAL ~test_observer() {}
|
||||
};
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <boost/test/detail/config.hpp>
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
#include <boost/test/detail/fwd_decl.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
#include <boost/test/tree/test_unit.hpp>
|
||||
|
||||
#include <boost/test/utils/class_properties.hpp>
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
#include <boost/type_traits/is_volatile.hpp>
|
||||
#include <boost/type_traits/is_lvalue_reference.hpp>
|
||||
#include <boost/type_traits/is_rvalue_reference.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
#include <boost/function/function0.hpp>
|
||||
|
||||
#if defined(BOOST_NO_TYPEID) || defined(BOOST_NO_RTTI)
|
||||
@@ -41,6 +45,12 @@
|
||||
#include <string> // for std::string
|
||||
#include <list> // for std::list
|
||||
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
|
||||
#include <type_traits>
|
||||
#include <boost/mpl/is_sequence.hpp>
|
||||
#endif
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
|
||||
@@ -64,7 +74,7 @@ public:
|
||||
// ************** generate_test_case_4_type ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename Generator,typename TestCaseTemplate>
|
||||
template<typename Generator, typename TestCaseTemplate>
|
||||
struct generate_test_case_4_type {
|
||||
explicit generate_test_case_4_type( const_string tc_name, const_string tc_file, std::size_t tc_line, Generator& G )
|
||||
: m_test_case_name( tc_name )
|
||||
@@ -84,8 +94,16 @@ struct generate_test_case_4_type {
|
||||
#else
|
||||
full_name += BOOST_CURRENT_FUNCTION;
|
||||
#endif
|
||||
if( boost::is_const<TestType>::value )
|
||||
typedef typename boost::remove_reference<TestType>::type TestTypewoRef;
|
||||
if( boost::is_const<TestTypewoRef>::value )
|
||||
full_name += "_const";
|
||||
if( boost::is_volatile<TestTypewoRef>::value )
|
||||
full_name += "_volatile";
|
||||
if( boost::is_rvalue_reference<TestType>::value )
|
||||
full_name += "_refref";
|
||||
else if( boost::is_lvalue_reference<TestType>::value )
|
||||
full_name += "_ref";
|
||||
|
||||
full_name += '>';
|
||||
|
||||
m_holder.m_test_cases.push_back( new test_case( ut_detail::normalize_test_case_name( full_name ),
|
||||
@@ -106,17 +124,8 @@ private:
|
||||
// ************** test_case_template ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename TestCaseTemplate,typename TestTypesList>
|
||||
class template_test_case_gen : public test_unit_generator {
|
||||
class template_test_case_gen_base : public test_unit_generator {
|
||||
public:
|
||||
// Constructor
|
||||
template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
|
||||
{
|
||||
typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
|
||||
|
||||
mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
|
||||
}
|
||||
|
||||
virtual test_unit* next() const
|
||||
{
|
||||
if( m_test_cases.empty() )
|
||||
@@ -132,6 +141,57 @@ public:
|
||||
mutable std::list<test_unit*> m_test_cases;
|
||||
};
|
||||
|
||||
template<typename TestCaseTemplate,typename TestTypesList, typename enabler = void>
|
||||
class template_test_case_gen : public template_test_case_gen_base {
|
||||
public:
|
||||
// Constructor
|
||||
template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
|
||||
{
|
||||
typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,TestCaseTemplate> single_test_gen;
|
||||
|
||||
mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, tc_file, tc_line, *this ) );
|
||||
}
|
||||
};
|
||||
|
||||
// Describing template test cases with tuples
|
||||
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
|
||||
!defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && \
|
||||
!defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
|
||||
|
||||
template<typename TestCaseTemplate,
|
||||
template <class ...> class C,
|
||||
typename... parameter_pack>
|
||||
class template_test_case_gen<
|
||||
TestCaseTemplate,
|
||||
C<parameter_pack...>,
|
||||
typename std::enable_if<!boost::mpl::is_sequence<C<parameter_pack...>>::value>::type >
|
||||
: public template_test_case_gen_base {
|
||||
|
||||
template<typename F>
|
||||
void for_each(F &f)
|
||||
{
|
||||
auto l = { (f(mpl::identity<parameter_pack>()), 0)... };
|
||||
(void)l; // silence warning
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
template_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line )
|
||||
{
|
||||
using this_type = template_test_case_gen<
|
||||
TestCaseTemplate,
|
||||
C<parameter_pack...>,
|
||||
typename std::enable_if<!boost::mpl::is_sequence<C<parameter_pack...>>::value>::type>;
|
||||
using single_test_gen = generate_test_case_4_type<this_type, TestCaseTemplate>;
|
||||
|
||||
single_test_gen op( tc_name, tc_file, tc_line, *this );
|
||||
|
||||
this->for_each(op);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* C++11 variadic, type alias */
|
||||
|
||||
} // namespace ut_detail
|
||||
} // unit_test
|
||||
} // namespace boost
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <boost/test/tree/decorator.hpp>
|
||||
#include <boost/test/tree/fixture.hpp>
|
||||
#include <boost/test/framework.hpp>
|
||||
|
||||
#include <boost/test/tools/assertion_result.hpp>
|
||||
|
||||
@@ -42,7 +43,7 @@ namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
namespace framework {
|
||||
class state;
|
||||
class state;
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -175,11 +176,21 @@ public:
|
||||
void add( test_unit_generator const& gen, unsigned timeout = 0 );
|
||||
|
||||
/// @overload
|
||||
void add( test_unit_generator const& gen, decorator::collector& decorators );
|
||||
void add( test_unit_generator const& gen, decorator::collector_t& decorators );
|
||||
|
||||
/// @overload
|
||||
void add( boost::shared_ptr<test_unit_generator> gen_ptr, decorator::collector_t& decorators );
|
||||
|
||||
//! Removes a test from the test suite.
|
||||
void remove( test_unit_id id );
|
||||
|
||||
//! Generates all the delayed test_units from the generators
|
||||
void generate( );
|
||||
|
||||
//! Check for duplicates name in test cases
|
||||
//!
|
||||
//! Raises a setup_error if there are duplicates
|
||||
void check_for_duplicate_test_cases();
|
||||
|
||||
// access methods
|
||||
test_unit_id get( const_string tu_name ) const;
|
||||
@@ -199,6 +210,8 @@ protected:
|
||||
|
||||
test_unit_id_list m_children;
|
||||
children_per_rank m_ranked_children; ///< maps child sibling rank to list of children with that rank
|
||||
|
||||
std::vector< std::pair<boost::shared_ptr<test_unit_generator>, std::vector<decorator::base_ptr> > > m_generators; /// lazy evaluation
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -206,12 +219,17 @@ protected:
|
||||
// ************************************************************************** //
|
||||
|
||||
class BOOST_TEST_DECL master_test_suite_t : public test_suite {
|
||||
public:
|
||||
private:
|
||||
master_test_suite_t();
|
||||
|
||||
master_test_suite_t(const master_test_suite_t&); // undefined
|
||||
master_test_suite_t& operator=(master_test_suite_t const &); // undefined
|
||||
|
||||
public:
|
||||
// Data members
|
||||
int argc;
|
||||
char** argv;
|
||||
|
||||
friend BOOST_TEST_DECL master_test_suite_t& boost::unit_test::framework::master_test_suite();
|
||||
};
|
||||
|
||||
// ************************************************************************** //
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
#include <boost/test/detail/fwd_decl.hpp>
|
||||
|
||||
#include <boost/test/utils/wrap_stringstream.hpp>
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
#include <boost/test/utils/lazy_ostream.hpp>
|
||||
|
||||
// Boost
|
||||
@@ -109,7 +108,7 @@ private:
|
||||
/// @see
|
||||
/// - boost::unit_test::test_observer
|
||||
/// - boost::unit_test::unit_test_log_formatter
|
||||
class BOOST_TEST_DECL unit_test_log_t : public test_observer, public singleton<unit_test_log_t> {
|
||||
class BOOST_TEST_DECL unit_test_log_t : public test_observer {
|
||||
public:
|
||||
// test_observer interface implementation
|
||||
virtual void test_start( counter_t test_cases_amount );
|
||||
@@ -120,10 +119,11 @@ public:
|
||||
virtual void test_unit_finish( test_unit const&, unsigned long elapsed );
|
||||
virtual void test_unit_skipped( test_unit const&, const_string );
|
||||
virtual void test_unit_aborted( test_unit const& );
|
||||
virtual void test_unit_timed_out( test_unit const& );
|
||||
|
||||
virtual void exception_caught( execution_exception const& ex );
|
||||
|
||||
virtual int priority() { return 1; }
|
||||
virtual int priority() { return 2; }
|
||||
|
||||
// log configuration methods
|
||||
//! Sets the stream for all loggers
|
||||
@@ -137,6 +137,13 @@ public:
|
||||
//! @par Since Boost 1.62
|
||||
void set_stream( output_format, std::ostream& );
|
||||
|
||||
//! Returns a pointer to the stream associated to specific logger
|
||||
//!
|
||||
//! @note Returns a null pointer if the format is not found
|
||||
//! @par Since Boost 1.67
|
||||
std::ostream* get_stream( output_format ) const;
|
||||
|
||||
|
||||
//! Sets the threshold level for all loggers/formatters.
|
||||
//!
|
||||
//! This will override the log level of all loggers, whether enabled or not.
|
||||
@@ -214,6 +221,7 @@ private:
|
||||
void log_entry_context( log_level l );
|
||||
void clear_entry_context();
|
||||
|
||||
// Singleton
|
||||
BOOST_TEST_SINGLETON_CONS( unit_test_log_t )
|
||||
}; // unit_test_log_t
|
||||
|
||||
|
||||
@@ -139,8 +139,9 @@ public:
|
||||
|
||||
/// Invoked when Unit Test Framework build information is requested
|
||||
///
|
||||
/// @param[in] os output stream to write a messages into
|
||||
virtual void log_build_info( std::ostream& os ) = 0;
|
||||
/// @param[in] os output stream to write a messages into
|
||||
/// @param[in] log_build_info indicates if build info should be logged or not
|
||||
virtual void log_build_info( std::ostream& os, bool log_build_info = true ) = 0;
|
||||
// @}
|
||||
|
||||
// @name Test unit start/finish
|
||||
@@ -176,6 +177,10 @@ public:
|
||||
/// Invoked when a test unit is aborted
|
||||
virtual void test_unit_aborted( std::ostream& /* os */, test_unit const& /* tu */) {}
|
||||
|
||||
/// Invoked when a test unit times-out
|
||||
virtual void test_unit_timed_out( std::ostream& /* os */, test_unit const& /* tu */) {}
|
||||
|
||||
|
||||
// @}
|
||||
|
||||
// @name Uncaught exception report
|
||||
@@ -248,7 +253,7 @@ public:
|
||||
// @name Log entry context report
|
||||
|
||||
/// Invoked by Unit Test Framework to start log entry context report
|
||||
|
||||
//
|
||||
/// Unit Test Framework logs for failed assertions and uncaught exceptions context if one was defined by a test module.
|
||||
/// Context consists of multiple "scopes" identified by description messages assigned by the test module using
|
||||
/// BOOST_TEST_INFO/BOOST_TEST_CONTEXT statements.
|
||||
@@ -258,18 +263,20 @@ public:
|
||||
virtual void entry_context_start( std::ostream& os, log_level l ) = 0;
|
||||
|
||||
/// Invoked by Unit Test Framework to report log entry context "scope" description
|
||||
|
||||
//
|
||||
/// Each "scope" description is reported by separate call to log_entry_context.
|
||||
/// @param[in] os output stream to write a messages into
|
||||
/// @param[in] l entry log_level, to be used to fine tune the message
|
||||
/// @param[in] value context "scope" description
|
||||
/// @see log_entry_start, entry_context_finish
|
||||
virtual void log_entry_context( std::ostream& os, const_string value ) = 0;
|
||||
virtual void log_entry_context( std::ostream& os, log_level l, const_string value ) = 0;
|
||||
|
||||
/// Invoked by Unit Test Framework to finish log entry context report
|
||||
|
||||
///
|
||||
/// @param[in] os output stream to write a messages into
|
||||
/// @param[in] l entry log_level, to be used to fine tune the message
|
||||
/// @see log_entry_start, entry_context_context
|
||||
virtual void entry_context_finish( std::ostream& os ) = 0;
|
||||
virtual void entry_context_finish( std::ostream& os, log_level l ) = 0;
|
||||
// @}
|
||||
|
||||
// @name Log level management
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
// Boost.Test
|
||||
#include <boost/test/execution_monitor.hpp>
|
||||
#include <boost/test/detail/fwd_decl.hpp>
|
||||
#include <boost/test/utils/trivial_singleton.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
@@ -30,11 +29,13 @@ namespace unit_test {
|
||||
// ************** unit_test_monitor ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class BOOST_TEST_DECL unit_test_monitor_t : public singleton<unit_test_monitor_t>, public execution_monitor {
|
||||
class BOOST_TEST_DECL unit_test_monitor_t :public execution_monitor {
|
||||
public:
|
||||
enum error_level {
|
||||
test_ok = 0,
|
||||
precondition_failure = -1,
|
||||
/// Indicates a failure to prepare the unit test (eg. fixture). Does not
|
||||
/// account for tests skipped because of parent tests failed/skipped.
|
||||
test_setup_failure = -1,
|
||||
unexpected_exception = -2,
|
||||
os_exception = -3,
|
||||
os_timeout = -4,
|
||||
@@ -44,9 +45,10 @@ public:
|
||||
static bool is_critical_error( error_level e ) { return e <= fatal_error; }
|
||||
|
||||
// monitor method
|
||||
error_level execute_and_translate( boost::function<void ()> const& func, unsigned timeout = 0 );
|
||||
// timeout is expressed in seconds
|
||||
error_level execute_and_translate( boost::function<void ()> const& func, unsigned long int timeout_microseconds = 0 );
|
||||
|
||||
private:
|
||||
// singleton pattern
|
||||
BOOST_TEST_SINGLETON_CONS( unit_test_monitor_t )
|
||||
};
|
||||
|
||||
|
||||
@@ -19,6 +19,9 @@
|
||||
#include <boost/test/utils/runtime/argument.hpp>
|
||||
#include <boost/make_shared.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/function/function0.hpp>
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@@ -96,24 +99,39 @@ BOOST_TEST_DECL bool save_pattern();
|
||||
class stream_holder {
|
||||
public:
|
||||
// Constructor
|
||||
explicit stream_holder( std::ostream& default_stream = std::cout)
|
||||
explicit stream_holder( std::ostream& default_stream = std::cout )
|
||||
: m_stream( &default_stream )
|
||||
{
|
||||
}
|
||||
|
||||
void setup( const const_string& stream_name )
|
||||
void setup( const const_string& stream_name,
|
||||
boost::function<void ()> const &cleaner_callback = boost::function<void ()>() )
|
||||
{
|
||||
if(stream_name.empty())
|
||||
return;
|
||||
|
||||
if( stream_name == "stderr" )
|
||||
if( stream_name == "stderr" ) {
|
||||
m_stream = &std::cerr;
|
||||
else if( stream_name == "stdout" )
|
||||
if(cleaner_callback) {
|
||||
m_cleaner = boost::make_shared<callback_cleaner>(cleaner_callback);
|
||||
}
|
||||
else {
|
||||
m_cleaner.reset();
|
||||
}
|
||||
}
|
||||
else if( stream_name == "stdout" ) {
|
||||
m_stream = &std::cout;
|
||||
if (cleaner_callback) {
|
||||
m_cleaner = boost::make_shared<callback_cleaner>(cleaner_callback);
|
||||
}
|
||||
else {
|
||||
m_cleaner.reset();
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_file = boost::make_shared<std::ofstream>();
|
||||
m_file->open( std::string(stream_name.begin(), stream_name.end()).c_str() );
|
||||
m_stream = m_file.get();
|
||||
m_cleaner = boost::make_shared<callback_cleaner>(cleaner_callback);
|
||||
m_cleaner->m_file.open( std::string(stream_name.begin(), stream_name.end()).c_str() );
|
||||
m_stream = &m_cleaner->m_file;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -121,9 +139,22 @@ public:
|
||||
std::ostream& ref() const { return *m_stream; }
|
||||
|
||||
private:
|
||||
struct callback_cleaner {
|
||||
callback_cleaner(boost::function<void ()> cleaner_callback)
|
||||
: m_cleaner_callback(cleaner_callback)
|
||||
, m_file() {
|
||||
}
|
||||
~callback_cleaner() {
|
||||
if( m_cleaner_callback )
|
||||
m_cleaner_callback();
|
||||
}
|
||||
boost::function<void ()> m_cleaner_callback;
|
||||
std::ofstream m_file;
|
||||
};
|
||||
|
||||
// Data members
|
||||
boost::shared_ptr<std::ofstream> m_file;
|
||||
std::ostream* m_stream;
|
||||
boost::shared_ptr<callback_cleaner> m_cleaner;
|
||||
std::ostream* m_stream;
|
||||
};
|
||||
|
||||
} // namespace runtime_config
|
||||
|
||||
@@ -32,10 +32,12 @@
|
||||
// ************** Non-auto (explicit) test case interface ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#define BOOST_TEST_CASE( test_function ) \
|
||||
#define BOOST_TEST_CASE_NAME( test_function, test_name ) \
|
||||
boost::unit_test::make_test_case( boost::function<void ()>(test_function), \
|
||||
BOOST_TEST_STRINGIZE( test_function ), \
|
||||
test_name , \
|
||||
__FILE__, __LINE__ )
|
||||
#define BOOST_TEST_CASE( test_function ) \
|
||||
BOOST_TEST_CASE_NAME(test_function, BOOST_TEST_STRINGIZE( test_function) )
|
||||
#define BOOST_CLASS_TEST_CASE( test_function, tc_instance ) \
|
||||
boost::unit_test::make_test_case( (test_function), \
|
||||
BOOST_TEST_STRINGIZE( test_function ), \
|
||||
@@ -63,7 +65,7 @@ BOOST_AUTO_TU_REGISTRAR( suite_name )( \
|
||||
#define BOOST_AUTO_TEST_SUITE_NO_DECOR( suite_name ) \
|
||||
BOOST_AUTO_TEST_SUITE_WITH_DECOR( \
|
||||
suite_name, \
|
||||
boost::unit_test::decorator::collector::instance() ) \
|
||||
boost::unit_test::decorator::collector_t::instance() ) \
|
||||
/**/
|
||||
|
||||
#if BOOST_PP_VARIADICS
|
||||
@@ -143,11 +145,15 @@ struct test_name : public F { void test_method(); }; \
|
||||
\
|
||||
static void BOOST_AUTO_TC_INVOKER( test_name )() \
|
||||
{ \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture entry."); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture ctor"); \
|
||||
test_name t; \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture setup"); \
|
||||
boost::unit_test::setup_conditional(t); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" test entry"); \
|
||||
t.test_method(); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture teardown"); \
|
||||
boost::unit_test::teardown_conditional(t); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture dtor"); \
|
||||
} \
|
||||
\
|
||||
struct BOOST_AUTO_TC_UNIQUE_ID( test_name ) {}; \
|
||||
@@ -163,7 +169,7 @@ void test_name::test_method() \
|
||||
|
||||
#define BOOST_FIXTURE_TEST_CASE_NO_DECOR( test_name, F ) \
|
||||
BOOST_FIXTURE_TEST_CASE_WITH_DECOR( test_name, F, \
|
||||
boost::unit_test::decorator::collector::instance() ) \
|
||||
boost::unit_test::decorator::collector_t::instance() ) \
|
||||
/**/
|
||||
|
||||
#if BOOST_PP_VARIADICS
|
||||
@@ -229,11 +235,15 @@ struct BOOST_AUTO_TC_INVOKER( test_name ) { \
|
||||
template<typename TestType> \
|
||||
static void run( boost::type<TestType>* = 0 ) \
|
||||
{ \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name <<"\" fixture entry."); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture ctor"); \
|
||||
test_name<TestType> t; \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" entry."); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture setup"); \
|
||||
boost::unit_test::setup_conditional(t); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" test entry"); \
|
||||
t.test_method(); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" exit."); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture teardown");\
|
||||
boost::unit_test::teardown_conditional(t); \
|
||||
BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture dtor"); \
|
||||
} \
|
||||
}; \
|
||||
\
|
||||
@@ -241,7 +251,7 @@ BOOST_AUTO_TU_REGISTRAR( test_name )( \
|
||||
boost::unit_test::ut_detail::template_test_case_gen< \
|
||||
BOOST_AUTO_TC_INVOKER( test_name ),TL >( \
|
||||
BOOST_STRINGIZE( test_name ), __FILE__, __LINE__ ), \
|
||||
boost::unit_test::decorator::collector::instance() ); \
|
||||
boost::unit_test::decorator::collector_t::instance() ); \
|
||||
\
|
||||
template<typename type_name> \
|
||||
void test_name<type_name>::test_method() \
|
||||
@@ -290,6 +300,22 @@ void BOOST_JOIN( name, _impl )( boost::type<type_name>* ) \
|
||||
// ************************************************************************** //
|
||||
|
||||
#define BOOST_GLOBAL_FIXTURE( F ) \
|
||||
static boost::unit_test::ut_detail::global_configuration_impl<F> BOOST_JOIN( gf_, F ) \
|
||||
/**/
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** BOOST_TEST_GLOBAL_CONFIGURATION ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#define BOOST_TEST_GLOBAL_CONFIGURATION( F ) \
|
||||
static boost::unit_test::ut_detail::global_configuration_impl<F> BOOST_JOIN( gf_, F ) \
|
||||
/**/
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** BOOST_TEST_GLOBAL_FIXTURE ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#define BOOST_TEST_GLOBAL_FIXTURE( F ) \
|
||||
static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F ) \
|
||||
/**/
|
||||
|
||||
@@ -298,8 +324,8 @@ static boost::unit_test::ut_detail::global_fixture_impl<F> BOOST_JOIN( gf_, F )
|
||||
// ************************************************************************** //
|
||||
|
||||
#define BOOST_TEST_DECORATOR( D ) \
|
||||
static boost::unit_test::decorator::collector const& \
|
||||
BOOST_TEST_APPEND_UNIQUE_ID(decorator_collector) = D; \
|
||||
static boost::unit_test::decorator::collector_t const& \
|
||||
BOOST_TEST_APPEND_UNIQUE_ID(decorator_collector) BOOST_ATTRIBUTE_UNUSED = D; \
|
||||
/**/
|
||||
|
||||
// ************************************************************************** //
|
||||
@@ -322,7 +348,7 @@ typedef ::boost::unit_test::ut_detail::nil_t BOOST_AUTO_TEST_CASE_FIXTURE;
|
||||
// ************************************************************************** //
|
||||
|
||||
// Facility for having a unique name based on __LINE__ and __COUNTER__ (later if available)
|
||||
#if defined(__COUNTER__)
|
||||
#if defined(__COUNTER__)
|
||||
#define BOOST_TEST_INTERNAL_HAS_COUNTER
|
||||
#endif
|
||||
|
||||
@@ -339,7 +365,7 @@ typedef ::boost::unit_test::ut_detail::nil_t BOOST_AUTO_TEST_CASE_FIXTURE;
|
||||
|
||||
#define BOOST_AUTO_TU_REGISTRAR( test_name ) \
|
||||
static boost::unit_test::ut_detail::auto_test_unit_registrar \
|
||||
BOOST_TEST_APPEND_UNIQUE_ID( BOOST_JOIN( test_name, _registrar ) ) \
|
||||
BOOST_TEST_APPEND_UNIQUE_ID( BOOST_JOIN( test_name, _registrar ) ) BOOST_ATTRIBUTE_UNUSED \
|
||||
/**/
|
||||
#define BOOST_AUTO_TC_INVOKER( test_name ) BOOST_JOIN( test_name, _invoker )
|
||||
#define BOOST_AUTO_TC_UNIQUE_ID( test_name ) BOOST_JOIN( test_name, _id )
|
||||
|
||||
@@ -15,10 +15,16 @@
|
||||
// STL
|
||||
#include <utility>
|
||||
#include <algorithm> // std::find
|
||||
#include <functional> // std::bind1st
|
||||
#include <functional> // std::bind1st or std::bind
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
#ifdef BOOST_NO_CXX98_BINDERS
|
||||
#define BOOST_TEST_BIND1ST(F,A) std::bind( (F), (A), std::placeholders::_1 )
|
||||
#else
|
||||
#define BOOST_TEST_BIND1ST(F,A) std::bind1st( (F), (A) )
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
@@ -109,7 +115,7 @@ find_first_not_of( ForwardIterator1 first1, ForwardIterator1 last1,
|
||||
Predicate pred )
|
||||
{
|
||||
while( first1 != last1 ) {
|
||||
if( std::find_if( first2, last2, std::bind1st( pred, *first1 ) ) == last2 )
|
||||
if( std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *first1 ) ) == last2 )
|
||||
break;
|
||||
++first1;
|
||||
}
|
||||
@@ -159,9 +165,9 @@ find_last_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
|
||||
return last1;
|
||||
|
||||
BidirectionalIterator1 it1 = last1;
|
||||
while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ) {}
|
||||
while( --it1 != first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) == last2 ) {}
|
||||
|
||||
return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
|
||||
return it1 == first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) == last2 ? last1 : it1;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -206,9 +212,9 @@ find_last_not_of( BidirectionalIterator1 first1, BidirectionalIterator1 last1,
|
||||
return last1;
|
||||
|
||||
BidirectionalIterator1 it1 = last1;
|
||||
while( --it1 != first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) != last2 ) {}
|
||||
while( --it1 != first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) != last2 ) {}
|
||||
|
||||
return it1 == first1 && std::find_if( first2, last2, std::bind1st( pred, *it1 ) ) == last2 ? last1 : it1;
|
||||
return it1 == first1 && std::find_if( first2, last2, BOOST_TEST_BIND1ST( pred, *it1 ) ) == last2 ? last1 : it1;
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -39,12 +39,12 @@ namespace unit_test {
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename CharT>
|
||||
class basic_cstring {
|
||||
class BOOST_SYMBOL_VISIBLE basic_cstring {
|
||||
typedef basic_cstring<CharT> self_type;
|
||||
public:
|
||||
// Subtypes
|
||||
typedef ut_detail::bcs_char_traits<CharT> traits_type;
|
||||
typedef typename ut_detail::bcs_char_traits<CharT>::std_string std_string;
|
||||
typedef typename traits_type::std_string std_string;
|
||||
|
||||
typedef CharT value_type;
|
||||
typedef typename remove_cv<value_type>::type value_ret_type;
|
||||
@@ -60,8 +60,8 @@ public:
|
||||
|
||||
// !! should also present reverse_iterator, const_reverse_iterator
|
||||
|
||||
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
|
||||
enum npos_type { npos = static_cast<size_type>(-1) };
|
||||
#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) && !defined(__DCC__)
|
||||
BOOST_STATIC_CONSTANT(size_type, npos = static_cast<size_type>(-1));
|
||||
#else
|
||||
// IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
|
||||
// But size_type is 8 bytes in 64bit mode.
|
||||
@@ -72,6 +72,7 @@ public:
|
||||
|
||||
// Constructors; default copy constructor is generated by compiler
|
||||
basic_cstring();
|
||||
basic_cstring( basic_cstring const & );
|
||||
basic_cstring( std_string const& s );
|
||||
basic_cstring( pointer s );
|
||||
template<typename LenType>
|
||||
@@ -162,15 +163,20 @@ private:
|
||||
// Data members
|
||||
iterator m_begin;
|
||||
iterator m_end;
|
||||
static CharT null;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename CharT>
|
||||
CharT basic_cstring<CharT>::null = 0;
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename CharT>
|
||||
inline typename basic_cstring<CharT>::pointer
|
||||
basic_cstring<CharT>::null_str()
|
||||
{
|
||||
static CharT null = 0;
|
||||
return &null;
|
||||
}
|
||||
|
||||
@@ -186,6 +192,16 @@ basic_cstring<CharT>::basic_cstring()
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename CharT>
|
||||
inline
|
||||
basic_cstring<CharT>::basic_cstring(basic_cstring const & s)
|
||||
: m_begin( s.m_begin )
|
||||
, m_end( s.m_end )
|
||||
{
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename CharT>
|
||||
inline
|
||||
basic_cstring<CharT>::basic_cstring( std_string const& s )
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
#ifndef BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
|
||||
#define BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/test/detail/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
namespace unit_test {
|
||||
|
||||
template<typename CharT> class basic_cstring;
|
||||
template<typename CharT> class BOOST_SYMBOL_VISIBLE basic_cstring;
|
||||
typedef basic_cstring<char const> const_string;
|
||||
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590041))
|
||||
typedef const_string literal_string;
|
||||
@@ -37,4 +37,3 @@ typedef char const* const c_literal_string;
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TEST_UTILS_BASIC_CSTRING_FWD_HPP
|
||||
|
||||
|
||||
@@ -76,9 +76,13 @@ case_ins_eq( basic_cstring<CharT> x, basic_cstring<CharT> y )
|
||||
// ************************************************************************** //
|
||||
|
||||
template<class CharT>
|
||||
class case_ins_less : public std::binary_function<basic_cstring<CharT>,basic_cstring<CharT>,bool>
|
||||
class case_ins_less
|
||||
{
|
||||
public:
|
||||
typedef bool result_type;
|
||||
typedef basic_cstring<CharT> first_argument_type;
|
||||
typedef basic_cstring<CharT> second_argument_type;
|
||||
|
||||
bool operator()( basic_cstring<CharT> x, basic_cstring<CharT> y ) const
|
||||
{
|
||||
return x.size() != y.size()
|
||||
|
||||
@@ -26,7 +26,6 @@
|
||||
// Boost
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/test/detail/workaround.hpp>
|
||||
|
||||
#include <boost/type_traits/is_const.hpp>
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <boost/type_traits/remove_const.hpp>
|
||||
#include <boost/type_traits/add_const.hpp>
|
||||
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
|
||||
#include <string>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -51,19 +52,36 @@ struct is_cstring_impl<char*> : public mpl::true_ {};
|
||||
template<>
|
||||
struct is_cstring_impl<wchar_t*> : public mpl::true_ {};
|
||||
|
||||
template <typename T, bool is_cstring = is_cstring_impl<typename boost::decay<T>::type>::value >
|
||||
struct deduce_cstring_impl;
|
||||
|
||||
template <typename T, bool is_cstring >
|
||||
struct deduce_cstring_impl<T&, is_cstring> : public deduce_cstring_impl<T, is_cstring>{};
|
||||
|
||||
template <typename T, bool is_cstring >
|
||||
struct deduce_cstring_impl<T const, is_cstring> : public deduce_cstring_impl<T, is_cstring>{};
|
||||
|
||||
template <typename T>
|
||||
struct deduce_cstring_impl {
|
||||
struct deduce_cstring_impl<T, true> {
|
||||
typedef typename boost::add_const<
|
||||
typename boost::remove_pointer<
|
||||
typename boost::decay<T>::type
|
||||
>::type
|
||||
>::type type;
|
||||
>::type U;
|
||||
typedef boost::unit_test::basic_cstring<U> type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct deduce_cstring_impl< std::basic_string<T, std::char_traits<T> > > {
|
||||
// const is required here
|
||||
typedef typename boost::add_const<T>::type type;
|
||||
struct deduce_cstring_impl< T, false > {
|
||||
typedef typename
|
||||
boost::remove_const<
|
||||
typename boost::remove_reference<T>::type
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
struct deduce_cstring_impl< std::basic_string<T, std::char_traits<T> >, false > {
|
||||
typedef boost::unit_test::basic_cstring<typename boost::add_const<T>::type> type;
|
||||
};
|
||||
|
||||
} // namespace ut_detail
|
||||
@@ -71,8 +89,17 @@ struct deduce_cstring_impl< std::basic_string<T, std::char_traits<T> > > {
|
||||
template<typename T>
|
||||
struct is_cstring : public ut_detail::is_cstring_impl<typename decay<T>::type> {};
|
||||
|
||||
template<typename T, bool is_cstring = is_cstring<typename boost::decay<T>::type>::value >
|
||||
struct is_cstring_comparable: public mpl::false_ {};
|
||||
|
||||
template<typename T>
|
||||
struct is_cstring< std::basic_string<T, std::char_traits<T> > > : public mpl::true_ {};
|
||||
struct is_cstring_comparable< T, true > : public mpl::true_ {};
|
||||
|
||||
template<typename T>
|
||||
struct is_cstring_comparable< std::basic_string<T, std::char_traits<T> >, false > : public mpl::true_ {};
|
||||
|
||||
template<typename T>
|
||||
struct is_cstring_comparable< boost::unit_test::basic_cstring<T>, false > : public mpl::true_ {};
|
||||
|
||||
template <class T>
|
||||
struct deduce_cstring {
|
||||
@@ -80,7 +107,7 @@ struct deduce_cstring {
|
||||
boost::remove_const<
|
||||
typename boost::remove_reference<T>::type
|
||||
>::type U;
|
||||
typedef typename ut_detail::deduce_cstring_impl<U>::type type;
|
||||
typedef typename ut_detail::deduce_cstring_impl<typename boost::decay<U>::type>::type type;
|
||||
};
|
||||
|
||||
} // namespace unit_test
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
defined(BOOST_NO_CXX11_NULLPTR) || \
|
||||
defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES)
|
||||
|
||||
// some issues with boost.config
|
||||
#if !defined(BOOST_MSVC) || BOOST_MSVC_FULL_VER < 170061030 /* VC2012 upd 5 */
|
||||
// this feature works with VC2012 upd 5 while BOOST_NO_CXX11_TRAILING_RESULT_TYPES is defined
|
||||
#if !defined(BOOST_MSVC) || BOOST_MSVC_FULL_VER < 170061232 /* VC2012 upd 5 */
|
||||
#define BOOST_TEST_FWD_ITERABLE_CXX03
|
||||
#endif
|
||||
#endif
|
||||
@@ -35,6 +35,7 @@
|
||||
#else
|
||||
|
||||
// Boost
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/utility/declval.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
@@ -51,6 +52,9 @@
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
template<typename T>
|
||||
struct is_forward_iterable;
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** is_forward_iterable ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -65,6 +69,9 @@ struct is_forward_iterable<T const> : public is_forward_iterable<T> {};
|
||||
template<typename T>
|
||||
struct is_forward_iterable<T&> : public is_forward_iterable<T> {};
|
||||
|
||||
template<typename T, std::size_t N>
|
||||
struct is_forward_iterable< T [N] > : public mpl::true_ {};
|
||||
|
||||
template<typename T, typename A>
|
||||
struct is_forward_iterable< std::vector<T, A> > : public mpl::true_ {};
|
||||
|
||||
@@ -86,6 +93,7 @@ struct is_forward_iterable< std::string > : public mpl::true_ {};
|
||||
|
||||
namespace ut_detail {
|
||||
|
||||
// SFINAE helper
|
||||
template<typename T>
|
||||
struct is_present : public mpl::true_ {};
|
||||
|
||||
@@ -110,7 +118,7 @@ template <class T>
|
||||
struct has_member_begin {
|
||||
private:
|
||||
struct nil_t {};
|
||||
template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().begin());
|
||||
template<typename U> static auto test( U* ) -> decltype(std::begin(boost::declval<U&>())); // does not work with boost::begin
|
||||
template<typename> static nil_t test( ... );
|
||||
public:
|
||||
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
|
||||
@@ -122,7 +130,7 @@ template <class T>
|
||||
struct has_member_end {
|
||||
private:
|
||||
struct nil_t {};
|
||||
template<typename U> static auto test( U* ) -> decltype(boost::declval<U>().end());
|
||||
template<typename U> static auto test( U* ) -> decltype(std::end(boost::declval<U&>())); // does not work with boost::end
|
||||
template<typename> static nil_t test( ... );
|
||||
public:
|
||||
static bool const value = !std::is_same< decltype(test<T>( nullptr )), nil_t>::value;
|
||||
@@ -134,24 +142,36 @@ template <class T, class enabled = void>
|
||||
struct is_forward_iterable_impl : std::false_type {
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template <class T>
|
||||
struct is_forward_iterable_impl<
|
||||
T,
|
||||
typename std::enable_if<
|
||||
is_present<typename T::const_iterator>::value &&
|
||||
is_present<typename T::value_type>::value &&
|
||||
has_member_size<T>::value &&
|
||||
has_member_begin<T>::value &&
|
||||
has_member_end<T>::value &&
|
||||
!is_cstring<T>::value
|
||||
has_member_begin<T>::value &&
|
||||
has_member_end<T>::value
|
||||
>::type
|
||||
> : std::true_type
|
||||
{};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template <class T, class enabled = void>
|
||||
struct is_container_forward_iterable_impl : std::false_type {
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct is_container_forward_iterable_impl<
|
||||
T,
|
||||
typename std::enable_if<
|
||||
is_present<typename T::const_iterator>::value &&
|
||||
is_present<typename T::value_type>::value &&
|
||||
has_member_size<T>::value &&
|
||||
is_forward_iterable_impl<T>::value
|
||||
>::type
|
||||
> : is_forward_iterable_impl<T>
|
||||
{};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace ut_detail
|
||||
|
||||
/*! Indicates that a specific type implements the forward iterable concept. */
|
||||
@@ -163,8 +183,84 @@ struct is_forward_iterable {
|
||||
enum { value = is_fwd_it_t::value };
|
||||
};
|
||||
|
||||
/*! Indicates that a specific type implements the forward iterable concept. */
|
||||
template<typename T>
|
||||
struct is_container_forward_iterable {
|
||||
typedef typename std::remove_reference<T>::type T_ref;
|
||||
typedef ut_detail::is_container_forward_iterable_impl<T_ref> is_fwd_it_t;
|
||||
typedef mpl::bool_<is_fwd_it_t::value> type;
|
||||
enum { value = is_fwd_it_t::value };
|
||||
};
|
||||
|
||||
#endif /* defined(BOOST_TEST_FWD_ITERABLE_CXX03) */
|
||||
|
||||
|
||||
//! Helper structure for accessing the content of a container or an array
|
||||
template <typename T, bool is_forward_iterable = is_forward_iterable<T>::value >
|
||||
struct bt_iterator_traits;
|
||||
|
||||
template <typename T>
|
||||
struct bt_iterator_traits< T, true >{
|
||||
BOOST_STATIC_ASSERT((is_forward_iterable<T>::value));
|
||||
|
||||
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
|
||||
(defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061232))
|
||||
typedef typename T::const_iterator const_iterator;
|
||||
typedef typename std::iterator_traits<const_iterator>::value_type value_type;
|
||||
#else
|
||||
typedef decltype(boost::declval<
|
||||
typename boost::add_const<
|
||||
typename boost::remove_reference<T>::type
|
||||
>::type>().begin()) const_iterator;
|
||||
|
||||
typedef typename std::iterator_traits<const_iterator>::value_type value_type;
|
||||
#endif /* BOOST_TEST_FWD_ITERABLE_CXX03 */
|
||||
|
||||
static const_iterator begin(T const& container) {
|
||||
return container.begin();
|
||||
}
|
||||
static const_iterator end(T const& container) {
|
||||
return container.end();
|
||||
}
|
||||
|
||||
#if defined(BOOST_TEST_FWD_ITERABLE_CXX03) || \
|
||||
(defined(BOOST_MSVC) && (BOOST_MSVC_FULL_VER <= 170061232))
|
||||
static std::size_t
|
||||
size(T const& container) {
|
||||
return container.size();
|
||||
}
|
||||
#else
|
||||
static std::size_t
|
||||
size(T const& container) {
|
||||
return size(container,
|
||||
std::integral_constant<bool, ut_detail::has_member_size<T>::value>());
|
||||
}
|
||||
private:
|
||||
static std::size_t
|
||||
size(T const& container, std::true_type) { return container.size(); }
|
||||
|
||||
static std::size_t
|
||||
size(T const& container, std::false_type) { return std::distance(begin(container), end(container)); }
|
||||
#endif /* BOOST_TEST_FWD_ITERABLE_CXX03 */
|
||||
};
|
||||
|
||||
template <typename T, std::size_t N>
|
||||
struct bt_iterator_traits< T [N], true > {
|
||||
typedef typename boost::add_const<T>::type T_const;
|
||||
typedef typename boost::add_pointer<T_const>::type const_iterator;
|
||||
typedef T value_type;
|
||||
|
||||
static const_iterator begin(T_const (&array)[N]) {
|
||||
return &array[0];
|
||||
}
|
||||
static const_iterator end(T_const (&array)[N]) {
|
||||
return &array[N];
|
||||
}
|
||||
static std::size_t size(T_const (&)[N]) {
|
||||
return N;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
|
||||
@@ -28,11 +28,11 @@
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
class lazy_ostream {
|
||||
class BOOST_TEST_DECL lazy_ostream {
|
||||
public:
|
||||
virtual ~lazy_ostream() {}
|
||||
|
||||
static lazy_ostream& instance() { static lazy_ostream inst; return inst; }
|
||||
static lazy_ostream& instance() { return inst; }
|
||||
|
||||
friend std::ostream& operator<<( std::ostream& ostr, lazy_ostream const& o ) { return o( ostr ); }
|
||||
|
||||
@@ -47,6 +47,7 @@ protected:
|
||||
private:
|
||||
// Data members
|
||||
bool m_empty;
|
||||
static lazy_ostream inst;
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
@@ -72,7 +72,7 @@ struct is_named_param_pack<named_parameter_combine<NP,Rest> > : public mpl::true
|
||||
// ************** param_type ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// param_type<Params,Keyword,Default>::type is is the type of the parameter
|
||||
/// param_type<Params,Keyword,Default>::type is the type of the parameter
|
||||
/// corresponding to the Keyword (if parameter is present) or Default
|
||||
|
||||
template<typename NP, typename Keyword, typename DefaultType=void>
|
||||
@@ -91,7 +91,7 @@ struct param_type<named_parameter_combine<NP,Rest>,Keyword,DefaultType>
|
||||
// ************** has_param ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
/// has_param<Params,Keyword>::value is true id Params has parameter corresponding
|
||||
/// has_param<Params,Keyword>::value is true if Params has parameter corresponding
|
||||
/// to the Keyword
|
||||
|
||||
template<typename NP, typename Keyword>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
// C Runtime
|
||||
#include <cstddef>
|
||||
#include <boost/test/detail/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
namespace rtti {
|
||||
@@ -30,7 +31,7 @@ typedef std::ptrdiff_t id_t;
|
||||
namespace rtti_detail {
|
||||
|
||||
template<typename T>
|
||||
struct rttid_holder {
|
||||
struct BOOST_TEST_DECL rttid_holder {
|
||||
static id_t id() { return reinterpret_cast<id_t>( &inst() ); }
|
||||
|
||||
private:
|
||||
@@ -44,7 +45,7 @@ private:
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename T>
|
||||
inline id_t
|
||||
BOOST_TEST_DECL inline id_t
|
||||
type_id()
|
||||
{
|
||||
return rtti_detail::rttid_holder<T>::id();
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
// Boost.Test Runtime parameters
|
||||
#include <boost/test/utils/runtime/errors.hpp>
|
||||
#include <boost/test/utils/runtime/argument.hpp>
|
||||
#include <boost/test/utils/runtime/modifier.hpp>
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/utils/basic_cstring/io.hpp>
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
// Boost.Test Runtime parameters
|
||||
#include <boost/test/utils/runtime/fwd.hpp>
|
||||
#include <cstring>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
|
||||
@@ -109,12 +109,12 @@ struct parameter_trie {
|
||||
// ************** runtime::cla::report_foreing_token ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
static void
|
||||
static void
|
||||
report_foreing_token( cstring program_name, cstring token )
|
||||
{
|
||||
std::cerr << "Boost.Test WARNING: token \"" << token << "\" does not correspond to the Boost.Test argument \n"
|
||||
<< " and should be placed after all Boost.Test arguments and the -- separator.\n"
|
||||
<< " For example: " << program_name << " --random -- " << token << "\n";
|
||||
<< " For example: " << program_name << " --random -- " << token << "\n";
|
||||
}
|
||||
|
||||
} // namespace rt_cla_detail
|
||||
@@ -203,7 +203,7 @@ public:
|
||||
|
||||
if( negative_form ) {
|
||||
BOOST_TEST_I_ASSRT( found_id.m_negatable,
|
||||
format_error( found_param->p_name )
|
||||
format_error( found_param->p_name )
|
||||
<< "Parameter tag " << found_id.m_tag << " is not negatable." );
|
||||
|
||||
curr_token.trim_left( m_negation_prefix.size() );
|
||||
@@ -211,13 +211,18 @@ public:
|
||||
|
||||
curr_token.trim_left( name.size() );
|
||||
|
||||
bool should_go_to_next = true;
|
||||
cstring value;
|
||||
|
||||
|
||||
// Skip validations if parameter has optional value and we are at the end of token
|
||||
if( !value_separator.is_empty() || !found_param->p_has_optional_value ) {
|
||||
|
||||
// we are given a separator or there is no optional value
|
||||
|
||||
// Validate and skip value separator in the input
|
||||
BOOST_TEST_I_ASSRT( found_id.m_value_separator == value_separator,
|
||||
format_error( found_param->p_name )
|
||||
format_error( found_param->p_name )
|
||||
<< "Invalid separator for the parameter "
|
||||
<< found_param->p_name
|
||||
<< " in the argument " << tr.current_token() );
|
||||
@@ -237,6 +242,40 @@ public:
|
||||
<< found_param->p_name
|
||||
<< " in the argument " << tr.current_token() );
|
||||
}
|
||||
else if( (value_separator.is_empty() && found_id.m_value_separator.empty()) ) {
|
||||
// Deduce value source
|
||||
value = curr_token;
|
||||
if( value.is_empty() ) {
|
||||
tr.next_token(); // tokenization broke the value, we check the next one
|
||||
|
||||
if(!found_param->p_has_optional_value) {
|
||||
// there is no separator and there is no optional value
|
||||
// we look for the value on the next token
|
||||
// example "-t XXXX" (no default)
|
||||
// and we commit this value as being the passed value
|
||||
value = tr.current_token();
|
||||
}
|
||||
else {
|
||||
// there is no separator and the value is optional
|
||||
// we check the next token
|
||||
// example "-c" (defaults to true)
|
||||
// and commit this as the value if this is not a token
|
||||
cstring value_check = tr.current_token();
|
||||
|
||||
cstring prefix_test, name_test, value_separator_test;
|
||||
bool negative_form_test;
|
||||
if( validate_token_format( value_check, prefix_test, name_test, value_separator_test, negative_form_test )
|
||||
&& m_param_trie[prefix_test]) {
|
||||
// this is a token, we consume what we have
|
||||
should_go_to_next = false;
|
||||
}
|
||||
else {
|
||||
// this is a value, we commit it
|
||||
value = value_check;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Validate against argument duplication
|
||||
BOOST_TEST_I_ASSRT( !res.has( found_param->p_name ) || found_param->p_repeatable,
|
||||
@@ -248,7 +287,9 @@ public:
|
||||
// Produce argument value
|
||||
found_param->produce_argument( value, negative_form, res );
|
||||
|
||||
tr.next_token();
|
||||
if(should_go_to_next) {
|
||||
tr.next_token();
|
||||
}
|
||||
}
|
||||
|
||||
// generate the remainder and return it's size
|
||||
@@ -273,7 +314,7 @@ public:
|
||||
<< BOOST_VERSION % 100 ;
|
||||
ostr << " with ";
|
||||
#if defined(BOOST_TEST_INCLUDED)
|
||||
ostr << "single header inclusion of";
|
||||
ostr << "header-only inclusion of";
|
||||
#elif defined(BOOST_TEST_DYN_LINK)
|
||||
ostr << "dynamic linking to";
|
||||
#else
|
||||
@@ -287,57 +328,119 @@ public:
|
||||
}
|
||||
|
||||
void
|
||||
usage( std::ostream& ostr, cstring param_name = cstring() )
|
||||
usage(std::ostream& ostr,
|
||||
cstring param_name = cstring(),
|
||||
bool use_color = true)
|
||||
{
|
||||
namespace utils = unit_test::utils;
|
||||
namespace ut_detail = unit_test::ut_detail;
|
||||
|
||||
if( !param_name.is_empty() ) {
|
||||
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
|
||||
param->usage( ostr, m_negation_prefix );
|
||||
}
|
||||
else {
|
||||
ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
|
||||
if( !m_end_of_param_indicator.empty() )
|
||||
ostr << m_end_of_param_indicator << " [custom test module argument]...";
|
||||
ostr << "\n";
|
||||
ostr << "\n The program '" << m_program_name << "' is a Boost.Test module containing unit tests.";
|
||||
|
||||
{
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
|
||||
ostr << "\n\n Usage\n ";
|
||||
}
|
||||
|
||||
{
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
|
||||
ostr << m_program_name << " [Boost.Test argument]... ";
|
||||
}
|
||||
if( !m_end_of_param_indicator.empty() ) {
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
|
||||
ostr << '[' << m_end_of_param_indicator << " [custom test module argument]...]";
|
||||
}
|
||||
}
|
||||
|
||||
ostr << "\nFor detailed help on Boost.Test parameters use:\n"
|
||||
<< " " << m_program_name << " --help\n"
|
||||
<< "or\n"
|
||||
<< " " << m_program_name << " --help=<parameter name>\n";
|
||||
ostr << "\n\n Use\n ";
|
||||
{
|
||||
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
|
||||
ostr << m_program_name << " --help";
|
||||
}
|
||||
ostr << "\n or ";
|
||||
{
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
|
||||
ostr << m_program_name << " --help=<parameter name>";
|
||||
}
|
||||
ostr << "\n for detailed help on Boost.Test parameters.\n";
|
||||
}
|
||||
|
||||
void
|
||||
help( std::ostream& ostr, parameters_store const& parameters, cstring param_name )
|
||||
help(std::ostream& ostr,
|
||||
parameters_store const& parameters,
|
||||
cstring param_name,
|
||||
bool use_color = true)
|
||||
{
|
||||
namespace utils = unit_test::utils;
|
||||
namespace ut_detail = unit_test::ut_detail;
|
||||
|
||||
if( !param_name.is_empty() ) {
|
||||
basic_param_ptr param = locate_parameter( m_param_trie[help_prefix], param_name, "" ).second;
|
||||
param->help( ostr, m_negation_prefix );
|
||||
param->help( ostr, m_negation_prefix, use_color);
|
||||
return;
|
||||
}
|
||||
|
||||
ostr << "Usage: " << m_program_name << " [Boost.Test argument]... ";
|
||||
if( !m_end_of_param_indicator.empty() )
|
||||
ostr << m_end_of_param_indicator << " [custom test module argument]...";
|
||||
usage(ostr, cstring(), use_color);
|
||||
|
||||
ostr << "\n\nBoost.Test arguments correspond to parameters listed below. "
|
||||
"All parameters are optional. You can use specify parameter value either "
|
||||
"as a command line argument or as a value of corresponding environment "
|
||||
"variable. In case if argument for the same parameter is specified in both "
|
||||
"places, command line is taking precedence. Command line argument format "
|
||||
"supports parameter name guessing, so you can use any unambiguous "
|
||||
"prefix to identify a parameter.";
|
||||
if( !m_end_of_param_indicator.empty() )
|
||||
ostr << " All the arguments after the " << m_end_of_param_indicator << " are ignored by the Boost.Test.";
|
||||
ostr << "\n\n";
|
||||
{
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
|
||||
ostr << " Command line flags:\n";
|
||||
}
|
||||
runtime::commandline_pretty_print(
|
||||
ostr,
|
||||
" ",
|
||||
"The command line flags of Boost.Test are listed below. "
|
||||
"All parameters are optional. You can specify parameter value either "
|
||||
"as a command line argument or as a value of its corresponding environment "
|
||||
"variable. If a flag is specified as a command line argument and an environment variable "
|
||||
"at the same time, the command line takes precedence. "
|
||||
"The command line argument "
|
||||
"support name guessing, and works with shorter names as long as those are not ambiguous."
|
||||
);
|
||||
|
||||
ostr << "\n\nBoost.Test supports following parameters:\n";
|
||||
|
||||
BOOST_TEST_FOREACH( parameters_store::storage_type::value_type const&, v, parameters.all() ) {
|
||||
basic_param_ptr param = v.second;
|
||||
|
||||
param->usage( ostr, m_negation_prefix );
|
||||
if( !m_end_of_param_indicator.empty() ) {
|
||||
ostr << "\n\n All the arguments after the '";
|
||||
{
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
|
||||
ostr << m_end_of_param_indicator;
|
||||
}
|
||||
ostr << "' are ignored by Boost.Test.";
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::ORIGINAL );
|
||||
ostr << "\n\n Environment variables:\n";
|
||||
}
|
||||
runtime::commandline_pretty_print(
|
||||
ostr,
|
||||
" ",
|
||||
"Every argument listed below may also be set by a corresponding environment"
|
||||
"variable. For an argument '--argument_x=<value>', the corresponding "
|
||||
"environment variable is 'BOOST_TEST_ARGUMENT_X=value"
|
||||
);
|
||||
|
||||
|
||||
|
||||
ostr << "\n\n The following parameters are supported:\n";
|
||||
|
||||
BOOST_TEST_FOREACH(
|
||||
parameters_store::storage_type::value_type const&,
|
||||
v,
|
||||
parameters.all() )
|
||||
{
|
||||
basic_param_ptr param = v.second;
|
||||
ostr << "\n";
|
||||
param->usage( ostr, m_negation_prefix, use_color);
|
||||
}
|
||||
|
||||
ostr << "\nUse --help=<parameter name> to display detailed help for specific parameter.\n";
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
@@ -37,7 +37,7 @@ namespace runtime {
|
||||
// ************** runtime::param_error ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
class param_error : public std::exception {
|
||||
class BOOST_SYMBOL_VISIBLE param_error : public std::exception {
|
||||
public:
|
||||
~param_error() BOOST_NOEXCEPT_OR_NOTHROW {}
|
||||
|
||||
@@ -55,13 +55,13 @@ protected:
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
class init_error : public param_error {
|
||||
class BOOST_SYMBOL_VISIBLE init_error : public param_error {
|
||||
protected:
|
||||
explicit init_error( cstring param_name ) : param_error( param_name ) {}
|
||||
~init_error() BOOST_NOEXCEPT_OR_NOTHROW {}
|
||||
};
|
||||
|
||||
class input_error : public param_error {
|
||||
class BOOST_SYMBOL_VISIBLE input_error : public param_error {
|
||||
protected:
|
||||
explicit input_error( cstring param_name ) : param_error( param_name ) {}
|
||||
~input_error() BOOST_NOEXCEPT_OR_NOTHROW {}
|
||||
@@ -70,7 +70,7 @@ protected:
|
||||
//____________________________________________________________________________//
|
||||
|
||||
template<typename Derived, typename Base>
|
||||
class specific_param_error : public Base {
|
||||
class BOOST_SYMBOL_VISIBLE specific_param_error : public Base {
|
||||
protected:
|
||||
explicit specific_param_error( cstring param_name ) : Base( param_name ) {}
|
||||
~specific_param_error() BOOST_NOEXCEPT_OR_NOTHROW {}
|
||||
@@ -86,7 +86,7 @@ public:
|
||||
{
|
||||
this->msg.append( val );
|
||||
|
||||
return reinterpret_cast<Derived&&>(*this);
|
||||
return static_cast<Derived&&>(*this);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -96,7 +96,7 @@ public:
|
||||
{
|
||||
this->msg.append( unit_test::utils::string_cast( val ) );
|
||||
|
||||
return reinterpret_cast<Derived&&>(*this);
|
||||
return static_cast<Derived&&>(*this);
|
||||
}
|
||||
|
||||
//____________________________________________________________________________//
|
||||
@@ -133,7 +133,7 @@ public:
|
||||
// ************************************************************************** //
|
||||
|
||||
#define SPECIFIC_EX_TYPE( type, base ) \
|
||||
class type : public specific_param_error<type,base> { \
|
||||
class BOOST_SYMBOL_VISIBLE type : public specific_param_error<type,base> { \
|
||||
public: \
|
||||
explicit type( cstring param_name = cstring() ) \
|
||||
: specific_param_error<type,base>( param_name ) \
|
||||
@@ -155,7 +155,7 @@ SPECIFIC_EX_TYPE( missing_req_arg, input_error );
|
||||
|
||||
#undef SPECIFIC_EX_TYPE
|
||||
|
||||
class ambiguous_param : public specific_param_error<ambiguous_param, input_error> {
|
||||
class BOOST_SYMBOL_VISIBLE ambiguous_param : public specific_param_error<ambiguous_param, input_error> {
|
||||
public:
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
explicit ambiguous_param( std::vector<cstring>&& amb_candidates )
|
||||
@@ -171,7 +171,7 @@ public:
|
||||
std::vector<cstring> m_amb_candidates;
|
||||
};
|
||||
|
||||
class unrecognized_param : public specific_param_error<unrecognized_param, input_error> {
|
||||
class BOOST_SYMBOL_VISIBLE unrecognized_param : public specific_param_error<unrecognized_param, input_error> {
|
||||
public:
|
||||
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
|
||||
explicit unrecognized_param( std::vector<cstring>&& type_candidates )
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/utils/named_params.hpp>
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
|
||||
@@ -24,9 +24,10 @@
|
||||
// Boost.Test
|
||||
#include <boost/test/utils/class_properties.hpp>
|
||||
#include <boost/test/utils/foreach.hpp>
|
||||
#include <boost/test/utils/setcolor.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/function/function2.hpp>
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/algorithm/cxx11/all_of.hpp>
|
||||
|
||||
// STL
|
||||
@@ -37,6 +38,40 @@
|
||||
namespace boost {
|
||||
namespace runtime {
|
||||
|
||||
inline
|
||||
std::ostream& commandline_pretty_print(
|
||||
std::ostream& ostr,
|
||||
std::string const& prefix,
|
||||
std::string const& to_print) {
|
||||
|
||||
const int split_at = 80;
|
||||
|
||||
std::string::size_type current = 0;
|
||||
|
||||
while(current < to_print.size()) {
|
||||
|
||||
// discards spaces at the beginning
|
||||
std::string::size_type startpos = to_print.find_first_not_of(" \t\n", current);
|
||||
current += startpos - current;
|
||||
|
||||
bool has_more_lines = (current + split_at) < to_print.size();
|
||||
|
||||
if(has_more_lines) {
|
||||
std::string::size_type endpos = to_print.find_last_of(" \t\n", current + split_at);
|
||||
std::string sub(to_print.substr(current, endpos - current));
|
||||
ostr << prefix << sub;
|
||||
ostr << "\n";
|
||||
current += endpos - current;
|
||||
}
|
||||
else
|
||||
{
|
||||
ostr << prefix << to_print.substr(current, split_at);
|
||||
current += split_at;
|
||||
}
|
||||
}
|
||||
return ostr;
|
||||
}
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** runtime::parameter_cla_id ************** //
|
||||
// ************************************************************************** //
|
||||
@@ -142,23 +177,37 @@ public:
|
||||
virtual void produce_default( arguments_store& store ) const = 0;
|
||||
|
||||
/// interfaces for help message reporting
|
||||
virtual void usage( std::ostream& ostr, cstring negation_prefix_ )
|
||||
virtual void usage( std::ostream& ostr, cstring negation_prefix_, bool use_color = true )
|
||||
{
|
||||
ostr << "Parameter: " << p_name << '\n';
|
||||
if( !p_description.empty() )
|
||||
ostr << ' ' << p_description << '\n';
|
||||
namespace utils = unit_test::utils;
|
||||
namespace ut_detail = unit_test::ut_detail;
|
||||
|
||||
//
|
||||
ostr << " ";
|
||||
{
|
||||
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::GREEN );
|
||||
ostr << p_name;
|
||||
}
|
||||
|
||||
ostr << '\n';
|
||||
|
||||
if( !p_description.empty() ) {
|
||||
commandline_pretty_print(ostr, " ", p_description) << '\n';
|
||||
}
|
||||
|
||||
ostr << " Command line formats:\n";
|
||||
BOOST_TEST_FOREACH( parameter_cla_id const&, id, cla_ids() ) {
|
||||
if( id.m_prefix == help_prefix )
|
||||
continue;
|
||||
|
||||
ostr << " " << id.m_prefix;
|
||||
if( id.m_negatable )
|
||||
cla_name_help( ostr, id.m_tag, negation_prefix_ );
|
||||
else
|
||||
cla_name_help( ostr, id.m_tag, "" );
|
||||
ostr << " " << id.m_prefix;
|
||||
|
||||
if( id.m_negatable )
|
||||
cla_name_help( ostr, id.m_tag, negation_prefix_, use_color );
|
||||
else
|
||||
cla_name_help( ostr, id.m_tag, "", use_color );
|
||||
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
|
||||
bool optional_value_ = false;
|
||||
|
||||
if( p_has_optional_value ) {
|
||||
@@ -166,6 +215,7 @@ public:
|
||||
ostr << '[';
|
||||
}
|
||||
|
||||
|
||||
if( id.m_value_separator.empty() )
|
||||
ostr << ' ';
|
||||
else {
|
||||
@@ -179,16 +229,16 @@ public:
|
||||
|
||||
ostr << '\n';
|
||||
}
|
||||
if( !p_env_var.empty() )
|
||||
ostr << " Environment variable: " << p_env_var << '\n';
|
||||
}
|
||||
|
||||
virtual void help( std::ostream& ostr, cstring negation_prefix_ )
|
||||
virtual void help( std::ostream& ostr, cstring negation_prefix_, bool use_color = true )
|
||||
{
|
||||
usage( ostr, negation_prefix_ );
|
||||
usage( ostr, negation_prefix_, use_color );
|
||||
|
||||
if( !p_help.empty() )
|
||||
ostr << '\n' << p_help << '\n';
|
||||
if( !p_help.empty() ) {
|
||||
ostr << '\n';
|
||||
commandline_pretty_print(ostr, " ", p_help);
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -220,7 +270,7 @@ protected:
|
||||
|
||||
private:
|
||||
/// interface for usage/help customization
|
||||
virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /* negation_prefix_ */) const
|
||||
virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring /*negation_prefix_*/, bool /*use_color*/ = true) const
|
||||
{
|
||||
ostr << cla_tag;
|
||||
}
|
||||
@@ -337,12 +387,16 @@ private:
|
||||
{
|
||||
m_arg_factory.produce_default( p_name, store );
|
||||
}
|
||||
virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring negation_prefix_ ) const
|
||||
virtual void cla_name_help( std::ostream& ostr, cstring cla_tag, cstring negation_prefix_, bool use_color = true ) const
|
||||
{
|
||||
if( negation_prefix_.is_empty() )
|
||||
ostr << cla_tag;
|
||||
else
|
||||
ostr << '[' << negation_prefix_ << ']' << cla_tag;
|
||||
namespace utils = unit_test::utils;
|
||||
namespace ut_detail = unit_test::ut_detail;
|
||||
|
||||
if( !negation_prefix_.is_empty() ) {
|
||||
BOOST_TEST_SCOPE_SETCOLOR( use_color, ostr, term_attr::BRIGHT, term_color::YELLOW );
|
||||
ostr << '[' << negation_prefix_ << ']';
|
||||
}
|
||||
ostr << cla_tag;
|
||||
}
|
||||
virtual void value_help( std::ostream& ostr ) const
|
||||
{
|
||||
|
||||
@@ -18,12 +18,23 @@
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/config.hpp>
|
||||
|
||||
#include <boost/core/ignore_unused.hpp>
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
#include <cstdio>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
|
||||
#if defined(__MINGW32__) && !defined(COMMON_LVB_UNDERSCORE)
|
||||
// mingw badly mimicking windows.h
|
||||
#define COMMON_LVB_UNDERSCORE 0x8000
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
@@ -64,57 +75,244 @@ struct term_color { enum _ {
|
||||
// ************** setcolor ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#ifndef _WIN32
|
||||
class setcolor {
|
||||
public:
|
||||
// Constructor
|
||||
explicit setcolor( term_attr::_ attr = term_attr::NORMAL,
|
||||
explicit setcolor( bool is_color_output = false,
|
||||
term_attr::_ attr = term_attr::NORMAL,
|
||||
term_color::_ fg = term_color::ORIGINAL,
|
||||
term_color::_ bg = term_color::ORIGINAL )
|
||||
: m_is_color_output(is_color_output)
|
||||
{
|
||||
m_command_size = std::sprintf( m_control_command, "%c[%d;%d;%dm", 0x1B, attr, fg + 30, bg + 40 );
|
||||
m_command_size = std::sprintf( m_control_command, "%c[%c;3%c;4%cm",
|
||||
0x1B,
|
||||
static_cast<char>(attr + '0'),
|
||||
static_cast<char>(fg + '0'),
|
||||
static_cast<char>(bg + '0'));
|
||||
}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<( std::ostream& os, setcolor const& sc )
|
||||
{
|
||||
return os.write( sc.m_control_command, sc.m_command_size );
|
||||
if (sc.m_is_color_output && (&os == &std::cout || &os == &std::cerr)) {
|
||||
return os.write( sc.m_control_command, sc.m_command_size );
|
||||
}
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
// Data members
|
||||
bool m_is_color_output;
|
||||
char m_control_command[13];
|
||||
int m_command_size;
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
class setcolor {
|
||||
|
||||
protected:
|
||||
void set_console_color(std::ostream& os, WORD *attributes = NULL) const {
|
||||
if (!m_is_color_output) {
|
||||
return;
|
||||
}
|
||||
DWORD console_type;
|
||||
if (&os == &std::cout) {
|
||||
console_type = STD_OUTPUT_HANDLE;
|
||||
}
|
||||
else if (&os == &std::cerr) {
|
||||
console_type = STD_ERROR_HANDLE;
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
HANDLE hConsole = GetStdHandle(console_type);
|
||||
|
||||
if(hConsole == INVALID_HANDLE_VALUE || hConsole == NULL )
|
||||
return;
|
||||
|
||||
if(attributes != NULL) {
|
||||
SetConsoleTextAttribute(hConsole, *attributes);
|
||||
return;
|
||||
}
|
||||
|
||||
CONSOLE_SCREEN_BUFFER_INFO consoleInfo;
|
||||
GetConsoleScreenBufferInfo(hConsole, &consoleInfo);
|
||||
saved_attributes = consoleInfo.wAttributes;
|
||||
|
||||
WORD fg_attr = 0;
|
||||
switch(m_fg)
|
||||
{
|
||||
case term_color::WHITE:
|
||||
fg_attr = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
break;
|
||||
case term_color::BLACK:
|
||||
fg_attr = 0;
|
||||
break;
|
||||
case term_color::RED:
|
||||
fg_attr = FOREGROUND_RED;
|
||||
break;
|
||||
case term_color::GREEN:
|
||||
fg_attr = FOREGROUND_GREEN;
|
||||
break;
|
||||
case term_color::CYAN:
|
||||
fg_attr = FOREGROUND_GREEN | FOREGROUND_BLUE;
|
||||
break;
|
||||
case term_color::MAGENTA:
|
||||
fg_attr = FOREGROUND_RED | FOREGROUND_BLUE;
|
||||
break;
|
||||
case term_color::BLUE:
|
||||
fg_attr = FOREGROUND_BLUE;
|
||||
break;
|
||||
case term_color::YELLOW:
|
||||
fg_attr = FOREGROUND_RED | FOREGROUND_GREEN;
|
||||
break;
|
||||
case term_color::ORIGINAL:
|
||||
default:
|
||||
fg_attr = saved_attributes & (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
|
||||
break;
|
||||
}
|
||||
|
||||
WORD bg_attr = 0;
|
||||
switch(m_bg)
|
||||
{
|
||||
case term_color::BLACK:
|
||||
bg_attr = 0;
|
||||
break;
|
||||
case term_color::WHITE:
|
||||
bg_attr = BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE;
|
||||
break;
|
||||
case term_color::RED:
|
||||
bg_attr = BACKGROUND_RED;
|
||||
break;
|
||||
case term_color::GREEN:
|
||||
bg_attr = BACKGROUND_GREEN;
|
||||
break;
|
||||
case term_color::BLUE:
|
||||
bg_attr = BACKGROUND_BLUE;
|
||||
break;
|
||||
case term_color::ORIGINAL:
|
||||
default:
|
||||
bg_attr = saved_attributes & (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE);
|
||||
break;
|
||||
}
|
||||
|
||||
WORD text_attr = 0;
|
||||
switch(m_attr)
|
||||
{
|
||||
case term_attr::BRIGHT:
|
||||
text_attr = FOREGROUND_INTENSITY;
|
||||
break;
|
||||
case term_attr::UNDERLINE:
|
||||
text_attr = COMMON_LVB_UNDERSCORE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
SetConsoleTextAttribute(hConsole, fg_attr | bg_attr | text_attr);
|
||||
return;
|
||||
}
|
||||
|
||||
public:
|
||||
// Constructor
|
||||
explicit setcolor(
|
||||
bool is_color_output = false,
|
||||
term_attr::_ attr = term_attr::NORMAL,
|
||||
term_color::_ fg = term_color::ORIGINAL,
|
||||
term_color::_ bg = term_color::ORIGINAL )
|
||||
: m_is_color_output(is_color_output)
|
||||
, m_attr(attr)
|
||||
, m_fg(fg)
|
||||
, m_bg(bg)
|
||||
{}
|
||||
|
||||
friend std::ostream&
|
||||
operator<<( std::ostream& os, setcolor const& sc )
|
||||
{
|
||||
sc.set_console_color(os);
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
bool m_is_color_output;
|
||||
term_attr::_ m_attr;
|
||||
term_color::_ m_fg;
|
||||
term_color::_ m_bg;
|
||||
|
||||
protected:
|
||||
// Data members
|
||||
mutable WORD saved_attributes;
|
||||
};
|
||||
|
||||
#endif
|
||||
// ************************************************************************** //
|
||||
// ************** scope_setcolor ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
struct scope_setcolor {
|
||||
scope_setcolor() : m_os( 0 ) {}
|
||||
explicit scope_setcolor( std::ostream& os,
|
||||
explicit scope_setcolor( bool is_color_output,
|
||||
std::ostream& os,
|
||||
term_attr::_ attr = term_attr::NORMAL,
|
||||
term_color::_ fg = term_color::ORIGINAL,
|
||||
term_color::_ bg = term_color::ORIGINAL )
|
||||
: m_os( &os )
|
||||
, m_is_color_output( is_color_output )
|
||||
{
|
||||
os << setcolor( attr, fg, bg );
|
||||
os << setcolor( is_color_output, attr, fg, bg );
|
||||
}
|
||||
~scope_setcolor()
|
||||
{
|
||||
if( m_os )
|
||||
*m_os << setcolor();
|
||||
*m_os << setcolor( m_is_color_output );
|
||||
}
|
||||
private:
|
||||
scope_setcolor(const scope_setcolor& r);
|
||||
scope_setcolor& operator=(const scope_setcolor& r);
|
||||
// Data members
|
||||
std::ostream* m_os;
|
||||
bool m_is_color_output;
|
||||
};
|
||||
|
||||
#define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \
|
||||
utils::scope_setcolor const& sc = is_color_output \
|
||||
? utils::scope_setcolor( os, utils::attr, utils::color ) \
|
||||
: utils::scope_setcolor(); \
|
||||
ut_detail::ignore_unused_variable_warning( sc ) \
|
||||
#else
|
||||
|
||||
struct scope_setcolor : setcolor {
|
||||
scope_setcolor() : m_os( 0 ) {}
|
||||
explicit scope_setcolor(
|
||||
bool is_color_output,
|
||||
std::ostream& os,
|
||||
term_attr::_ attr = term_attr::NORMAL,
|
||||
term_color::_ fg = term_color::ORIGINAL,
|
||||
term_color::_ bg = term_color::ORIGINAL )
|
||||
: setcolor(is_color_output, attr, fg, bg)
|
||||
, m_os( &os )
|
||||
{
|
||||
os << *this;
|
||||
}
|
||||
|
||||
~scope_setcolor()
|
||||
{
|
||||
if (m_os) {
|
||||
set_console_color(*m_os, &this->saved_attributes);
|
||||
}
|
||||
}
|
||||
private:
|
||||
scope_setcolor(const scope_setcolor& r);
|
||||
scope_setcolor& operator=(const scope_setcolor& r);
|
||||
// Data members
|
||||
std::ostream* m_os;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#define BOOST_TEST_SCOPE_SETCOLOR( is_color_output, os, attr, color ) \
|
||||
utils::scope_setcolor const sc(is_color_output, os, utils::attr, utils::color); \
|
||||
boost::ignore_unused( sc ) \
|
||||
/**/
|
||||
|
||||
} // namespace utils
|
||||
|
||||
164
winx64/include/boost/test/utils/timer.hpp
Normal file
164
winx64/include/boost/test/utils/timer.hpp
Normal file
@@ -0,0 +1,164 @@
|
||||
// (C) Copyright Raffi Enficiaud 2019.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.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 : timer and elapsed types
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_UTILS_TIMER_HPP
|
||||
#define BOOST_TEST_UTILS_TIMER_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <utility>
|
||||
#include <ctime>
|
||||
|
||||
# if defined(_WIN32) || defined(__CYGWIN__)
|
||||
# define BOOST_TEST_TIMER_WINDOWS_API
|
||||
# elif defined(__MACH__)// && !defined(CLOCK_MONOTONIC)
|
||||
# // we compile for all macs the same, CLOCK_MONOTONIC introduced in 10.12
|
||||
# define BOOST_TEST_TIMER_MACH_API
|
||||
# else
|
||||
# define BOOST_TEST_TIMER_POSIX_API
|
||||
# if !defined(CLOCK_MONOTONIC)
|
||||
# error "CLOCK_MONOTONIC not defined"
|
||||
# endif
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_TEST_TIMER_WINDOWS_API)
|
||||
# include <windows.h>
|
||||
# elif defined(BOOST_TEST_TIMER_MACH_API)
|
||||
# include <mach/mach_time.h>
|
||||
//# include <mach/mach.h> /* host_get_clock_service, mach_... */
|
||||
# else
|
||||
# include <sys/time.h>
|
||||
# endif
|
||||
|
||||
# ifdef BOOST_NO_STDC_NAMESPACE
|
||||
namespace std { using ::clock_t; using ::clock; }
|
||||
# endif
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
namespace timer {
|
||||
|
||||
struct elapsed_time
|
||||
{
|
||||
typedef boost::int_least64_t nanosecond_type;
|
||||
|
||||
nanosecond_type wall;
|
||||
nanosecond_type system;
|
||||
void clear() {
|
||||
wall = 0;
|
||||
system = 0;
|
||||
}
|
||||
};
|
||||
|
||||
inline double
|
||||
microsecond_wall_time( elapsed_time const& elapsed )
|
||||
{
|
||||
return elapsed.wall / 1E3;
|
||||
}
|
||||
|
||||
inline double
|
||||
second_wall_time( elapsed_time const& elapsed )
|
||||
{
|
||||
return elapsed.wall / 1E9;
|
||||
}
|
||||
|
||||
namespace details {
|
||||
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
|
||||
elapsed_time::nanosecond_type get_tick_freq() {
|
||||
LARGE_INTEGER freq;
|
||||
::QueryPerformanceFrequency( &freq );
|
||||
return static_cast<elapsed_time::nanosecond_type>(freq.QuadPart);
|
||||
}
|
||||
#elif defined(BOOST_TEST_TIMER_MACH_API)
|
||||
std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type> get_time_base() {
|
||||
mach_timebase_info_data_t timebase;
|
||||
if(mach_timebase_info(&timebase) == 0)
|
||||
return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(timebase.numer, timebase.denom);
|
||||
return std::pair<elapsed_time::nanosecond_type, elapsed_time::nanosecond_type>(0, 1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//! Simple timing class
|
||||
//!
|
||||
//! This class measures the wall clock time.
|
||||
class timer
|
||||
{
|
||||
public:
|
||||
timer()
|
||||
{
|
||||
restart();
|
||||
}
|
||||
void restart()
|
||||
{
|
||||
_start_time_clock = std::clock();
|
||||
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
|
||||
::QueryPerformanceCounter(&_start_time_wall);
|
||||
#elif defined(BOOST_TEST_TIMER_MACH_API)
|
||||
_start_time_wall = mach_absolute_time();
|
||||
#else
|
||||
if( ::clock_gettime( CLOCK_MONOTONIC, &_start_time_wall ) != 0 )
|
||||
{
|
||||
_start_time_wall.tv_nsec = -1;
|
||||
_start_time_wall.tv_sec = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// return elapsed time in seconds
|
||||
elapsed_time elapsed() const
|
||||
{
|
||||
typedef elapsed_time::nanosecond_type nanosecond_type;
|
||||
static const double clock_to_nano_seconds = 1E9 / CLOCKS_PER_SEC;
|
||||
elapsed_time return_value;
|
||||
|
||||
// processor / system time
|
||||
return_value.system = static_cast<nanosecond_type>(double(std::clock() - _start_time_clock) * clock_to_nano_seconds);
|
||||
|
||||
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
|
||||
static const nanosecond_type tick_per_sec = details::get_tick_freq();
|
||||
LARGE_INTEGER end_time;
|
||||
::QueryPerformanceCounter(&end_time);
|
||||
return_value.wall = static_cast<nanosecond_type>(((end_time.QuadPart - _start_time_wall.QuadPart) * 1E9) / tick_per_sec);
|
||||
#elif defined(BOOST_TEST_TIMER_MACH_API)
|
||||
static std::pair<nanosecond_type, nanosecond_type> timebase = details::get_time_base();
|
||||
nanosecond_type clock = mach_absolute_time() - _start_time_wall;
|
||||
return_value.wall = static_cast<nanosecond_type>((clock * timebase.first) / timebase.second);
|
||||
#else
|
||||
struct timespec end_time;
|
||||
if( ::clock_gettime( CLOCK_MONOTONIC, &end_time ) == 0 )
|
||||
{
|
||||
return_value.wall = static_cast<nanosecond_type>((end_time.tv_sec - _start_time_wall.tv_sec) * 1E9 + (end_time.tv_nsec - _start_time_wall.tv_nsec));
|
||||
}
|
||||
#endif
|
||||
|
||||
return return_value;
|
||||
}
|
||||
|
||||
private:
|
||||
std::clock_t _start_time_clock;
|
||||
#if defined(BOOST_TEST_TIMER_WINDOWS_API)
|
||||
LARGE_INTEGER _start_time_wall;
|
||||
#elif defined(BOOST_TEST_TIMER_MACH_API)
|
||||
elapsed_time::nanosecond_type _start_time_wall;
|
||||
#else
|
||||
struct timespec _start_time_wall;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace timer
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_TEST_UTILS_TIMER_HPP
|
||||
|
||||
@@ -1,79 +0,0 @@
|
||||
// (C) Copyright Gennadiy Rozental 2001.
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// (See accompanying file LICENSE_1_0.txt or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
// See http://www.boost.org/libs/test for the library home page.
|
||||
//
|
||||
// File : $RCSfile$
|
||||
//
|
||||
// Version : $Revision$
|
||||
//
|
||||
// Description : simple helpers for creating cusom output manipulators
|
||||
// ***************************************************************************
|
||||
|
||||
#ifndef BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
|
||||
#define BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
// Boost
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
namespace boost {
|
||||
namespace unit_test {
|
||||
|
||||
// ************************************************************************** //
|
||||
// ************** singleton ************** //
|
||||
// ************************************************************************** //
|
||||
|
||||
template<typename Derived>
|
||||
class singleton {
|
||||
public:
|
||||
static Derived& instance() { static Derived the_inst; return the_inst; }
|
||||
|
||||
BOOST_DELETED_FUNCTION(singleton(singleton const&))
|
||||
BOOST_DELETED_FUNCTION(singleton& operator=(singleton const&))
|
||||
|
||||
protected:
|
||||
BOOST_DEFAULTED_FUNCTION(singleton(), {})
|
||||
BOOST_DEFAULTED_FUNCTION(~singleton(), {})
|
||||
};
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
#define BOOST_TEST_SINGLETON_CONS( type ) \
|
||||
friend class boost::unit_test::singleton<type>; \
|
||||
type() {} \
|
||||
/**/
|
||||
|
||||
#if BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042))
|
||||
|
||||
#define BOOST_TEST_SINGLETON_INST( inst ) \
|
||||
template class unit_test::singleton< BOOST_JOIN( inst, _t ) > ; \
|
||||
namespace { BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }
|
||||
|
||||
#elif defined(__APPLE_CC__) && defined(__GNUC__) && __GNUC__ < 4
|
||||
#define BOOST_TEST_SINGLETON_INST( inst ) \
|
||||
static BOOST_JOIN( inst, _t)& inst = BOOST_JOIN (inst, _t)::instance();
|
||||
|
||||
#else
|
||||
|
||||
#define BOOST_TEST_SINGLETON_INST( inst ) \
|
||||
namespace { BOOST_JOIN( inst, _t)& inst = BOOST_JOIN( inst, _t)::instance(); }
|
||||
|
||||
#endif
|
||||
|
||||
//____________________________________________________________________________//
|
||||
|
||||
} // namespace unit_test
|
||||
} // namespace boost
|
||||
|
||||
|
||||
#include <boost/test/detail/enable_warnings.hpp>
|
||||
|
||||
#endif // BOOST_TEST_UTILS_TRIVIAL_SIGNLETON_HPP
|
||||
@@ -16,6 +16,7 @@
|
||||
#define BOOST_TEST_UTILS_XML_PRINTER_HPP
|
||||
|
||||
// Boost.Test
|
||||
#include <boost/test/detail/global_typedef.hpp>
|
||||
#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
|
||||
#include <boost/test/utils/custom_manip.hpp>
|
||||
#include <boost/test/utils/foreach.hpp>
|
||||
@@ -26,6 +27,7 @@
|
||||
|
||||
// STL
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
|
||||
#include <boost/test/detail/suppress_warnings.hpp>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user