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#include <boost/test/utils/basic_cstring/basic_cstring.hpp>
26
27// Boost
28#include <boost/shared_ptr.hpp>
29#include <boost/function/function0.hpp>
30#include <boost/function/function1.hpp>
31
32#include <boost/test/detail/suppress_warnings.hpp>
33
34// STL
35#include <vector>
36
37//____________________________________________________________________________//
38
39namespace boost {
40namespace unit_test {
41
42class test_unit;
43
44namespace decorator {
45
46// ************************************************************************** //
47// ************** decorator::collector_t ************** //
48// ************************************************************************** //
49
50class base;
51typedef boost::shared_ptr<base> base_ptr;
52
53class BOOST_TEST_DECL collector_t {
54
55public:
56 collector_t& operator*( base const& d );
57
58 void store_in( test_unit& tu );
59
60 void reset();
61
62 void stack();
63
64 std::vector<base_ptr> get_lazy_decorators() const;
65
66 // singleton pattern without ctor
67 BOOST_TEST_SINGLETON_CONS_NO_CTOR( collector_t )
68
69private:
70 // Class invariant: minimal size is 1.
71 collector_t() : m_tu_decorators_stack(1) {}
72
73 // Data members
74 std::vector< std::vector<base_ptr> > m_tu_decorators_stack;
75};
76
77
78// ************************************************************************** //
79// ************** decorator::base ************** //
80// ************************************************************************** //
81
82class BOOST_TEST_DECL base {
83public:
84 // composition interface
85 virtual collector_t& operator*() const;
86
87 // application interface
88 virtual void apply( test_unit& tu ) = 0;
89
90 // deep cloning interface
91 virtual base_ptr clone() const = 0;
92
93protected:
94 virtual ~base() {}
95};
96
97// ************************************************************************** //
98// ************** decorator::stack_decorator ************** //
99// ************************************************************************** //
100
101//!@ A decorator that creates a new stack in the collector
102//!
103//! This decorator may be used in places where the currently accumulated decorators
104//! in the collector should be applied to lower levels of the hierarchy rather
105//! than the current one. This is for instance for dataset test cases, where the
106//! macro does not let the user specify decorators for the underlying generated tests
107//! (but rather on the main generator function), applying the stack_decorator at the
108//! parent level lets us consume the decorator at the underlying test cases level.
109class BOOST_TEST_DECL stack_decorator : public decorator::base {
110public:
111 explicit stack_decorator() {}
112
113 collector_t& operator*() const BOOST_OVERRIDE;
114
115private:
116 // decorator::base interface
117 void apply( test_unit& tu ) BOOST_OVERRIDE;
118 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new stack_decorator()); }
119};
120
121// ************************************************************************** //
122// ************** decorator::label ************** //
123// ************************************************************************** //
124
125class BOOST_TEST_DECL label : public decorator::base {
126public:
127 explicit label( const_string l ) : m_label( l ) {}
128
129private:
130 // decorator::base interface
131 void apply( test_unit& tu ) BOOST_OVERRIDE;
132 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new label( m_label )); }
133
134 // Data members
135 const_string m_label;
136};
137
138// ************************************************************************** //
139// ************** decorator::expected_failures ************** //
140// ************************************************************************** //
141
142class BOOST_TEST_DECL expected_failures : public decorator::base {
143public:
144 explicit expected_failures( counter_t ef ) : m_exp_fail( ef ) {}
145
146private:
147 // decorator::base interface
148 void apply( test_unit& tu ) BOOST_OVERRIDE;
149 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new expected_failures( m_exp_fail )); }
150
151 // Data members
152 counter_t m_exp_fail;
153};
154
155// ************************************************************************** //
156// ************** decorator::timeout ************** //
157// ************************************************************************** //
158
159class BOOST_TEST_DECL timeout : public decorator::base {
160public:
161 explicit timeout( unsigned t ) : m_timeout( t ) {}
162
163private:
164 // decorator::base interface
165 void apply( test_unit& tu ) BOOST_OVERRIDE;
166 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new timeout( m_timeout )); }
167
168 // Data members
169 unsigned m_timeout;
170};
171
172// ************************************************************************** //
173// ************** decorator::description ************** //
174// ************************************************************************** //
175
176class BOOST_TEST_DECL description : public decorator::base {
177public:
178 explicit description( const_string descr ) : m_description( descr ) {}
179
180private:
181 // decorator::base interface
182 void apply( test_unit& tu ) BOOST_OVERRIDE;
183 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new description( m_description )); }
184
185 // Data members
186 const_string m_description;
187};
188
189// ************************************************************************** //
190// ************** decorator::depends_on ************** //
191// ************************************************************************** //
192
193class BOOST_TEST_DECL depends_on : public decorator::base {
194public:
195 explicit depends_on( const_string dependency ) : m_dependency( dependency ) {}
196
197private:
198 // decorator::base interface
199 void apply( test_unit& tu ) BOOST_OVERRIDE;
200 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new depends_on( m_dependency )); }
201
202 // Data members
203 const_string m_dependency;
204};
205
206// ************************************************************************** //
207// ************** decorator::enable_if/enabled/disabled ************** //
208// ************************************************************************** //
209
210class BOOST_TEST_DECL enable_if_impl : public decorator::base {
211protected:
212 void apply_impl( test_unit& tu, bool condition );
213};
214
215template<bool condition>
216class enable_if : public enable_if_impl {
217private:
218 // decorator::base interface
219 void apply( test_unit& tu ) BOOST_OVERRIDE { this->apply_impl( tu, condition ); }
220 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new enable_if<condition>()); }
221};
222
223typedef enable_if<true> enabled;
224typedef enable_if<false> disabled;
225
226// ************************************************************************** //
227// ************** decorator::fixture ************** //
228// ************************************************************************** //
229
230class BOOST_TEST_DECL fixture_t : public decorator::base {
231public:
232 // Constructor
233 explicit fixture_t( test_unit_fixture_ptr impl ) : m_impl( impl ) {}
234
235private:
236 // decorator::base interface
237 void apply( test_unit& tu ) BOOST_OVERRIDE;
238 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new fixture_t( m_impl )); }
239
240 // Data members
241 test_unit_fixture_ptr m_impl;
242};
243
244//____________________________________________________________________________//
245
246template<typename F>
247inline fixture_t
248fixture()
249{
250 return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F>() ) );
251}
252
253//____________________________________________________________________________//
254
255template<typename F, typename Arg>
256inline fixture_t
257fixture( Arg const& arg )
258{
259 return fixture_t( test_unit_fixture_ptr( new unit_test::class_based_fixture<F,Arg>( arg ) ) );
260}
261
262//____________________________________________________________________________//
263
264inline fixture_t
265fixture( boost::function<void()> const& setup, boost::function<void()> const& teardown = boost::function<void()>() )
266{
267 return fixture_t( test_unit_fixture_ptr( new unit_test::function_based_fixture( setup, teardown ) ) );
268}
269
270//____________________________________________________________________________//
271
272// ************************************************************************** //
273// ************** decorator::depends_on ************** //
274// ************************************************************************** //
275
276class BOOST_TEST_DECL precondition : public decorator::base {
277public:
278 typedef boost::function<test_tools::assertion_result (test_unit_id)> predicate_t;
279
280 explicit precondition( predicate_t p ) : m_precondition( p ) {}
281
282private:
283 // decorator::base interface
284 void apply( test_unit& tu ) BOOST_OVERRIDE;
285 base_ptr clone() const BOOST_OVERRIDE { return base_ptr(new precondition( m_precondition )); }
286
287 // Data members
288 predicate_t m_precondition;
289};
290
291} // namespace decorator
292
293using decorator::label;
294using decorator::expected_failures;
295using decorator::timeout;
296using decorator::description;
297using decorator::depends_on;
298using decorator::enable_if;
299using decorator::enabled;
300using decorator::disabled;
301using decorator::fixture;
302using decorator::precondition;
303
304} // namespace unit_test
305} // namespace boost
306
307#include <boost/test/detail/enable_warnings.hpp>
308
309#endif // BOOST_TEST_TREE_DECORATOR_HPP_091911GER
310

source code of include/boost/test/tree/decorator.hpp