]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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$ | |
11 | // | |
12 | // Description : main function implementation for Unit Test Framework | |
13 | // *************************************************************************** | |
14 | ||
15 | #ifndef BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER | |
16 | #define BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER | |
17 | ||
18 | // Boost.Test | |
19 | #include <boost/test/framework.hpp> | |
20 | #include <boost/test/results_collector.hpp> | |
21 | #include <boost/test/results_reporter.hpp> | |
22 | ||
23 | #include <boost/test/tree/visitor.hpp> | |
24 | #include <boost/test/tree/test_unit.hpp> | |
25 | #include <boost/test/tree/traverse.hpp> | |
26 | ||
27 | #include <boost/test/unit_test_parameters.hpp> | |
28 | ||
29 | #include <boost/test/utils/foreach.hpp> | |
30 | #include <boost/test/utils/basic_cstring/io.hpp> | |
31 | ||
32 | // Boost | |
33 | #include <boost/cstdlib.hpp> | |
34 | ||
35 | // STL | |
36 | #include <cstdio> | |
37 | #include <stdexcept> | |
38 | #include <iostream> | |
39 | #include <iomanip> | |
40 | #include <set> | |
41 | ||
42 | #include <boost/test/detail/suppress_warnings.hpp> | |
43 | ||
44 | //____________________________________________________________________________// | |
45 | ||
46 | namespace boost { | |
47 | namespace unit_test { | |
48 | ||
49 | namespace ut_detail { | |
50 | ||
51 | // ************************************************************************** // | |
52 | // ************** hrf_content_reporter ************** // | |
53 | // ************************************************************************** // | |
54 | ||
55 | struct hrf_content_reporter : test_tree_visitor { | |
56 | explicit hrf_content_reporter( std::ostream& os ) : m_os( os ), m_indent( -4 ) {} // skip master test suite | |
57 | ||
58 | private: | |
59 | void report_test_unit( test_unit const& tu ) | |
60 | { | |
61 | m_os << std::setw( m_indent ) << "" << tu.p_name; | |
62 | m_os << (tu.p_default_status == test_unit::RS_ENABLED ? "*" : " "); | |
63 | //m_os << '[' << tu.p_sibling_rank << ']'; | |
64 | if( !tu.p_description->empty() ) | |
65 | m_os << ": " << tu.p_description; | |
66 | ||
67 | m_os << "\n"; | |
68 | } | |
69 | virtual void visit( test_case const& tc ) { report_test_unit( tc ); } | |
70 | virtual bool test_suite_start( test_suite const& ts ) | |
71 | { | |
72 | if( m_indent >= 0 ) | |
73 | report_test_unit( ts ); | |
74 | m_indent += 4; | |
75 | return true; | |
76 | } | |
77 | virtual void test_suite_finish( test_suite const& ) | |
78 | { | |
79 | m_indent -= 4; | |
80 | } | |
81 | ||
82 | // Data members | |
83 | std::ostream& m_os; | |
84 | int m_indent; | |
85 | }; | |
86 | ||
87 | // ************************************************************************** // | |
88 | // ************** dot_content_reporter ************** // | |
89 | // ************************************************************************** // | |
90 | ||
91 | struct dot_content_reporter : test_tree_visitor { | |
92 | explicit dot_content_reporter( std::ostream& os ) : m_os( os ) {} | |
93 | ||
94 | private: | |
95 | void report_test_unit( test_unit const& tu ) | |
96 | { | |
97 | bool master_ts = tu.p_parent_id == INV_TEST_UNIT_ID; | |
98 | ||
99 | m_os << "tu" << tu.p_id; | |
100 | ||
101 | m_os << (master_ts ? "[shape=ellipse,peripheries=2" : "[shape=Mrecord" ); | |
102 | ||
103 | m_os << ",fontname=Helvetica"; | |
104 | ||
105 | m_os << (tu.p_default_status == test_unit::RS_ENABLED ? ",color=green" : ",color=yellow"); | |
106 | ||
107 | if( master_ts ) | |
108 | m_os << ",label=\"" << tu.p_name << "\"];\n"; | |
109 | else { | |
110 | m_os << ",label=\"" << tu.p_name << "|" << tu.p_file_name << "(" << tu.p_line_num << ")"; | |
111 | if( tu.p_timeout > 0 ) | |
112 | m_os << "|timeout=" << tu.p_timeout; | |
113 | if( tu.p_expected_failures != 0 ) | |
114 | m_os << "|expected failures=" << tu.p_expected_failures; | |
115 | if( !tu.p_labels->empty() ) { | |
116 | m_os << "|labels:"; | |
117 | ||
118 | BOOST_TEST_FOREACH( std::string const&, l, tu.p_labels.get() ) | |
119 | m_os << " @" << l; | |
120 | } | |
121 | m_os << "\"];\n"; | |
122 | } | |
123 | ||
124 | if( !master_ts ) | |
125 | m_os << "tu" << tu.p_parent_id << " -> " << "tu" << tu.p_id << ";\n"; | |
126 | ||
127 | BOOST_TEST_FOREACH( test_unit_id, dep_id, tu.p_dependencies.get() ) { | |
128 | test_unit const& dep = framework::get( dep_id, TUT_ANY ); | |
129 | ||
130 | m_os << "tu" << tu.p_id << " -> " << "tu" << dep.p_id << "[color=red,style=dotted,constraint=false];\n"; | |
131 | } | |
132 | ||
133 | } | |
134 | virtual void visit( test_case const& tc ) | |
135 | { | |
136 | report_test_unit( tc ); | |
137 | } | |
138 | virtual bool test_suite_start( test_suite const& ts ) | |
139 | { | |
140 | if( ts.p_parent_id == INV_TEST_UNIT_ID ) | |
141 | m_os << "digraph G {rankdir=LR;\n"; | |
142 | ||
143 | report_test_unit( ts ); | |
144 | ||
145 | m_os << "{\n"; | |
146 | ||
147 | return true; | |
148 | } | |
149 | virtual void test_suite_finish( test_suite const& ts ) | |
150 | { | |
151 | m_os << "}\n"; | |
152 | if( ts.p_parent_id == INV_TEST_UNIT_ID ) | |
153 | m_os << "}\n"; | |
154 | } | |
155 | ||
156 | std::ostream& m_os; | |
157 | }; | |
158 | ||
159 | // ************************************************************************** // | |
160 | // ************** labels_collector ************** // | |
161 | // ************************************************************************** // | |
162 | ||
163 | struct labels_collector : test_tree_visitor { | |
164 | std::set<std::string> const& labels() const { return m_labels; } | |
165 | ||
166 | private: | |
167 | virtual bool visit( test_unit const& tu ) | |
168 | { | |
169 | m_labels.insert( tu.p_labels->begin(), tu.p_labels->end() ); | |
170 | return true; | |
171 | } | |
172 | ||
173 | // Data members | |
174 | std::set<std::string> m_labels; | |
175 | }; | |
176 | ||
177 | } // namespace ut_detail | |
178 | ||
179 | // ************************************************************************** // | |
180 | // ************** unit_test_main ************** // | |
181 | // ************************************************************************** // | |
182 | ||
183 | int BOOST_TEST_DECL | |
184 | unit_test_main( init_unit_test_func init_func, int argc, char* argv[] ) | |
185 | { | |
186 | int result_code = 0; | |
187 | ||
188 | BOOST_TEST_I_TRY { | |
189 | framework::init( init_func, argc, argv ); | |
190 | ||
191 | if( runtime_config::get<bool>( runtime_config::WAIT_FOR_DEBUGGER ) ) { | |
192 | results_reporter::get_stream() << "Press any key to continue..." << std::endl; | |
193 | ||
194 | // getchar is defined as a macro in uClibc. Use parenthesis to fix | |
195 | // gcc bug 58952 for gcc <= 4.8.2. | |
196 | (std::getchar)(); | |
197 | results_reporter::get_stream() << "Continuing..." << std::endl; | |
198 | } | |
199 | ||
200 | framework::finalize_setup_phase(); | |
201 | ||
202 | output_format list_cont = runtime_config::get<output_format>( runtime_config::LIST_CONTENT ); | |
203 | if( list_cont != unit_test::OF_INVALID ) { | |
204 | if( list_cont == unit_test::OF_DOT ) { | |
205 | ut_detail::dot_content_reporter reporter( results_reporter::get_stream() ); | |
206 | ||
207 | traverse_test_tree( framework::master_test_suite().p_id, reporter, true ); | |
208 | } | |
209 | else { | |
210 | ut_detail::hrf_content_reporter reporter( results_reporter::get_stream() ); | |
211 | ||
212 | traverse_test_tree( framework::master_test_suite().p_id, reporter, true ); | |
213 | } | |
214 | ||
215 | return boost::exit_success; | |
216 | } | |
217 | ||
218 | if( runtime_config::get<bool>( runtime_config::LIST_LABELS ) ) { | |
219 | ut_detail::labels_collector collector; | |
220 | ||
221 | traverse_test_tree( framework::master_test_suite().p_id, collector, true ); | |
222 | ||
223 | results_reporter::get_stream() << "Available labels:\n "; | |
224 | std::copy( collector.labels().begin(), collector.labels().end(), | |
225 | std::ostream_iterator<std::string>( results_reporter::get_stream(), "\n " ) ); | |
226 | results_reporter::get_stream() << "\n"; | |
227 | ||
228 | return boost::exit_success; | |
229 | } | |
230 | ||
231 | framework::run(); | |
232 | ||
233 | results_reporter::make_report(); | |
234 | ||
235 | result_code = !runtime_config::get<bool>( runtime_config::RESULT_CODE ) | |
236 | ? boost::exit_success | |
237 | : results_collector.results( framework::master_test_suite().p_id ).result_code(); | |
238 | } | |
239 | BOOST_TEST_I_CATCH( framework::nothing_to_test, ex ) { | |
240 | result_code = ex.m_result_code; | |
241 | } | |
242 | BOOST_TEST_I_CATCH( framework::internal_error, ex ) { | |
243 | results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl; | |
244 | ||
245 | result_code = boost::exit_exception_failure; | |
246 | } | |
247 | BOOST_TEST_I_CATCH( framework::setup_error, ex ) { | |
248 | results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl; | |
249 | ||
250 | result_code = boost::exit_exception_failure; | |
251 | } | |
252 | BOOST_TEST_I_CATCHALL() { | |
253 | results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl; | |
254 | ||
255 | result_code = boost::exit_exception_failure; | |
256 | } | |
257 | ||
258 | framework::shutdown(); | |
259 | ||
260 | return result_code; | |
261 | } | |
262 | ||
263 | } // namespace unit_test | |
264 | } // namespace boost | |
265 | ||
266 | #if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN) | |
267 | ||
268 | // ************************************************************************** // | |
269 | // ************** main function for tests using lib ************** // | |
270 | // ************************************************************************** // | |
271 | ||
272 | int BOOST_TEST_CALL_DECL | |
273 | main( int argc, char* argv[] ) | |
274 | { | |
275 | // prototype for user's unit test init function | |
276 | #ifdef BOOST_TEST_ALTERNATIVE_INIT_API | |
277 | extern bool init_unit_test(); | |
278 | ||
279 | boost::unit_test::init_unit_test_func init_func = &init_unit_test; | |
280 | #else | |
281 | extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] ); | |
282 | ||
283 | boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite; | |
284 | #endif | |
285 | ||
286 | return ::boost::unit_test::unit_test_main( init_func, argc, argv ); | |
287 | } | |
288 | ||
289 | #endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN | |
290 | ||
291 | //____________________________________________________________________________// | |
292 | ||
293 | #include <boost/test/detail/enable_warnings.hpp> | |
294 | ||
295 | #endif // BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER |