blob: 42933e4dca032a9be29dd4e54b2c390a5d1f4dec [file] [log] [blame]
Jeff Thompsonef2d5a42013-08-22 19:09:24 -07001// (C) Copyright Gennadiy Rozental 2001-2008.
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 : $RCSfile$
9//
10// Version : $Revision: 54633 $
11//
12// Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
13// ***************************************************************************
14
15#ifndef BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
16#define BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
17
18// Boost.Test
19#include <ndnboost/test/detail/config.hpp>
20#include <ndnboost/test/detail/global_typedef.hpp>
21#include <ndnboost/test/utils/class_properties.hpp>
22#include <ndnboost/test/utils/callback.hpp>
23#include <ndnboost/test/detail/fwd_decl.hpp>
24#include <ndnboost/test/detail/workaround.hpp>
25#include <ndnboost/test/test_observer.hpp>
26
27// Boost
28#include <ndnboost/shared_ptr.hpp>
29#include <ndnboost/mpl/for_each.hpp>
30#include <ndnboost/mpl/identity.hpp>
31#include <ndnboost/type.hpp>
32#include <ndnboost/type_traits/is_const.hpp>
33
34// STL
35#include <typeinfo> // for typeid
36#include <string> // for std::string
37#include <list> // for std::list
38#include <vector> // for std::vector
39
40#include <ndnboost/test/detail/suppress_warnings.hpp>
41
42//____________________________________________________________________________//
43
44namespace ndnboost {
45
46namespace unit_test {
47
48// ************************************************************************** //
49// ************** test_unit ************** //
50// ************************************************************************** //
51
52class BOOST_TEST_DECL test_unit {
53public:
54 enum { type = tut_any };
55
56 // Constructor
57 test_unit( const_string tu_name, test_unit_type t );
58
59 // dependencies management
60 void depends_on( test_unit* tu );
61 bool check_dependencies() const;
62
63 // Public r/o properties
64 typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl)) id_t;
65 typedef BOOST_READONLY_PROPERTY(test_unit_id,(test_suite)) parent_id_t;
66 readonly_property<test_unit_type> p_type; // type for this test unit
67 readonly_property<const_string> p_type_name; // "case"/"suite"
68 id_t p_id; // unique id for this test unit
69 parent_id_t p_parent_id; // parent test suite id
70
71 // Public r/w properties
72 readwrite_property<std::string> p_name; // name for this test unit
73 readwrite_property<unsigned> p_timeout; // timeout for the test unit execution
74 readwrite_property<counter_t> p_expected_failures; // number of expected failures in this test unit
75 mutable readwrite_property<bool> p_enabled; // enabled status for this unit
76
77 void increase_exp_fail( unsigned num );
78
79protected:
80 ~test_unit();
81
82private:
83 // Data members
84 std::list<test_unit_id> m_dependencies;
85};
86
87// ************************************************************************** //
88// ************** test_case_generator ************** //
89// ************************************************************************** //
90
91class BOOST_TEST_DECL test_unit_generator {
92public:
93 virtual test_unit* next() const = 0;
94
95protected:
96 BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
97};
98
99// ************************************************************************** //
100// ************** test_case ************** //
101// ************************************************************************** //
102
103class BOOST_TEST_DECL test_case : public test_unit {
104public:
105 enum { type = tut_case };
106
107 // Constructor
108 test_case( const_string tc_name, callback0<> const& test_func );
109
110 // Access methods
111 callback0<> const& test_func() const { return m_test_func; }
112
113private:
114 friend class framework_impl;
115 ~test_case() {}
116
117 // BOOST_MSVC <= 1200 have problems with callback as property
118 // Data members
119 callback0<> m_test_func;
120};
121
122// ************************************************************************** //
123// ************** test_suite ************** //
124// ************************************************************************** //
125
126class BOOST_TEST_DECL test_suite : public test_unit {
127public:
128 enum { type = tut_suite };
129
130 // Constructor
131 explicit test_suite( const_string ts_name );
132
133 // test unit list management
134 void add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
135 void add( test_unit_generator const& gen, unsigned timeout = 0 );
136 void remove( test_unit_id id );
137
138 // access methods
139 test_unit_id get( const_string tu_name ) const;
140 std::size_t size() const { return m_members.size(); }
141
142protected:
143 friend BOOST_TEST_DECL
144 void traverse_test_tree( test_suite const&, test_tree_visitor& );
145 friend class framework_impl;
146 virtual ~test_suite() {}
147
148 // Data members
149 std::vector<test_unit_id> m_members;
150};
151
152// ************************************************************************** //
153// ************** master_test_suite ************** //
154// ************************************************************************** //
155
156class BOOST_TEST_DECL master_test_suite_t : public test_suite {
157public:
158 master_test_suite_t() : test_suite( "Master Test Suite" )
159 , argc( 0 )
160 , argv( 0 )
161 {}
162
163 // Data members
164 int argc;
165 char** argv;
166};
167
168
169// ************************************************************************** //
170// ************** test_tree_visitor ************** //
171// ************************************************************************** //
172
173class BOOST_TEST_DECL test_tree_visitor {
174public:
175 // test tree visitor interface
176 virtual void visit( test_case const& ) {}
177 virtual bool test_suite_start( test_suite const& ) { return true; }
178 virtual void test_suite_finish( test_suite const& ) {}
179
180protected:
181 BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
182};
183
184// ************************************************************************** //
185// ************** traverse_test_tree ************** //
186// ************************************************************************** //
187
188BOOST_TEST_DECL void traverse_test_tree( test_case const&, test_tree_visitor& );
189BOOST_TEST_DECL void traverse_test_tree( test_suite const&, test_tree_visitor& );
190BOOST_TEST_DECL void traverse_test_tree( test_unit_id , test_tree_visitor& );
191
192//____________________________________________________________________________//
193
194inline void
195traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
196{
197 if( tu.p_type == tut_case )
198 traverse_test_tree( static_cast<test_case const&>( tu ), V );
199 else
200 traverse_test_tree( static_cast<test_suite const&>( tu ), V );
201}
202
203//____________________________________________________________________________//
204
205// ************************************************************************** //
206// ************** test_case_counter ************** //
207// ************************************************************************** //
208
209class test_case_counter : public test_tree_visitor {
210public:
211 // Constructor
212 test_case_counter() : p_count( 0 ) {}
213
214 BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
215private:
216 // test tree visitor interface
217 virtual void visit( test_case const& );
218 virtual bool test_suite_start( test_suite const& ts ) { return ts.p_enabled; }
219};
220
221// ************************************************************************** //
222// ************** test_being_aborted ************** //
223// ************************************************************************** //
224
225struct BOOST_TEST_DECL test_being_aborted {};
226
227// ************************************************************************** //
228// ************** object generators ************** //
229// ************************************************************************** //
230
231namespace ut_detail {
232
233BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );
234
235template<typename InstanceType,typename UserTestCase>
236struct user_tc_method_invoker {
237 typedef void (UserTestCase::*TestMethod )();
238
239 user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
240 : m_inst( inst ), m_test_method( test_method ) {}
241
242 void operator()() { ((*m_inst).*m_test_method)(); }
243
244 shared_ptr<InstanceType> m_inst;
245 TestMethod m_test_method;
246};
247
248} // namespace ut_detail
249
250//____________________________________________________________________________//
251
252inline test_case*
253make_test_case( callback0<> const& test_func, const_string tc_name )
254{
255 return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
256}
257
258//____________________________________________________________________________//
259
260template<typename UserTestCase, typename InstanceType>
261inline test_case*
262make_test_case( void (UserTestCase::* test_method )(),
263 const_string tc_name,
264 ndnboost::shared_ptr<InstanceType> user_test_case )
265{
266 return new test_case( ut_detail::normalize_test_case_name( tc_name ),
267 ut_detail::user_tc_method_invoker<InstanceType,UserTestCase>( user_test_case, test_method ) );
268}
269
270//____________________________________________________________________________//
271
272// ************************************************************************** //
273// ************** auto_test_unit_registrar ************** //
274// ************************************************************************** //
275
276namespace ut_detail {
277
278struct BOOST_TEST_DECL auto_test_unit_registrar
279{
280 // Constructors
281 auto_test_unit_registrar( test_case* tc, counter_t exp_fail );
282 explicit auto_test_unit_registrar( const_string ts_name );
283 explicit auto_test_unit_registrar( test_unit_generator const& tc_gen );
284 explicit auto_test_unit_registrar( int );
285
286private:
287 static std::list<test_suite*>& curr_ts_store();
288};
289
290//____________________________________________________________________________//
291
292template<typename T>
293struct auto_tc_exp_fail {
294 auto_tc_exp_fail() : m_value( 0 ) {}
295
296 explicit auto_tc_exp_fail( unsigned v )
297 : m_value( v )
298 {
299 instance() = this;
300 }
301
302 static auto_tc_exp_fail*& instance()
303 {
304 static auto_tc_exp_fail inst;
305 static auto_tc_exp_fail* inst_ptr = &inst;
306
307 return inst_ptr;
308 }
309
310 unsigned value() const { return m_value; }
311
312private:
313 // Data members
314 unsigned m_value;
315};
316
317//____________________________________________________________________________//
318
319} // namespace ut_detail
320
321// ************************************************************************** //
322// ************** global_fixture ************** //
323// ************************************************************************** //
324
325class BOOST_TEST_DECL global_fixture : public test_observer {
326public:
327 // Constructor
328 global_fixture();
329};
330
331//____________________________________________________________________________//
332
333namespace ut_detail {
334
335template<typename F>
336struct global_fixture_impl : public global_fixture {
337 // Constructor
338 global_fixture_impl(): m_fixure( 0 ) {}
339
340 // test observer interface
341 virtual void test_start( counter_t ) { m_fixure = new F; }
342 virtual void test_finish() { delete m_fixure; m_fixure = 0; }
343 virtual void test_aborted() { delete m_fixure; m_fixure = 0; }
344
345private:
346 // Data members
347 F* m_fixure;
348};
349
350// ************************************************************************** //
351// ************** test_case_template_invoker ************** //
352// ************************************************************************** //
353
354template<typename TestCaseTemplate,typename TestType>
355class test_case_template_invoker {
356public:
357 void operator()() { TestCaseTemplate::run( (ndnboost::type<TestType>*)0 ); }
358};
359
360// ************************************************************************** //
361// ************** generate_test_case_4_type ************** //
362// ************************************************************************** //
363
364template<typename Generator,typename TestCaseTemplate>
365struct generate_test_case_4_type {
366 explicit generate_test_case_4_type( const_string tc_name, Generator& G )
367 : m_test_case_name( tc_name )
368 , m_holder( G )
369 {}
370
371 template<typename TestType>
372 void operator()( mpl::identity<TestType> )
373 {
374 std::string full_name;
375 assign_op( full_name, m_test_case_name, 0 );
376 full_name += '<';
377 full_name += typeid(TestType).name();
378 if( ndnboost::is_const<TestType>::value )
379 full_name += " const";
380 full_name += '>';
381
382 m_holder.m_test_cases.push_back(
383 new test_case( full_name, test_case_template_invoker<TestCaseTemplate,TestType>() ) );
384 }
385
386private:
387 // Data members
388 const_string m_test_case_name;
389 Generator& m_holder;
390};
391
392// ************************************************************************** //
393// ************** test_case_template ************** //
394// ************************************************************************** //
395
396template<typename TestCaseTemplate,typename TestTypesList>
397class template_test_case_gen : public test_unit_generator {
398public:
399 // Constructor
400 template_test_case_gen( const_string tc_name )
401 {
402 typedef generate_test_case_4_type<template_test_case_gen<TestCaseTemplate,TestTypesList>,
403 TestCaseTemplate
404 > single_test_gen;
405 mpl::for_each<TestTypesList,mpl::make_identity<mpl::_> >( single_test_gen( tc_name, *this ) );
406 }
407
408 virtual test_unit* next() const
409 {
410 if( m_test_cases.empty() )
411 return 0;
412
413 test_unit* res = m_test_cases.front();
414 m_test_cases.pop_front();
415
416 return res;
417 }
418
419 // Data members
420 mutable std::list<test_unit*> m_test_cases;
421};
422
423//____________________________________________________________________________//
424
425} // namespace ut_detail
426
427} // unit_test
428
429} // namespace ndnboost
430
431#include <ndnboost/test/detail/enable_warnings.hpp>
432
433#endif // BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
434