]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/test/data/test_case.hpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / boost / test / data / test_case.hpp
1 // (C) Copyright Gennadiy Rozental 2001.
2 // Distributed under the Boost Software License, Version 1.0.
3 // (See accompanying file LICENSE_1_0.txt or copy at
4 // http://www.boost.org/LICENSE_1_0.txt)
5
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 //!@file
9 //!@brief test case family based on data generator
10 // ***************************************************************************
11
12 #ifndef BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
13 #define BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
14
15 // Boost.Test
16 #include <boost/test/data/config.hpp>
17 #include <boost/test/data/dataset.hpp>
18 #include <boost/test/data/for_each_sample.hpp>
19 #include <boost/test/tree/test_unit.hpp>
20
21 // Boost
22 #include <boost/preprocessor/repetition/enum_params.hpp>
23 #include <boost/preprocessor/repetition/enum_binary_params.hpp>
24 #include <boost/preprocessor/repetition/repeat_from_to.hpp>
25
26 #include <boost/preprocessor/variadic/to_seq.hpp>
27 #include <boost/preprocessor/variadic/size.hpp>
28 #include <boost/preprocessor/cat.hpp>
29 #include <boost/preprocessor/seq/for_each_i.hpp>
30 #include <boost/preprocessor/seq/for_each.hpp>
31 #include <boost/preprocessor/seq/enum.hpp>
32 #include <boost/preprocessor/control/iif.hpp>
33 #include <boost/preprocessor/comparison/equal.hpp>
34
35 #include <boost/bind.hpp>
36 #include <boost/type_traits/is_copy_constructible.hpp>
37
38 #include <boost/test/tools/detail/print_helper.hpp>
39 #include <boost/test/utils/string_cast.hpp>
40
41 #include <list>
42 #include <string>
43
44 #include <boost/test/detail/suppress_warnings.hpp>
45
46 #if defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) \
47 && !defined(BOOST_TEST_DATASET_MAX_ARITY)
48 # define BOOST_TEST_DATASET_MAX_ARITY 10
49 #endif
50
51 //____________________________________________________________________________//
52
53 namespace boost {
54 namespace unit_test {
55 namespace data {
56
57 namespace ds_detail {
58
59 // ************************************************************************** //
60 // ************** seed ************** //
61 // ************************************************************************** //
62
63 struct seed {
64 template<typename DataSet>
65 typename data::result_of::make<DataSet>::type
66 operator->*( DataSet&& ds ) const
67 {
68 return data::make( std::forward<DataSet>( ds ) );
69 }
70 };
71
72
73 #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) && \
74 !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) && \
75 !defined(BOOST_NO_CXX11_DECLTYPE) && \
76 !defined(BOOST_NO_CXX11_TRAILING_RESULT_TYPES) && \
77 !defined(BOOST_NO_CXX11_SMART_PTR)
78
79 #define BOOST_TEST_DATASET_VARIADIC
80 template <class T>
81 struct parameter_holder {
82 std::shared_ptr<T> value;
83
84 parameter_holder(T && value_)
85 : value(std::make_shared<T>(std::move(value_)))
86 {}
87
88 operator T const&() const {
89 return *value;
90 }
91 };
92
93 template <class T>
94 parameter_holder<typename std::remove_reference<T>::type>
95 boost_bind_rvalue_holder_helper_impl(T&& value, boost::false_type /* is copy constructible */) {
96 return parameter_holder<typename std::remove_reference<T>::type>(std::forward<T>(value));
97 }
98
99 template <class T>
100 T&& boost_bind_rvalue_holder_helper_impl(T&& value, boost::true_type /* is copy constructible */) {
101 return std::forward<T>(value);
102 }
103
104 template <class T>
105 auto boost_bind_rvalue_holder_helper(T&& value)
106 -> decltype(boost_bind_rvalue_holder_helper_impl(
107 std::forward<T>(value),
108 typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type()))
109 {
110 // need to use boost::is_copy_constructible because std::is_copy_constructible is broken on MSVC12
111 return boost_bind_rvalue_holder_helper_impl(
112 std::forward<T>(value),
113 typename boost::is_copy_constructible<typename std::remove_reference<T>::type>::type());
114 }
115
116 #endif
117
118
119 // ************************************************************************** //
120 // ************** test_case_gen ************** //
121 // ************************************************************************** //
122
123 template<typename TestCase,typename DataSet>
124 class test_case_gen : public test_unit_generator {
125 public:
126 // Constructor
127 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
128 test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
129 : m_dataset( std::forward<DataSet>( ds ) )
130 , m_generated( false )
131 , m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
132 , m_tc_file( tc_file )
133 , m_tc_line( tc_line )
134 , m_tc_index( 0 )
135 {}
136 test_case_gen( test_case_gen&& gen )
137 : m_dataset( std::move( gen.m_dataset ) )
138 , m_generated( gen.m_generated )
139 , m_tc_name( gen.m_tc_name )
140 , m_tc_file( gen.m_tc_file )
141 , m_tc_line( gen.m_tc_line )
142 , m_tc_index( gen.m_tc_index )
143 , m_test_cases( std::move(gen.m_test_cases) )
144 {}
145 #else
146 test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
147 : m_dataset( ds )
148 , m_generated( false )
149 , m_tc_name( ut_detail::normalize_test_case_name( tc_name ) )
150 , m_tc_file( tc_file )
151 , m_tc_line( tc_line )
152 , m_tc_index( 0 )
153 {}
154 #endif
155
156 public:
157 virtual test_unit* next() const
158 {
159 if(!m_generated) {
160 data::for_each_sample( m_dataset, *this );
161 m_generated = true;
162 }
163
164 if( m_test_cases.empty() )
165 return 0;
166
167 test_unit* res = m_test_cases.front();
168 m_test_cases.pop_front();
169
170 return res;
171 }
172
173
174 #if !defined(BOOST_TEST_DATASET_VARIADIC)
175 // see BOOST_TEST_DATASET_MAX_ARITY to increase the default supported arity
176 // there is also a limit on boost::bind
177 #define TC_MAKE(z,arity,_) \
178 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
179 void operator()( BOOST_PP_ENUM_BINARY_PARAMS(arity, Arg, const& arg) ) const \
180 { \
181 m_test_cases.push_back( new test_case( genTestCaseName(), m_tc_file, m_tc_line, \
182 boost::bind( &TestCase::template test_method<BOOST_PP_ENUM_PARAMS(arity,Arg)>,\
183 BOOST_PP_ENUM_PARAMS(arity, arg) ) ) ); \
184 } \
185
186 BOOST_PP_REPEAT_FROM_TO(1, BOOST_TEST_DATASET_MAX_ARITY, TC_MAKE, _)
187 #else
188 template<typename ...Arg>
189 void operator()(Arg&& ... arg) const
190 {
191 m_test_cases.push_back(
192 new test_case( genTestCaseName(),
193 m_tc_file,
194 m_tc_line,
195 std::bind( &TestCase::template test_method<Arg...>,
196 boost_bind_rvalue_holder_helper(std::forward<Arg>(arg))...)));
197 }
198 #endif
199
200 private:
201 std::string genTestCaseName() const
202 {
203 return "_" + utils::string_cast(m_tc_index++);
204 }
205
206 // Data members
207 DataSet m_dataset;
208 mutable bool m_generated;
209 std::string m_tc_name;
210 const_string m_tc_file;
211 std::size_t m_tc_line;
212 mutable std::size_t m_tc_index;
213 mutable std::list<test_unit*> m_test_cases;
214 };
215
216 //____________________________________________________________________________//
217
218 #ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
219 template<typename TestCase,typename DataSet>
220 boost::shared_ptr<test_unit_generator> //test_case_gen<TestCase,DataSet>
221 make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet&& ds )
222 {
223 return boost::shared_ptr<test_unit_generator>(new test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, std::forward<DataSet>(ds) ));
224 }
225 #else
226 template<typename TestCase,typename DataSet>
227 test_case_gen<TestCase,DataSet>
228 make_test_case_gen( const_string tc_name, const_string tc_file, std::size_t tc_line, DataSet const& ds )
229 {
230 return test_case_gen<TestCase,DataSet>( tc_name, tc_file, tc_line, ds );
231 }
232 #endif
233
234 //____________________________________________________________________________//
235
236 } // namespace ds_detail
237
238 // ************************************************************************** //
239 // ************** BOOST_DATA_TEST_CASE ************** //
240 // ************************************************************************** //
241
242 #define BOOST_DATA_TEST_CASE_PARAM(r, _, i, param) (BOOST_PP_CAT(Arg, i) const& param)
243 #define BOOST_DATA_TEST_CONTEXT(r, _, param) << BOOST_STRINGIZE(param) << " = " << boost::test_tools::tt_detail::print_helper(param) << "; "
244
245 #define BOOST_DATA_TEST_CASE_PARAMS( params ) \
246 BOOST_PP_SEQ_ENUM( \
247 BOOST_PP_SEQ_FOR_EACH_I(BOOST_DATA_TEST_CASE_PARAM, _, params)) \
248 /**/
249
250 #define BOOST_DATA_TEST_CASE_IMPL(arity, F, test_name, dataset, params) \
251 struct BOOST_PP_CAT(test_name, case) : public F { \
252 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
253 static void test_method( BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
254 { \
255 BOOST_TEST_CONTEXT( "" \
256 BOOST_PP_SEQ_FOR_EACH(BOOST_DATA_TEST_CONTEXT, _, params)) \
257 { \
258 BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture ctor");\
259 BOOST_PP_CAT(test_name, case) t; \
260 BOOST_TEST_CHECKPOINT('"' \
261 << #test_name << "\" fixture setup"); \
262 boost::unit_test::setup_conditional(t); \
263 BOOST_TEST_CHECKPOINT('"' << #test_name << "\" test entry"); \
264 t._impl(BOOST_PP_SEQ_ENUM(params)); \
265 BOOST_TEST_CHECKPOINT('"' \
266 << #test_name << "\" fixture teardown"); \
267 boost::unit_test::teardown_conditional(t); \
268 BOOST_TEST_CHECKPOINT('"' << #test_name << "\" fixture dtor");\
269 } \
270 } \
271 private: \
272 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
273 void _impl(BOOST_DATA_TEST_CASE_PARAMS( params )); \
274 }; \
275 \
276 BOOST_AUTO_TEST_SUITE( test_name, \
277 *boost::unit_test::decorator::stack_decorator()) \
278 \
279 BOOST_AUTO_TU_REGISTRAR( BOOST_PP_CAT(test_name, case) )( \
280 boost::unit_test::data::ds_detail::make_test_case_gen< \
281 BOOST_PP_CAT(test_name, case)>( \
282 BOOST_STRINGIZE( test_name ), \
283 __FILE__, __LINE__, \
284 boost::unit_test::data::ds_detail::seed{} ->* dataset ), \
285 boost::unit_test::decorator::collector_t::instance() ); \
286 \
287 BOOST_AUTO_TEST_SUITE_END() \
288 \
289 template<BOOST_PP_ENUM_PARAMS(arity, typename Arg)> \
290 void BOOST_PP_CAT(test_name, case)::_impl( \
291 BOOST_DATA_TEST_CASE_PARAMS( params ) ) \
292 /**/
293
294 #define BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, ... ) \
295 BOOST_DATA_TEST_CASE_IMPL( BOOST_PP_VARIADIC_SIZE(__VA_ARGS__), \
296 F, test_name, dataset, \
297 BOOST_PP_VARIADIC_TO_SEQ(__VA_ARGS__) ) \
298 /**/
299 #define BOOST_DATA_TEST_CASE_NO_PARAMS( F, test_name, dataset ) \
300 BOOST_DATA_TEST_CASE_WITH_PARAMS( F, test_name, dataset, sample ) \
301 /**/
302
303 #if BOOST_PP_VARIADICS_MSVC
304
305 #define BOOST_DATA_TEST_CASE( ... ) \
306 BOOST_PP_CAT( \
307 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
308 BOOST_DATA_TEST_CASE_NO_PARAMS, \
309 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
310 BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__), ) \
311 /**/
312
313 #define BOOST_DATA_TEST_CASE_F( F, ... ) \
314 BOOST_PP_CAT( \
315 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
316 BOOST_DATA_TEST_CASE_NO_PARAMS, \
317 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
318 F, __VA_ARGS__), ) \
319 /**/
320
321 #else
322
323 #define BOOST_DATA_TEST_CASE( ... ) \
324 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
325 BOOST_DATA_TEST_CASE_NO_PARAMS, \
326 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
327 BOOST_AUTO_TEST_CASE_FIXTURE, __VA_ARGS__) \
328 /**/
329
330 #define BOOST_DATA_TEST_CASE_F( F, ... ) \
331 BOOST_PP_IIF(BOOST_PP_EQUAL(BOOST_PP_VARIADIC_SIZE(__VA_ARGS__),2), \
332 BOOST_DATA_TEST_CASE_NO_PARAMS, \
333 BOOST_DATA_TEST_CASE_WITH_PARAMS) ( \
334 F, __VA_ARGS__) \
335 /**/
336 #endif
337
338 } // namespace data
339 } // namespace unit_test
340 } // namespace boost
341
342 #include <boost/test/detail/enable_warnings.hpp>
343
344 #endif // BOOST_TEST_DATA_TEST_CASE_HPP_102211GER
345