unit_test_suite_impl.hpp 15 KB

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