summaryrefslogtreecommitdiff
path: root/boost/test
diff options
context:
space:
mode:
Diffstat (limited to 'boost/test')
-rw-r--r--boost/test/data/config.hpp5
-rw-r--r--boost/test/data/for_each_sample.hpp2
-rw-r--r--boost/test/data/generators.hpp19
-rw-r--r--boost/test/data/index_sequence.hpp5
-rw-r--r--boost/test/data/monomorphic.hpp1
-rw-r--r--boost/test/data/monomorphic/delayed.hpp122
-rw-r--r--boost/test/data/monomorphic/fwd.hpp48
-rw-r--r--boost/test/data/monomorphic/grid.hpp7
-rw-r--r--boost/test/data/monomorphic/initializer_list.hpp75
-rw-r--r--boost/test/data/monomorphic/zip.hpp59
-rw-r--r--boost/test/data/test_case.hpp35
-rw-r--r--boost/test/execution_monitor.hpp6
-rw-r--r--boost/test/impl/decorator.ipp8
-rw-r--r--boost/test/impl/framework.ipp14
-rw-r--r--boost/test/impl/results_collector.ipp22
-rw-r--r--boost/test/impl/test_tree.ipp46
-rw-r--r--boost/test/impl/unit_test_main.ipp23
-rw-r--r--boost/test/impl/unit_test_parameters.ipp5
-rw-r--r--boost/test/results_collector.hpp6
-rw-r--r--boost/test/tree/auto_registration.hpp1
-rw-r--r--boost/test/tree/decorator.hpp2
-rw-r--r--boost/test/tree/test_case_template.hpp7
-rw-r--r--boost/test/tree/test_unit.hpp18
-rw-r--r--boost/test/unit_test_monitor.hpp4
-rw-r--r--boost/test/unit_test_parameters.hpp14
-rw-r--r--boost/test/utils/basic_cstring/compare.hpp2
-rw-r--r--boost/test/utils/runtime/cla/parser.hpp43
27 files changed, 496 insertions, 103 deletions
diff --git a/boost/test/data/config.hpp b/boost/test/data/config.hpp
index 7a9d03be98..e1d15b5013 100644
--- a/boost/test/data/config.hpp
+++ b/boost/test/data/config.hpp
@@ -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 ) )
diff --git a/boost/test/data/for_each_sample.hpp b/boost/test/data/for_each_sample.hpp
index 4785b038cc..6cb40bd33c 100644
--- a/boost/test/data/for_each_sample.hpp
+++ b/boost/test/data/for_each_sample.hpp
@@ -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 )
{
diff --git a/boost/test/data/generators.hpp b/boost/test/data/generators.hpp
deleted file mode 100644
index e9bd4c17b5..0000000000
--- a/boost/test/data/generators.hpp
+++ /dev/null
@@ -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
-
diff --git a/boost/test/data/index_sequence.hpp b/boost/test/data/index_sequence.hpp
index 21af7e504c..05b48f7f97 100644
--- a/boost/test/data/index_sequence.hpp
+++ b/boost/test/data/index_sequence.hpp
@@ -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;
diff --git a/boost/test/data/monomorphic.hpp b/boost/test/data/monomorphic.hpp
index 31d7b01b32..e5f2d3ad21 100644
--- a/boost/test/data/monomorphic.hpp
+++ b/boost/test/data/monomorphic.hpp
@@ -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
diff --git a/boost/test/data/monomorphic/delayed.hpp b/boost/test/data/monomorphic/delayed.hpp
new file mode 100644
index 0000000000..eecf117a8d
--- /dev/null
+++ b/boost/test/data/monomorphic/delayed.hpp
@@ -0,0 +1,122 @@
+// (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 <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());
+ using sample = typename dataset_t::sample;
+
+ 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
+
+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
diff --git a/boost/test/data/monomorphic/fwd.hpp b/boost/test/data/monomorphic/fwd.hpp
index dcd1b84165..82d3ff354d 100644
--- a/boost/test/data/monomorphic/fwd.hpp
+++ b/boost/test/data/monomorphic/fwd.hpp
@@ -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
// ************************************************************************** //
@@ -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.
diff --git a/boost/test/data/monomorphic/grid.hpp b/boost/test/data/monomorphic/grid.hpp
index 2cf66189a0..ee138df15d 100644
--- a/boost/test/data/monomorphic/grid.hpp
+++ b/boost/test/data/monomorphic/grid.hpp
@@ -104,7 +104,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:
@@ -140,8 +143,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 ) );
}
diff --git a/boost/test/data/monomorphic/initializer_list.hpp b/boost/test/data/monomorphic/initializer_list.hpp
index 3221597396..3f4a4df045 100644
--- a/boost/test/data/monomorphic/initializer_list.hpp
+++ b/boost/test/data/monomorphic/initializer_list.hpp
@@ -16,6 +16,7 @@
#include <boost/test/data/config.hpp>
#include <boost/test/data/monomorphic/fwd.hpp>
+#include <boost/core/ignore_unused.hpp>
#include <boost/test/detail/suppress_warnings.hpp>
//____________________________________________________________________________//
@@ -26,10 +27,14 @@ 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:
@@ -37,12 +42,22 @@ public:
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 +65,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 +118,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
diff --git a/boost/test/data/monomorphic/zip.hpp b/boost/test/data/monomorphic/zip.hpp
index 5fc65d0e20..04e390e9ac 100644
--- a/boost/test/data/monomorphic/zip.hpp
+++ b/boost/test/data/monomorphic/zip.hpp
@@ -75,28 +75,47 @@ public:
//! 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 +126,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 +146,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 )*/ );
}
//____________________________________________________________________________//
diff --git a/boost/test/data/test_case.hpp b/boost/test/data/test_case.hpp
index 01dc91b06a..eecbee9065 100644
--- a/boost/test/data/test_case.hpp
+++ b/boost/test/data/test_case.hpp
@@ -126,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 )
@@ -142,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_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;
@@ -162,6 +170,7 @@ 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
@@ -195,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;
@@ -206,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>
diff --git a/boost/test/execution_monitor.hpp b/boost/test/execution_monitor.hpp
index ed06ef254e..eb3b21c6dc 100644
--- a/boost/test/execution_monitor.hpp
+++ b/boost/test/execution_monitor.hpp
@@ -515,8 +515,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)
diff --git a/boost/test/impl/decorator.ipp b/boost/test/impl/decorator.ipp
index 74d42b22a2..0cc562ee2f 100644
--- a/boost/test/impl/decorator.ipp
+++ b/boost/test/impl/decorator.ipp
@@ -64,6 +64,14 @@ collector::reset()
//____________________________________________________________________________//
+std::vector<base_ptr>
+collector::get_lazy_decorators() const
+{
+ return m_tu_decorators;
+}
+
+//____________________________________________________________________________//
+
// ************************************************************************** //
// ************** decorator::base ************** //
// ************************************************************************** //
diff --git a/boost/test/impl/framework.ipp b/boost/test/impl/framework.ipp
index 496e7de859..ddb0144d27 100644
--- a/boost/test/impl/framework.ipp
+++ b/boost/test/impl/framework.ipp
@@ -692,7 +692,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
@@ -707,7 +710,7 @@ public:
break;
test_results const& test_rslt = unit_test::results_collector.results( m_curr_test_unit );
if( test_rslt.aborted() ) {
- result = unit_test_monitor_t::precondition_failure;
+ result = unit_test_monitor_t::test_setup_failure;
break;
}
}
@@ -1178,6 +1181,13 @@ finalize_setup_phase( test_unit_id master_tu_id )
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();
+ 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() )
diff --git a/boost/test/impl/results_collector.ipp b/boost/test/impl/results_collector.ipp
index fd74bdb65c..ea5050937b 100644
--- a/boost/test/impl/results_collector.ipp
+++ b/boost/test/impl/results_collector.ipp
@@ -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
@@ -52,13 +50,17 @@ 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_test_cases_skipped == 0 &&
!p_aborted;
}
+//____________________________________________________________________________//
+
bool
test_results::aborted() const
{
@@ -67,6 +69,14 @@ test_results::aborted() const
//____________________________________________________________________________//
+bool
+test_results::skipped() const
+{
+ return p_skipped;
+}
+
+//____________________________________________________________________________//
+
int
test_results::result_code() const
{
diff --git a/boost/test/impl/test_tree.ipp b/boost/test/impl/test_tree.ipp
index e0839e3dd1..cb48be4a99 100644
--- a/boost/test/impl/test_tree.ipp
+++ b/boost/test/impl/test_tree.ipp
@@ -124,7 +124,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;
}
@@ -281,10 +281,46 @@ test_suite::add( test_unit_generator const& gen, decorator::collector& decorator
decorators.store_in( *tu );
add( tu, 0 );
}
+ decorators.reset();
+}
+void
+test_suite::add( boost::shared_ptr<test_unit_generator> gen_ptr, decorator::collector& 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
@@ -457,6 +493,14 @@ auto_test_unit_registrar::auto_test_unit_registrar( test_unit_generator const& t
//____________________________________________________________________________//
+auto_test_unit_registrar::auto_test_unit_registrar( boost::shared_ptr<test_unit_generator> tc_gen, decorator::collector& decorators )
+{
+ framework::current_auto_test_suite().add( tc_gen, decorators );
+}
+
+
+//____________________________________________________________________________//
+
auto_test_unit_registrar::auto_test_unit_registrar( int )
{
framework::current_auto_test_suite( 0, false );
diff --git a/boost/test/impl/unit_test_main.ipp b/boost/test/impl/unit_test_main.ipp
index 1780c6b93b..cad3d88ec6 100644
--- a/boost/test/impl/unit_test_main.ipp
+++ b/boost/test/impl/unit_test_main.ipp
@@ -174,18 +174,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 ) ) {
@@ -247,14 +263,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;
}
diff --git a/boost/test/impl/unit_test_parameters.ipp b/boost/test/impl/unit_test_parameters.ipp
index 428c10116f..fec7bb94ca 100644
--- a/boost/test/impl/unit_test_parameters.ipp
+++ b/boost/test/impl/unit_test_parameters.ipp
@@ -351,7 +351,7 @@ register_parameters( rt::parameters_store& store )
rt::env_var = "BOOST_TEST_LOG_SINK",
rt::value_hint = "<stderr|stdout|file name>",
rt::help = "Sets the log sink - the location "
- "where Boost.Test writes the logs of the test execution. it allows to easily redirect the "
+ "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,8 +380,7 @@ register_parameters( rt::parameters_store& store )
,
#endif
rt::help = "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 "
+ " 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 "
diff --git a/boost/test/results_collector.hpp b/boost/test/results_collector.hpp
index 3acd7b87bc..75a0e551cd 100644
--- a/boost/test/results_collector.hpp
+++ b/boost/test/results_collector.hpp
@@ -79,6 +79,12 @@ public:
/// 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;
diff --git a/boost/test/tree/auto_registration.hpp b/boost/test/tree/auto_registration.hpp
index a3fe32fda7..98bc2924fd 100644
--- a/boost/test/tree/auto_registration.hpp
+++ b/boost/test/tree/auto_registration.hpp
@@ -40,6 +40,7 @@ struct BOOST_TEST_DECL auto_test_unit_registrar {
auto_test_unit_registrar( test_case* tc, decorator::collector& decorators, counter_t exp_fail = 0 );
explicit auto_test_unit_registrar( const_string ts_name, const_string ts_file, std::size_t ts_line, decorator::collector& decorators );
explicit auto_test_unit_registrar( test_unit_generator const& tc_gen, decorator::collector& decorators );
+ explicit auto_test_unit_registrar( boost::shared_ptr<test_unit_generator> tc_gen, decorator::collector& decorators );
explicit auto_test_unit_registrar( int );
};
diff --git a/boost/test/tree/decorator.hpp b/boost/test/tree/decorator.hpp
index 27c46682a0..f891a27765 100644
--- a/boost/test/tree/decorator.hpp
+++ b/boost/test/tree/decorator.hpp
@@ -59,6 +59,8 @@ public:
void store_in( test_unit& tu );
void reset();
+
+ std::vector<base_ptr> get_lazy_decorators() const;
private:
BOOST_TEST_SINGLETON_CONS( collector )
diff --git a/boost/test/tree/test_case_template.hpp b/boost/test/tree/test_case_template.hpp
index 83a13f00f5..f588e12e9f 100644
--- a/boost/test/tree/test_case_template.hpp
+++ b/boost/test/tree/test_case_template.hpp
@@ -141,10 +141,11 @@ public:
}
};
-// adding support for tuple
+// Describing template test cases with tuples
#if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
!defined(BOOST_NO_CXX11_HDR_TUPLE) && \
- !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS)
+ !defined(BOOST_NO_CXX11_AUTO_DECLARATIONS) && \
+ !defined(BOOST_NO_CXX11_TEMPLATE_ALIASES)
template<typename TestCaseTemplate, typename... tuple_parameter_pack>
class template_test_case_gen<TestCaseTemplate, std::tuple<tuple_parameter_pack...> > : public template_test_case_gen_base {
@@ -179,7 +180,7 @@ public:
}
};
-#endif /* C++11 variadic and tuples */
+#endif /* C++11 variadic, tuples and type alias */
} // namespace ut_detail
} // unit_test
diff --git a/boost/test/tree/test_unit.hpp b/boost/test/tree/test_unit.hpp
index 273fa14ff3..1441bdc7dd 100644
--- a/boost/test/tree/test_unit.hpp
+++ b/boost/test/tree/test_unit.hpp
@@ -43,6 +43,7 @@ namespace unit_test {
namespace framework {
class state;
+BOOST_TEST_DECL master_test_suite_t& master_test_suite();
}
// ************************************************************************** //
@@ -176,9 +177,15 @@ public:
/// @overload
void add( test_unit_generator const& gen, decorator::collector& decorators );
+
+ /// @overload
+ void add( boost::shared_ptr<test_unit_generator> gen_ptr, decorator::collector& 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( );
// access methods
@@ -199,6 +206,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 +215,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 master_test_suite_t& boost::unit_test::framework::master_test_suite();
};
// ************************************************************************** //
diff --git a/boost/test/unit_test_monitor.hpp b/boost/test/unit_test_monitor.hpp
index 1f937fa674..4402b79e73 100644
--- a/boost/test/unit_test_monitor.hpp
+++ b/boost/test/unit_test_monitor.hpp
@@ -34,7 +34,9 @@ class BOOST_TEST_DECL unit_test_monitor_t : public singleton<unit_test_monitor_t
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,
diff --git a/boost/test/unit_test_parameters.hpp b/boost/test/unit_test_parameters.hpp
index e01bbd7aed..e7e60d344f 100644
--- a/boost/test/unit_test_parameters.hpp
+++ b/boost/test/unit_test_parameters.hpp
@@ -112,11 +112,21 @@ public:
if( stream_name == "stderr" ) {
m_stream = &std::cerr;
- m_cleaner.reset();
+ 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;
- m_cleaner.reset();
+ if (cleaner_callback) {
+ m_cleaner = boost::make_shared<callback_cleaner>(cleaner_callback);
+ }
+ else {
+ m_cleaner.reset();
+ }
}
else {
m_cleaner = boost::make_shared<callback_cleaner>(cleaner_callback);
diff --git a/boost/test/utils/basic_cstring/compare.hpp b/boost/test/utils/basic_cstring/compare.hpp
index 2a256fc6be..b6dc15ab77 100644
--- a/boost/test/utils/basic_cstring/compare.hpp
+++ b/boost/test/utils/basic_cstring/compare.hpp
@@ -82,7 +82,7 @@ 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()
diff --git a/boost/test/utils/runtime/cla/parser.hpp b/boost/test/utils/runtime/cla/parser.hpp
index a57091b474..de8943884b 100644
--- a/boost/test/utils/runtime/cla/parser.hpp
+++ b/boost/test/utils/runtime/cla/parser.hpp
@@ -211,10 +211,15 @@ 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 )
@@ -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