1 //  (C) Copyright Gennadiy Rozental 2005.
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: unit_test_suite.hpp,v $
9 //
10 //  Version     : $Revision: 1.1.1.1 $
11 //
12 //  Description : defines test_unit, test_case, test_case_results, test_suite and test_tree_visitor
13 // ***************************************************************************
14 
15 #ifndef BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
16 #define BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
17 
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 
26 // Boost
27 #include <boost/shared_ptr.hpp>
28 
29 // STL
30 #include <string>   // for std::string
31 #include <list>     // for std::list
32 #include <vector>   // for std::list
33 
34 #include <boost/test/detail/suppress_warnings.hpp>
35 
36 //____________________________________________________________________________//
37 
38 #define BOOST_TEST_CASE( function ) \
39 boost::unit_test::make_test_case( boost::unit_test::callback0<>(function), BOOST_TEST_STRINGIZE( function ) )
40 #define BOOST_CLASS_TEST_CASE( function, tc_instance ) \
41 boost::unit_test::make_test_case((function), BOOST_TEST_STRINGIZE( function ), tc_instance )
42 #define BOOST_TEST_SUITE( testsuite_name ) \
43 ( new boost::unit_test::test_suite( testsuite_name ) )
44 
45 namespace boost {
46 
47 namespace unit_test {
48 
49 // ************************************************************************** //
50 // **************                   test_unit                  ************** //
51 // ************************************************************************** //
52 
53 class test_unit {
54 public:
55     enum { type = tut_any };
56 
57     // Constructor
58     test_unit( const_string tu_name, test_unit_type t );
59 
60     // dependencies management
61     void    depends_on( test_unit* tu );
62     bool    check_dependencies() const;
63 
64     // Public r/o properties
65     typedef BOOST_READONLY_PROPERTY(test_unit_id,(framework_impl)) 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 
70     // Public r/w properties
71     readwrite_property<std::string>     p_name;                 // name for this test unit
72     readwrite_property<unsigned>        p_timeout;              // timeout for the test unit execution
73     readwrite_property<counter_t>       p_expected_failures;    // number of expected failured in this test unit
74 
75 private:
76     // Data members
77     std::list<test_unit_id>             m_dependencies;
78 };
79 
80 // ************************************************************************** //
81 // **************              test_case_generator             ************** //
82 // ************************************************************************** //
83 
84 class test_unit_generator {
85 public:
86     virtual test_unit*  next() const = 0;
87 
88 protected:
~test_unit_generator()89     BOOST_TEST_PROTECTED_VIRTUAL ~test_unit_generator() {}
90 };
91 
92 // ************************************************************************** //
93 // **************                   test_case                  ************** //
94 // ************************************************************************** //
95 
96 class test_case : public test_unit {
97 public:
98     enum { type = tut_case };
99 
100     // Constructor
101     test_case( const_string tc_name, callback0<> const& test_func );
102 
103     // Access methods
test_func() const104     callback0<> const&  test_func() const { return m_test_func; }
105 
106 private:
107     friend class framework_impl;
~test_case()108     ~test_case() {}
109 
110     // BOOST_MSVC <= 1200 have problems with callback as property
111     // Data members
112     callback0<> m_test_func;
113 };
114 
115 // ************************************************************************** //
116 // **************                  test_suite                  ************** //
117 // ************************************************************************** //
118 
119 class test_suite : public test_unit {
120 public:
121     enum { type = tut_suite };
122 
123     // Constructor
124     explicit    test_suite( const_string ts_name = "Master" );
125 
126     // test case list management
127     void        add( test_unit* tu, counter_t expected_failures = 0, unsigned timeout = 0 );
128     void        add( test_unit_generator const& gen, unsigned timeout = 0 );
129 
130 protected:
131     friend void traverse_test_tree( test_suite const&, test_tree_visitor& );
132     friend class framework_impl;
~test_suite()133     virtual     ~test_suite() {}
134 
135 private:
136     // Data members
137     std::vector<test_unit_id> m_members;
138 };
139 
140 // ************************************************************************** //
141 // **************               test_tree_visitor              ************** //
142 // ************************************************************************** //
143 
144 class test_tree_visitor {
145 public:
146     // test tree visitor interface
visit(test_case const &)147     virtual void    visit( test_case const& )               {}
test_suite_start(test_suite const &)148     virtual bool    test_suite_start( test_suite const& )   { return true; }
test_suite_finish(test_suite const &)149     virtual void    test_suite_finish( test_suite const& )  {}
150 
151 protected:
~test_tree_visitor()152     BOOST_TEST_PROTECTED_VIRTUAL ~test_tree_visitor() {}
153 };
154 
155 // ************************************************************************** //
156 // **************               traverse_test_tree             ************** //
157 // ************************************************************************** //
158 
159 void    traverse_test_tree( test_case const&, test_tree_visitor& );
160 void    traverse_test_tree( test_suite const&, test_tree_visitor& );
161 void    traverse_test_tree( test_unit_id id, test_tree_visitor& );
162 
163 //____________________________________________________________________________//
164 
165 inline void
traverse_test_tree(test_unit const & tu,test_tree_visitor & V)166 traverse_test_tree( test_unit const& tu, test_tree_visitor& V )
167 {
168     if( tu.p_type == tut_case )
169         traverse_test_tree( static_cast<test_case const&>( tu ), V );
170     else
171         traverse_test_tree( static_cast<test_suite const&>( tu ), V );
172 }
173 
174 //____________________________________________________________________________//
175 
176 // ************************************************************************** //
177 // **************                test_case_counter             ************** //
178 // ************************************************************************** //
179 
180 struct test_case_counter : test_tree_visitor {
test_case_counterboost::unit_test::test_case_counter181     test_case_counter() : m_count( 0 ) {}
182 
visitboost::unit_test::test_case_counter183     void        visit( test_case const& ) { m_count++; }
184 
185     counter_t   m_count;
186 };
187 
188 // ************************************************************************** //
189 // **************                  test_aborted                ************** //
190 // ************************************************************************** //
191 
192 struct test_aborted {};
193 
194 // ************************************************************************** //
195 // **************               object generators              ************** //
196 // ************************************************************************** //
197 
198 namespace ut_detail {
199 
200 std::string normalize_test_case_name( const_string tu_name );
201 
202 template<typename UserTestCase>
203 struct user_tc_method_invoker {
204     typedef void (UserTestCase::*test_method )();
205 
user_tc_method_invokerboost::unit_test::ut_detail::user_tc_method_invoker206     user_tc_method_invoker( shared_ptr<UserTestCase> inst, test_method tm )
207     : m_inst( inst ), m_test_method( tm ) {}
208 
operator ()boost::unit_test::ut_detail::user_tc_method_invoker209     void operator()() { ((*m_inst).*m_test_method)(); }
210 
211     shared_ptr<UserTestCase> m_inst;
212     test_method              m_test_method;
213 };
214 
215 } // namespace ut_detail
216 
217 //____________________________________________________________________________//
218 
219 inline test_case*
make_test_case(callback0<> const & test_func,const_string tc_name)220 make_test_case( callback0<> const& test_func, const_string tc_name )
221 {
222     return new test_case( ut_detail::normalize_test_case_name( tc_name ), test_func );
223 }
224 
225 //____________________________________________________________________________//
226 
227 template<typename UserTestCase>
228 inline test_case*
make_test_case(void (UserTestCase::* test_method)(),const_string tc_name,boost::shared_ptr<UserTestCase> const & user_test_case)229 make_test_case( void (UserTestCase::*test_method )(),
230                   const_string tc_name,
231                   boost::shared_ptr<UserTestCase> const& user_test_case )
232 {
233     return new test_case( ut_detail::normalize_test_case_name( tc_name ),
234                           ut_detail::user_tc_method_invoker<UserTestCase>( user_test_case, test_method ) );
235 }
236 
237 //____________________________________________________________________________//
238 
239 } // unit_test
240 
241 } // namespace boost
242 
243 //____________________________________________________________________________//
244 
245 #include <boost/test/detail/enable_warnings.hpp>
246 
247 // ***************************************************************************
248 //  Revision History :
249 //
250 //  $Log: unit_test_suite.hpp,v $
251 //  Revision 1.1.1.1  2006/03/20 20:15:27  ewalkup
252 //  boost libraries
253 //
254 //  Revision 1.32  2005/05/02 06:00:10  rogeeff
255 //  restore a parameterized user case method based testing
256 //
257 //  Revision 1.31  2005/04/18 04:55:30  rogeeff
258 //  test unit name made read/write
259 //
260 //  Revision 1.30  2005/03/22 06:57:29  rogeeff
261 //  allow to inherit test_suite
262 //
263 //  Revision 1.29  2005/02/21 10:25:54  rogeeff
264 //  use std::vector so we could employ random_shuffle
265 //
266 //  Revision 1.28  2005/02/20 08:27:06  rogeeff
267 //  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
268 //
269 //  Revision 1.27  2005/02/01 06:40:06  rogeeff
270 //  copyright update
271 //  old log entries removed
272 //  minor stylistic changes
273 //  deprecated tools removed
274 //
275 //  Revision 1.26  2005/01/30 03:22:07  rogeeff
276 //  interface changed to use const_string
277 //  use BOOST_TEST_STRINGIZE
278 //
279 //  Revision 1.25  2005/01/22 19:22:12  rogeeff
280 //  implementation moved into headers section to eliminate dependency of included/minimal component on src directory
281 //
282 // ***************************************************************************
283 
284 #endif // BOOST_TEST_UNIT_TEST_SUITE_HPP_071894GER
285 
286