fix doc example typo
[boost.git] / boost / test / unit_test_suite_impl.hpp
blobe3573dd9d7c2604c35ee29359d1f2ded826b4885
1 // (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)
6 // See http://www.boost.org/libs/test for the library home page.
7 //
8 // File : $RCSfile$
9 //
10 // Version : $Revision$
12 // Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
13 // ***************************************************************************
15 #ifndef BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
16 #define BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER
18 // Boost.Test
19 #include <boost/test/detail/config.hpp>
20 #include <boost/test/detail/global_typedef.hpp>
21 #include <boost/test/utils/class_properties.hpp>
22 #include <boost/test/utils/callback.hpp>
23 #include <boost/test/detail/fwd_decl.hpp>
24 #include <boost/test/detail/workaround.hpp>
25 #include <boost/test/test_observer.hpp>
27 // Boost
28 #include <boost/shared_ptr.hpp>
29 #include <boost/mpl/for_each.hpp>
30 #include <boost/mpl/identity.hpp>
31 #include <boost/type.hpp>
32 #include <boost/type_traits/is_const.hpp>
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
40 #include <boost/test/detail/suppress_warnings.hpp>
42 //____________________________________________________________________________//
44 namespace boost {
46 namespace unit_test {
48 // ************************************************************************** //
49 // ************** test_unit ************** //
50 // ************************************************************************** //
52 class BOOST_TEST_DECL test_unit {
53 public:
54 enum { type = tut_any };
56 // Constructor
57 test_unit( const_string tu_name, test_unit_type t );
59 // dependencies management
60 void depends_on( test_unit* tu );
61 bool check_dependencies() const;
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
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
77 void increase_exp_fail( unsigned num );
79 protected:
80 ~test_unit();
82 private:
83 // Data members
84 std::list<test_unit_id> m_dependencies;
87 // ************************************************************************** //
88 // ************** test_case_generator ************** //
89 // ************************************************************************** //
91 class BOOST_TEST_DECL test_unit_generator {
92 public:
93 virtual test_unit* next() const = 0;
95 protected:
96 BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
99 // ************************************************************************** //
100 // ************** test_case ************** //
101 // ************************************************************************** //
103 class BOOST_TEST_DECL test_case : public test_unit {
104 public:
105 enum { type = tut_case };
107 // Constructor
108 test_case( const_string tc_name, callback0<> const& test_func );
110 // Access methods
111 callback0<> const& test_func() const { return m_test_func; }
113 private:
114 friend class framework_impl;
115 ~test_case() {}
117 // BOOST_MSVC <= 1200 have problems with callback as property
118 // Data members
119 callback0<> m_test_func;
122 // ************************************************************************** //
123 // ************** test_suite ************** //
124 // ************************************************************************** //
126 class BOOST_TEST_DECL test_suite : public test_unit {
127 public:
128 enum { type = tut_suite };
130 // Constructor
131 explicit test_suite( const_string ts_name );
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 );
138 // access methods
139 test_unit_id get( const_string tu_name ) const;
140 std::size_t size() const { return m_members.size(); }
142 protected:
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() {}
148 // Data members
149 std::vector<test_unit_id> m_members;
152 // ************************************************************************** //
153 // ************** master_test_suite ************** //
154 // ************************************************************************** //
156 class BOOST_TEST_DECL master_test_suite_t : public test_suite {
157 public:
158 master_test_suite_t() : test_suite( "Master Test Suite" )
159 , argc( 0 )
160 , argv( 0 )
163 // Data members
164 int argc;
165 char** argv;
169 // ************************************************************************** //
170 // ************** test_tree_visitor ************** //
171 // ************************************************************************** //
173 class BOOST_TEST_DECL test_tree_visitor {
174 public:
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& ) {}
180 protected:
181 BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
184 // ************************************************************************** //
185 // ************** traverse_test_tree ************** //
186 // ************************************************************************** //
188 BOOST_TEST_DECL void traverse_test_tree( test_case const&, test_tree_visitor& );
189 BOOST_TEST_DECL void traverse_test_tree( test_suite const&, test_tree_visitor& );
190 BOOST_TEST_DECL void traverse_test_tree( test_unit_id , test_tree_visitor& );
192 //____________________________________________________________________________//
194 inline void
195 traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
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 );
203 //____________________________________________________________________________//
205 // ************************************************************************** //
206 // ************** test_case_counter ************** //
207 // ************************************************************************** //
209 class test_case_counter : public test_tree_visitor {
210 public:
211 // Constructor
212 test_case_counter() : p_count( 0 ) {}
214 BOOST_READONLY_PROPERTY( counter_t, (test_case_counter)) p_count;
215 private:
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; }
221 // ************************************************************************** //
222 // ************** test_being_aborted ************** //
223 // ************************************************************************** //
225 struct BOOST_TEST_DECL test_being_aborted {};
227 // ************************************************************************** //
228 // ************** object generators ************** //
229 // ************************************************************************** //
231 namespace ut_detail {
233 BOOST_TEST_DECL std::string normalize_test_case_name( const_string tu_name );
235 template<typename InstanceType,typename UserTestCase>
236 struct user_tc_method_invoker {
237 typedef void (UserTestCase::*TestMethod )();
239 user_tc_method_invoker( shared_ptr<InstanceType> inst, TestMethod test_method )
240 : m_inst( inst ), m_test_method( test_method ) {}
242 void operator()() { ((*m_inst).*m_test_method)(); }
244 shared_ptr<InstanceType> m_inst;
245 TestMethod m_test_method;
248 } // namespace ut_detail
250 //____________________________________________________________________________//
252 inline test_case*
253 make_test_case( callback0<> const& test_func, const_string tc_name )
255 return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
258 //____________________________________________________________________________//
260 template<typename UserTestCase, typename InstanceType>
261 inline test_case*
262 make_test_case( void (UserTestCase::* test_method )(),
263 const_string tc_name,
264 boost::shared_ptr<InstanceType> user_test_case )
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 ) );
270 //____________________________________________________________________________//
272 // ************************************************************************** //
273 // ************** auto_test_unit_registrar ************** //
274 // ************************************************************************** //
276 namespace ut_detail {
278 struct BOOST_TEST_DECL auto_test_unit_registrar
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 );
286 private:
287 static std::list<test_suite*>& curr_ts_store();
290 //____________________________________________________________________________//
292 template<typename T>
293 struct auto_tc_exp_fail {
294 auto_tc_exp_fail() : m_value( 0 ) {}
296 explicit auto_tc_exp_fail( unsigned v )
297 : m_value( v )
299 instance() = this;
302 static auto_tc_exp_fail*& instance()
304 static auto_tc_exp_fail inst;
305 static auto_tc_exp_fail* inst_ptr = &inst;
307 return inst_ptr;
310 unsigned value() const { return m_value; }
312 private:
313 // Data members
314 unsigned m_value;
317 //____________________________________________________________________________//
319 } // namespace ut_detail
321 // ************************************************************************** //
322 // ************** global_fixture ************** //
323 // ************************************************************************** //
325 class BOOST_TEST_DECL global_fixture : public test_observer {
326 public:
327 // Constructor
328 global_fixture();
331 //____________________________________________________________________________//
333 namespace ut_detail {
335 template<typename F>
336 struct global_fixture_impl : public global_fixture {
337 // Constructor
338 global_fixture_impl(): m_fixure( 0 ) {}
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; }
345 private:
346 // Data members
347 F* m_fixure;
350 // ************************************************************************** //
351 // ************** test_case_template_invoker ************** //
352 // ************************************************************************** //
354 template<typename TestCaseTemplate,typename TestType>
355 class test_case_template_invoker {
356 public:
357 void operator()() { TestCaseTemplate::run( (boost::type<TestType>*)0 ); }
360 // ************************************************************************** //
361 // ************** generate_test_case_4_type ************** //
362 // ************************************************************************** //
364 template<typename Generator,typename TestCaseTemplate>
365 struct 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 )
371 template<typename TestType>
372 void operator()( mpl::identity<TestType> )
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( boost::is_const<TestType>::value )
379 full_name += " const";
380 full_name += '>';
382 m_holder.m_test_cases.push_back(
383 new test_case( full_name, test_case_template_invoker<TestCaseTemplate,TestType>() ) );
386 private:
387 // Data members
388 const_string m_test_case_name;
389 Generator& m_holder;
392 // ************************************************************************** //
393 // ************** test_case_template ************** //
394 // ************************************************************************** //
396 template<typename TestCaseTemplate,typename TestTypesList>
397 class template_test_case_gen : public test_unit_generator {
398 public:
399 // Constructor
400 template_test_case_gen( const_string tc_name )
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 ) );
408 virtual test_unit* next() const
410 if( m_test_cases.empty() )
411 return 0;
413 test_unit* res = m_test_cases.front();
414 m_test_cases.pop_front();
416 return res;
419 // Data members
420 mutable std::list<test_unit*> m_test_cases;
423 //____________________________________________________________________________//
425 } // namespace ut_detail
427 } // unit_test
429 } // namespace boost
431 #include <boost/test/detail/enable_warnings.hpp>
433 #endif // BOOST_TEST_UNIT_TEST_SUITE_IMPL_HPP_071894GER