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 |
9 | //!@brief Defines Unit Test Framework mono-state interfaces. |
10 | //! The framework interfaces are based on Monostate design pattern. |
11 | // *************************************************************************** |
12 | |
13 | #ifndef BOOST_TEST_FRAMEWORK_HPP_020805GER |
14 | #define BOOST_TEST_FRAMEWORK_HPP_020805GER |
15 | |
16 | // Boost.Test |
17 | #include <boost/test/detail/global_typedef.hpp> |
18 | #include <boost/test/detail/fwd_decl.hpp> |
19 | #include <boost/test/detail/throw_exception.hpp> |
20 | |
21 | #include <boost/test/utils/trivial_singleton.hpp> |
22 | |
23 | #include <boost/test/detail/suppress_warnings.hpp> |
24 | |
25 | // STL |
26 | #include <stdexcept> |
27 | |
28 | //____________________________________________________________________________// |
29 | |
30 | namespace boost { |
31 | |
32 | /// Main namespace for the Unit Test Framework interfaces and implementation |
33 | namespace unit_test { |
34 | |
35 | // ************************************************************************** // |
36 | // ************** init_unit_test_func ************** // |
37 | // ************************************************************************** // |
38 | |
39 | /// Test module initialization routine signature |
40 | |
41 | /// Different depending on whether BOOST_TEST_ALTERNATIVE_INIT_API is defined or not |
42 | #ifdef BOOST_TEST_ALTERNATIVE_INIT_API |
43 | typedef bool (*init_unit_test_func)(); |
44 | #else |
45 | typedef test_suite* (*init_unit_test_func)( int, char* [] ); |
46 | #endif |
47 | |
48 | // ************************************************************************** // |
49 | // ************** framework ************** // |
50 | // ************************************************************************** // |
51 | |
52 | /// Namespace of the Unit Test Framework mono-state |
53 | namespace framework { |
54 | |
55 | /// @name Unit Test Framework initialization and shutdown |
56 | /// @{ |
57 | |
58 | /// @brief This function performs initialization of the framework mono-state. |
59 | /// |
60 | /// It needs to be called every time before the test is started. |
61 | /// @param[in] init_func test module initialization routine |
62 | /// @param[in] argc command line arguments collection |
63 | /// @param[in] argv command line arguments collection |
64 | BOOST_TEST_DECL void init( init_unit_test_func init_func, int argc, char* argv[] ); |
65 | |
66 | /// This function applies all the decorators and figures out default run status. This argument facilitates an |
67 | /// ability of the test cases to prepare some other test units (primarily used internally for self testing). |
68 | /// @param[in] tu Optional id of the test unit representing root of test tree. If absent, master test suite is used |
69 | BOOST_TEST_DECL void finalize_setup_phase( test_unit_id tu = INV_TEST_UNIT_ID); |
70 | |
71 | /// This function returns true when testing is in progress (setup is finished). |
72 | BOOST_TEST_DECL bool test_in_progress(); |
73 | |
74 | /// This function shuts down the framework and clears up its mono-state. |
75 | /// |
76 | /// It needs to be at the very end of test module execution |
77 | BOOST_TEST_DECL void shutdown(); |
78 | /// @} |
79 | |
80 | /// @name Test unit registration |
81 | /// @{ |
82 | |
83 | /// Provides both read and write access to current "leaf" auto test suite during the test unit registration phase. |
84 | /// |
85 | /// During auto-registration phase the framework maintain a FIFO queue of test units being registered. New test units become children |
86 | /// of the current "leaf" test suite and if this is test suite it is pushed back into queue and becomes a new leaf. |
87 | /// When test suite registration is completed, a test suite is popped from the back of the queue. Only automatically registered test suites |
88 | /// should be added to this queue. Master test suite is always a zero element in this queue, so if no other test suites are registered |
89 | /// all test cases are added to master test suite. |
90 | |
91 | /// This function facilitates all three possible actions: |
92 | /// - if no argument are provided it returns the current queue leaf test suite |
93 | /// - if test suite is provided and no second argument are set, test suite is added to the queue |
94 | /// - if no test suite are provided and last argument is false, the semantic of this function is similar to queue pop: last element is popped from the queue |
95 | /// @param[in] ts test suite to push back to the queue |
96 | /// @param[in] push_or_pop should we push ts to the queue or pop leaf test suite instead |
97 | /// @returns a reference to the currently active/"leaf" test suite |
98 | BOOST_TEST_DECL test_suite& current_auto_test_suite( test_suite* ts = 0, bool push_or_pop = true ); |
99 | |
100 | /// This function add new test case into the global collection of test units the framework aware of. |
101 | |
102 | /// This function also assignes unique test unit id for every test case. Later on one can use this id to locate |
103 | /// the test case if necessary. This is the way for the framework to maintain weak references between test units. |
104 | /// @param[in] tc test case to register |
105 | BOOST_TEST_DECL void register_test_unit( test_case* tc ); |
106 | |
107 | /// This function add new test suite into the global collection of test units the framework aware of. |
108 | |
109 | /// This function also assignes unique test unit id for every test suite. Later on one can use this id to locate |
110 | /// the test case if necessary. This is the way for the framework to maintain weak references between test units. |
111 | /// @param[in] ts test suite to register |
112 | BOOST_TEST_DECL void register_test_unit( test_suite* ts ); |
113 | |
114 | /// This function removes the test unit from the collection of known test units and destroys the test unit object. |
115 | |
116 | /// This function also assigns unique test unit id for every test case. Later on one can use this id to located |
117 | /// the test case if necessary. This is the way for the framework to maintain weak references between test units. |
118 | /// @param[in] tu test unit to deregister |
119 | BOOST_TEST_DECL void deregister_test_unit( test_unit* tu ); |
120 | |
121 | // This function clears up the framework mono-state. |
122 | |
123 | /// After this call the framework can be reinitialized to perform a second test run during the same program lifetime. |
124 | BOOST_TEST_DECL void clear(); |
125 | /// @} |
126 | |
127 | /// @name Test observer registration |
128 | /// @{ |
129 | /// Adds new test execution observer object into the framework's list of test observers. |
130 | |
131 | /// Observer lifetime should exceed the the testing execution timeframe |
132 | /// @param[in] to test observer object to add |
133 | BOOST_TEST_DECL void register_observer( test_observer& to ); |
134 | |
135 | /// Excldes the observer object form the framework's list of test observers |
136 | /// @param[in] to test observer object to exclude |
137 | BOOST_TEST_DECL void deregister_observer( test_observer& to ); |
138 | |
139 | /// @} |
140 | |
141 | /// @name Assertion/uncaught exception context support |
142 | /// @{ |
143 | /// Context accessor |
144 | struct BOOST_TEST_DECL context_generator { |
145 | context_generator() : m_curr_frame( 0 ) {} |
146 | |
147 | /// Is there any context? |
148 | bool is_empty() const; |
149 | |
150 | /// Give me next frame; empty - last frame |
151 | const_string next() const; |
152 | |
153 | private: |
154 | // Data members |
155 | mutable unsigned m_curr_frame; |
156 | }; |
157 | |
158 | /// Records context frame message. |
159 | |
160 | /// Some context frames are sticky - they can only explicitly cleared by specifying context id. Other (non sticky) context frames cleared after every assertion. |
161 | /// @param[in] context_descr context frame message |
162 | /// @param[in] sticky is this sticky frame or not |
163 | /// @returns id of the newly created frame |
164 | BOOST_TEST_DECL int add_context( lazy_ostream const& context_descr, bool sticky ); |
165 | /// Erases context frame (when test exits context scope) |
166 | |
167 | /// If context_id is passed clears that specific context frame identified by this id, otherwise clears all non sticky contexts. |
168 | BOOST_TEST_DECL void clear_context( int context_id = -1 ); |
169 | /// Produces an instance of small "delegate" object, which facilitates access to collected context. |
170 | BOOST_TEST_DECL context_generator get_context(); |
171 | /// @} |
172 | |
173 | /// @name Access to registered test units. |
174 | /// @{ |
175 | /// This function provides access to the master test suite. |
176 | |
177 | /// There is only only master test suite per test module. |
178 | /// @returns a reference the master test suite instance |
179 | BOOST_TEST_DECL master_test_suite_t& master_test_suite(); |
180 | |
181 | /// This function provides an access to the test case currently being executed. |
182 | |
183 | /// This function is only valid during test execution phase. |
184 | /// @see current_test_case_id |
185 | BOOST_TEST_DECL test_case const& current_test_case(); |
186 | |
187 | /// This function provides an access to an id of the test case currently being executed. |
188 | |
189 | /// This function safer than current_test_case, cause if wont throw if no test case is being executed. |
190 | /// @see current_test_case |
191 | BOOST_TEST_DECL test_unit_id current_test_case_id(); /* safe version of above */ |
192 | |
193 | /// This function provides access to a test unit by id and type combination. It will throw if no test unit located. |
194 | /// @param[in] tu_id id of a test unit to locate |
195 | /// @param[in] tu_type type of a test unit to locate |
196 | /// @returns located test unit |
197 | BOOST_TEST_DECL test_unit& get( test_unit_id tu_id, test_unit_type tu_type ); |
198 | |
199 | /// This function template provides access to a typed test unit by id |
200 | |
201 | /// It will throw if you specify incorrect test unit type |
202 | /// @tparam UnitType compile time type of test unit to get (test_suite or test_case) |
203 | /// @param id id of test unit to get |
204 | template<typename UnitType> |
205 | inline UnitType& get( test_unit_id id ) |
206 | { |
207 | return static_cast<UnitType&>( get( tu_id: id, tu_type: static_cast<test_unit_type>(UnitType::type) ) ); |
208 | } |
209 | ///@} |
210 | |
211 | /// @name Test initiation interface |
212 | /// @{ |
213 | |
214 | /// Initiates test execution |
215 | |
216 | /// This function is used to start the test execution from a specific "root" test unit. |
217 | /// If no root provided, test is started from master test suite. This second argument facilitates an ability of the test cases to |
218 | /// start some other test units (primarily used internally for self testing). |
219 | /// @param[in] tu Optional id of the test unit or test unit itself from which the test is started. If absent, master test suite is used |
220 | /// @param[in] continue_test true == continue test if it was already started, false == restart the test from scratch regardless |
221 | BOOST_TEST_DECL void run( test_unit_id tu = INV_TEST_UNIT_ID, bool continue_test = true ); |
222 | /// Initiates test execution. Same as other overload |
223 | BOOST_TEST_DECL void run( test_unit const* tu, bool continue_test = true ); |
224 | /// @} |
225 | |
226 | /// @name Test events dispatchers |
227 | /// @{ |
228 | /// Reports results of assertion to all test observers |
229 | BOOST_TEST_DECL void assertion_result( unit_test::assertion_result ar ); |
230 | /// Reports uncaught exception to all test observers |
231 | BOOST_TEST_DECL void exception_caught( execution_exception const& ); |
232 | /// Reports aborted test unit to all test observers |
233 | BOOST_TEST_DECL void test_unit_aborted( test_unit const& ); |
234 | /// @} |
235 | |
236 | namespace impl { |
237 | // exclusively for self test |
238 | BOOST_TEST_DECL void setup_for_execution( test_unit const& ); |
239 | } // namespace impl |
240 | |
241 | // ************************************************************************** // |
242 | // ************** framework errors ************** // |
243 | // ************************************************************************** // |
244 | |
245 | /// This exception type is used to report internal Boost.Test framework errors. |
246 | struct BOOST_TEST_DECL internal_error : public std::runtime_error { |
247 | internal_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {} |
248 | }; |
249 | |
250 | //____________________________________________________________________________// |
251 | |
252 | /// This exception type is used to report test module setup errors. |
253 | struct BOOST_TEST_DECL setup_error : public std::runtime_error { |
254 | setup_error( const_string m ) : std::runtime_error( std::string( m.begin(), m.size() ) ) {} |
255 | }; |
256 | |
257 | #define BOOST_TEST_SETUP_ASSERT( cond, msg ) BOOST_TEST_I_ASSRT( cond, unit_test::framework::setup_error( msg ) ) |
258 | |
259 | //____________________________________________________________________________// |
260 | |
261 | struct nothing_to_test { |
262 | explicit nothing_to_test( int rc ) : m_result_code( rc ) {} |
263 | |
264 | int m_result_code; |
265 | }; |
266 | |
267 | //____________________________________________________________________________// |
268 | |
269 | } // namespace framework |
270 | } // unit_test |
271 | } // namespace boost |
272 | |
273 | #include <boost/test/detail/enable_warnings.hpp> |
274 | |
275 | #endif // BOOST_TEST_FRAMEWORK_HPP_020805GER |
276 | |