decorator.hpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  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. // See http://www.boost.org/libs/test for the library home page.
  6. //
  7. // File : $RCSfile$
  8. //
  9. // Version : $Revision: 62016 $
  10. //
  11. // Description : defines decorators to be using with auto registered test units
  12. // ***************************************************************************
  13. #ifndef BOOST_TEST_TREE_DECORATOR_HPP_091911GER
  14. #define BOOST_TEST_TREE_DECORATOR_HPP_091911GER
  15. // Boost.Test
  16. #include <boost/test/detail/config.hpp>
  17. #include <boost/test/detail/global_typedef.hpp>
  18. #include <boost/test/tree/fixture.hpp>
  19. #include <boost/test/tools/assertion_result.hpp>
  20. #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
  21. // Boost
  22. #include <boost/shared_ptr.hpp>
  23. #include <boost/function/function0.hpp>
  24. #include <boost/function/function1.hpp>
  25. #include <boost/test/detail/suppress_warnings.hpp>
  26. // STL
  27. #include <vector>
  28. //____________________________________________________________________________//
  29. namespace boost {
  30. namespace unit_test {
  31. class test_unit;
  32. namespace decorator {
  33. // ************************************************************************** //
  34. // ************** decorator::collector_t ************** //
  35. // ************************************************************************** //
  36. class base;
  37. typedef boost::shared_ptr<base> base_ptr;
  38. class BOOST_TEST_DECL collector_t {
  39. public:
  40. collector_t& operator*( base const& d );
  41. void store_in( test_unit& tu );
  42. void reset();
  43. void stack();
  44. std::vector<base_ptr> get_lazy_decorators() const;
  45. // singleton pattern without ctor
  46. BOOST_TEST_SINGLETON_CONS_NO_CTOR( collector_t )
  47. private:
  48. // Class invariant: minimal size is 1.
  49. collector_t() : m_tu_decorators_stack(1) {}
  50. // Data members
  51. std::vector< std::vector<base_ptr> > m_tu_decorators_stack;
  52. };
  53. // ************************************************************************** //
  54. // ************** decorator::base ************** //
  55. // ************************************************************************** //
  56. class BOOST_TEST_DECL base {
  57. public:
  58. // composition interface
  59. virtual collector_t& operator*() const;
  60. // application interface
  61. virtual void apply( test_unit& tu ) = 0;
  62. // deep cloning interface
  63. virtual base_ptr clone() const = 0;
  64. protected:
  65. virtual ~base() {}
  66. };
  67. // ************************************************************************** //
  68. // ************** decorator::stack_decorator ************** //
  69. // ************************************************************************** //
  70. //!@ A decorator that creates a new stack in the collector
  71. //!
  72. //! This decorator may be used in places where the currently accumulated decorators
  73. //! in the collector should be applied to lower levels of the hierarchy rather
  74. //! than the current one. This is for instance for dataset test cases, where the
  75. //! macro does not let the user specify decorators for the underlying generated tests
  76. //! (but rather on the main generator function), applying the stack_decorator at the
  77. //! parent level lets us consume the decorator at the underlying test cases level.
  78. class BOOST_TEST_DECL stack_decorator : public decorator::base {
  79. public:
  80. explicit stack_decorator() {}
  81. virtual collector_t& operator*() const;
  82. private:
  83. // decorator::base interface
  84. virtual void apply( test_unit& tu );
  85. virtual base_ptr clone() const { return base_ptr(new stack_decorator()); }
  86. };
  87. // ************************************************************************** //
  88. // ************** decorator::label ************** //
  89. // ************************************************************************** //
  90. class BOOST_TEST_DECL label : public decorator::base {
  91. public:
  92. explicit label( const_string l ) : m_label( l ) {}
  93. private:
  94. // decorator::base interface
  95. virtual void apply( test_unit& tu );
  96. virtual base_ptr clone() const { return base_ptr(new label( m_label )); }
  97. // Data members
  98. const_string m_label;
  99. };
  100. // ************************************************************************** //
  101. // ************** decorator::expected_failures ************** //
  102. // ************************************************************************** //
  103. class BOOST_TEST_DECL expected_failures : public decorator::base {
  104. public:
  105. explicit expected_failures( counter_t ef ) : m_exp_fail( ef ) {}
  106. private:
  107. // decorator::base interface
  108. virtual void apply( test_unit& tu );
  109. virtual base_ptr clone() const { return base_ptr(new expected_failures( m_exp_fail )); }
  110. // Data members
  111. counter_t m_exp_fail;
  112. };
  113. // ************************************************************************** //
  114. // ************** decorator::timeout ************** //
  115. // ************************************************************************** //
  116. class BOOST_TEST_DECL timeout : public decorator::base {
  117. public:
  118. explicit timeout( unsigned t ) : m_timeout( t ) {}
  119. private:
  120. // decorator::base interface
  121. virtual void apply( test_unit& tu );
  122. virtual base_ptr clone() const { return base_ptr(new timeout( m_timeout )); }
  123. // Data members
  124. unsigned m_timeout;
  125. };
  126. // ************************************************************************** //
  127. // ************** decorator::description ************** //
  128. // ************************************************************************** //
  129. class BOOST_TEST_DECL description : public decorator::base {
  130. public:
  131. explicit description( const_string descr ) : m_description( descr ) {}
  132. private:
  133. // decorator::base interface
  134. virtual void apply( test_unit& tu );
  135. virtual base_ptr clone() const { return base_ptr(new description( m_description )); }
  136. // Data members
  137. const_string m_description;
  138. };
  139. // ************************************************************************** //
  140. // ************** decorator::depends_on ************** //
  141. // ************************************************************************** //
  142. class BOOST_TEST_DECL depends_on : public decorator::base {
  143. public:
  144. explicit depends_on( const_string dependency ) : m_dependency( dependency ) {}
  145. private:
  146. // decorator::base interface
  147. virtual void apply( test_unit& tu );
  148. virtual base_ptr clone() const { return base_ptr(new depends_on( m_dependency )); }
  149. // Data members
  150. const_string m_dependency;
  151. };
  152. // ************************************************************************** //
  153. // ************** decorator::enable_if/enabled/disabled ************** //
  154. // ************************************************************************** //
  155. class BOOST_TEST_DECL enable_if_impl : public decorator::base {
  156. protected:
  157. void apply_impl( test_unit& tu, bool condition );
  158. };
  159. template<bool condition>
  160. class enable_if : public enable_if_impl {
  161. private:
  162. // decorator::base interface
  163. virtual void apply( test_unit& tu ) { this->apply_impl( tu, condition ); }
  164. virtual base_ptr clone() const { return base_ptr(new enable_if<condition>()); }
  165. };
  166. typedef enable_if<true> enabled;
  167. typedef enable_if<false> disabled;
  168. // ************************************************************************** //
  169. // ************** decorator::fixture ************** //
  170. // ************************************************************************** //
  171. class BOOST_TEST_DECL fixture_t : public decorator::base {
  172. public:
  173. // Constructor
  174. explicit fixture_t( test_unit_fixture_ptr impl ) : m_impl( impl ) {}
  175. private:
  176. // decorator::base interface
  177. virtual void apply( test_unit& tu );
  178. virtual base_ptr clone() const { return base_ptr(new fixture_t( m_impl )); }
  179. // Data members
  180. test_unit_fixture_ptr m_impl;
  181. };
  182. //____________________________________________________________________________//
  183. template<typename F>
  184. inline fixture_t
  185. fixture()
  186. {
  187. return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F>() ) );
  188. }
  189. //____________________________________________________________________________//
  190. template<typename F, typename Arg>
  191. inline fixture_t
  192. fixture( Arg const& arg )
  193. {
  194. return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F,Arg>( arg ) ) );
  195. }
  196. //____________________________________________________________________________//
  197. inline fixture_t
  198. fixture( boost::function<void()> const& setup, boost::function<void()> const& teardown = boost::function<void()>() )
  199. {
  200. return fixture_t( test_unit_fixture_ptr( new unit_test::function_based_fixture( setup, teardown ) ) );
  201. }
  202. //____________________________________________________________________________//
  203. // ************************************************************************** //
  204. // ************** decorator::depends_on ************** //
  205. // ************************************************************************** //
  206. class BOOST_TEST_DECL precondition : public decorator::base {
  207. public:
  208. typedef boost::function<test_tools::assertion_result (test_unit_id)> predicate_t;
  209. explicit precondition( predicate_t p ) : m_precondition( p ) {}
  210. private:
  211. // decorator::base interface
  212. virtual void apply( test_unit& tu );
  213. virtual base_ptr clone() const { return base_ptr(new precondition( m_precondition )); }
  214. // Data members
  215. predicate_t m_precondition;
  216. };
  217. } // namespace decorator
  218. using decorator::label;
  219. using decorator::expected_failures;
  220. using decorator::timeout;
  221. using decorator::description;
  222. using decorator::depends_on;
  223. using decorator::enable_if;
  224. using decorator::enabled;
  225. using decorator::disabled;
  226. using decorator::fixture;
  227. using decorator::precondition;
  228. } // namespace unit_test
  229. } // namespace boost
  230. #include <boost/test/detail/enable_warnings.hpp>
  231. #endif // BOOST_TEST_TREE_DECORATOR_HPP_091911GER