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        : $RCSfile$
9 //
10 //  Version     : $Revision: 62016 $
11 //
12 //  Description : defines decorators to be using with auto registered test units
13 // ***************************************************************************
14 
15 #ifndef BOOST_TEST_TREE_DECORATOR_HPP_091911GER
16 #define BOOST_TEST_TREE_DECORATOR_HPP_091911GER
17 
18 // Boost.Test
19 #include <boost/test/detail/config.hpp>
20 #include <boost/test/detail/global_typedef.hpp>
21 
22 #include <boost/test/tree/fixture.hpp>
23 
24 #include <boost/test/tools/assertion_result.hpp>
25 
26 #include <boost/test/utils/basic_cstring/basic_cstring.hpp>
27 #include <boost/test/utils/trivial_singleton.hpp>
28 
29 // Boost
30 #include <boost/shared_ptr.hpp>
31 #include <boost/function/function0.hpp>
32 #include <boost/function/function1.hpp>
33 
34 #include <boost/test/detail/suppress_warnings.hpp>
35 
36 // STL
37 #include <vector>
38 
39 //____________________________________________________________________________//
40 
41 namespace boost {
42 namespace unit_test {
43 
44 class test_unit;
45 
46 namespace decorator {
47 
48 // ************************************************************************** //
49 // **************             decorator::collector             ************** //
50 // ************************************************************************** //
51 
52 class base;
53 typedef boost::shared_ptr<base> base_ptr;
54 
55 class BOOST_TEST_DECL collector : public singleton<collector> {
56 public:
57     collector&              operator*( base const& d );
58 
59     void                    store_in( test_unit& tu );
60 
61     void                    reset();
62 
63 private:
64     BOOST_TEST_SINGLETON_CONS( collector )
65 
66     // Data members
67     std::vector<base_ptr>   m_tu_decorators;
68 };
69 
70 // ************************************************************************** //
71 // **************               decorator::base                ************** //
72 // ************************************************************************** //
73 
74 class BOOST_TEST_DECL base {
75 public:
76     // composition interface
77     collector&              operator*() const;
78 
79     // application interface
80     virtual void            apply( test_unit& tu ) = 0;
81 
82     // deep cloning interface
83     virtual base_ptr        clone() const = 0;
84 
85 protected:
86     virtual ~base() {}
87 };
88 
89 // ************************************************************************** //
90 // **************               decorator::label               ************** //
91 // ************************************************************************** //
92 
93 class BOOST_TEST_DECL label : public decorator::base {
94 public:
95     explicit                label( const_string l ) : m_label( l ) {}
96 
97 private:
98     // decorator::base interface
99     virtual void            apply( test_unit& tu );
100     virtual base_ptr        clone() const { return base_ptr(new label( m_label )); }
101 
102     // Data members
103     const_string            m_label;
104 };
105 
106 // ************************************************************************** //
107 // **************         decorator::expected_failures         ************** //
108 // ************************************************************************** //
109 
110 class BOOST_TEST_DECL expected_failures : public decorator::base {
111 public:
112     explicit                expected_failures( counter_t ef ) : m_exp_fail( ef ) {}
113 
114 private:
115     // decorator::base interface
116     virtual void            apply( test_unit& tu );
117     virtual base_ptr        clone() const { return base_ptr(new expected_failures( m_exp_fail )); }
118 
119     // Data members
120     counter_t               m_exp_fail;
121 };
122 
123 // ************************************************************************** //
124 // **************              decorator::timeout              ************** //
125 // ************************************************************************** //
126 
127 class BOOST_TEST_DECL timeout : public decorator::base {
128 public:
129     explicit                timeout( unsigned t ) : m_timeout( t ) {}
130 
131 private:
132     // decorator::base interface
133     virtual void            apply( test_unit& tu );
134     virtual base_ptr        clone() const { return base_ptr(new timeout( m_timeout )); }
135 
136     // Data members
137     unsigned                m_timeout;
138 };
139 
140 // ************************************************************************** //
141 // **************            decorator::description            ************** //
142 // ************************************************************************** //
143 
144 class BOOST_TEST_DECL description : public decorator::base {
145 public:
146     explicit                description( const_string descr ) : m_description( descr ) {}
147 
148 private:
149     // decorator::base interface
150     virtual void            apply( test_unit& tu );
151     virtual base_ptr        clone() const { return base_ptr(new description( m_description )); }
152 
153     // Data members
154     const_string            m_description;
155 };
156 
157 // ************************************************************************** //
158 // **************            decorator::depends_on             ************** //
159 // ************************************************************************** //
160 
161 class BOOST_TEST_DECL depends_on : public decorator::base {
162 public:
163     explicit                depends_on( const_string dependency ) : m_dependency( dependency ) {}
164 
165 private:
166     // decorator::base interface
167     virtual void            apply( test_unit& tu );
168     virtual base_ptr        clone() const { return base_ptr(new depends_on( m_dependency )); }
169 
170     // Data members
171     const_string            m_dependency;
172 };
173 
174 // ************************************************************************** //
175 // **************    decorator::enable_if/enabled/disabled     ************** //
176 // ************************************************************************** //
177 
178 class BOOST_TEST_DECL enable_if_impl : public decorator::base {
179 protected:
180     void                    apply_impl( test_unit& tu, bool condition );
181 };
182 
183 template<bool condition>
184 class enable_if : public enable_if_impl {
185 private:
186     // decorator::base interface
187     virtual void            apply( test_unit& tu )   { this->apply_impl( tu, condition ); }
188     virtual base_ptr        clone() const            { return base_ptr(new enable_if<condition>()); }
189 };
190 
191 typedef enable_if<true> enabled;
192 typedef enable_if<false> disabled;
193 
194 // ************************************************************************** //
195 // **************              decorator::fixture              ************** //
196 // ************************************************************************** //
197 
198 class BOOST_TEST_DECL fixture_t : public decorator::base {
199 public:
200     // Constructor
201     explicit                fixture_t( test_unit_fixture_ptr impl ) : m_impl( impl ) {}
202 
203 private:
204     // decorator::base interface
205     virtual void            apply( test_unit& tu );
206     virtual base_ptr        clone() const { return base_ptr(new fixture_t( m_impl )); }
207 
208     // Data members
209     test_unit_fixture_ptr m_impl;
210 };
211 
212 //____________________________________________________________________________//
213 
214 template<typename F>
215 inline fixture_t
216 fixture()
217 {
218     return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F>() ) );
219 }
220 
221 //____________________________________________________________________________//
222 
223 template<typename F, typename Arg>
224 inline fixture_t
225 fixture( Arg const& arg )
226 {
227     return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F,Arg>( arg ) ) );
228 }
229 
230 //____________________________________________________________________________//
231 
232 inline fixture_t
233 fixture( boost::function<void()> const& setup, boost::function<void()> const& teardown = boost::function<void()>() )
234 {
235     return fixture_t( test_unit_fixture_ptr( new unit_test::function_based_fixture( setup, teardown ) ) );
236 }
237 
238 //____________________________________________________________________________//
239 
240 // ************************************************************************** //
241 // **************            decorator::depends_on             ************** //
242 // ************************************************************************** //
243 
244 class BOOST_TEST_DECL precondition : public decorator::base {
245 public:
246     typedef boost::function<test_tools::assertion_result (test_unit_id)>   predicate_t;
247 
248     explicit                precondition( predicate_t p ) : m_precondition( p ) {}
249 
250 private:
251     // decorator::base interface
252     virtual void            apply( test_unit& tu );
253     virtual base_ptr        clone() const { return base_ptr(new precondition( m_precondition )); }
254 
255     // Data members
256     predicate_t             m_precondition;
257 };
258 
259 } // namespace decorator
260 
261 using decorator::label;
262 using decorator::expected_failures;
263 using decorator::timeout;
264 using decorator::description;
265 using decorator::depends_on;
266 using decorator::enable_if;
267 using decorator::enabled;
268 using decorator::disabled;
269 using decorator::fixture;
270 using decorator::precondition;
271 
272 } // namespace unit_test
273 } // namespace boost
274 
275 #include <boost/test/detail/enable_warnings.hpp>
276 
277 #endif // BOOST_TEST_TREE_DECORATOR_HPP_091911GER
278