Chris@16
|
1 // (C) Copyright Gennadiy Rozental 2005-2008.
|
Chris@16
|
2 // Distributed under the Boost Software License, Version 1.0.
|
Chris@16
|
3 // (See accompanying file LICENSE_1_0.txt or copy at
|
Chris@16
|
4 // http://www.boost.org/LICENSE_1_0.txt)
|
Chris@16
|
5
|
Chris@16
|
6 // See http://www.boost.org/libs/test for the library home page.
|
Chris@16
|
7 //
|
Chris@16
|
8 // File : $RCSfile$
|
Chris@16
|
9 //
|
Chris@101
|
10 // Version : $Revision$
|
Chris@16
|
11 //
|
Chris@16
|
12 // Description : implements Unit Test results collecting facility.
|
Chris@16
|
13 // ***************************************************************************
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
|
Chris@16
|
16 #define BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
|
Chris@16
|
17
|
Chris@16
|
18 // Boost.Test
|
Chris@16
|
19 #include <boost/test/unit_test_suite_impl.hpp>
|
Chris@16
|
20 #include <boost/test/unit_test_log.hpp>
|
Chris@16
|
21 #include <boost/test/results_collector.hpp>
|
Chris@16
|
22 #include <boost/test/framework.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 // Boost
|
Chris@16
|
25 #include <boost/cstdlib.hpp>
|
Chris@16
|
26
|
Chris@16
|
27 // STL
|
Chris@16
|
28 #include <map>
|
Chris@16
|
29
|
Chris@16
|
30 #include <boost/test/detail/suppress_warnings.hpp>
|
Chris@16
|
31
|
Chris@16
|
32 //____________________________________________________________________________//
|
Chris@16
|
33
|
Chris@16
|
34 namespace boost {
|
Chris@16
|
35
|
Chris@16
|
36 namespace unit_test {
|
Chris@16
|
37
|
Chris@16
|
38 // ************************************************************************** //
|
Chris@16
|
39 // ************** test_results ************** //
|
Chris@16
|
40 // ************************************************************************** //
|
Chris@16
|
41
|
Chris@16
|
42 test_results::test_results()
|
Chris@16
|
43 {
|
Chris@16
|
44 clear();
|
Chris@16
|
45 }
|
Chris@16
|
46
|
Chris@16
|
47 //____________________________________________________________________________//
|
Chris@16
|
48
|
Chris@16
|
49 bool
|
Chris@16
|
50 test_results::passed() const
|
Chris@16
|
51 {
|
Chris@16
|
52 return !p_skipped &&
|
Chris@16
|
53 p_test_cases_failed == 0 &&
|
Chris@16
|
54 p_assertions_failed <= p_expected_failures &&
|
Chris@16
|
55 !p_aborted;
|
Chris@16
|
56 }
|
Chris@16
|
57
|
Chris@16
|
58 //____________________________________________________________________________//
|
Chris@16
|
59
|
Chris@16
|
60 int
|
Chris@16
|
61 test_results::result_code() const
|
Chris@16
|
62 {
|
Chris@16
|
63 return passed() ? exit_success
|
Chris@16
|
64 : ( (p_assertions_failed > p_expected_failures || p_skipped )
|
Chris@16
|
65 ? exit_test_failure
|
Chris@16
|
66 : exit_exception_failure );
|
Chris@16
|
67 }
|
Chris@16
|
68
|
Chris@16
|
69 //____________________________________________________________________________//
|
Chris@16
|
70
|
Chris@16
|
71 void
|
Chris@16
|
72 test_results::operator+=( test_results const& tr )
|
Chris@16
|
73 {
|
Chris@16
|
74 p_assertions_passed.value += tr.p_assertions_passed;
|
Chris@16
|
75 p_assertions_failed.value += tr.p_assertions_failed;
|
Chris@16
|
76 p_test_cases_passed.value += tr.p_test_cases_passed;
|
Chris@16
|
77 p_test_cases_failed.value += tr.p_test_cases_failed;
|
Chris@16
|
78 p_test_cases_skipped.value += tr.p_test_cases_skipped;
|
Chris@16
|
79 p_test_cases_aborted.value += tr.p_test_cases_aborted;
|
Chris@16
|
80 }
|
Chris@16
|
81
|
Chris@16
|
82 //____________________________________________________________________________//
|
Chris@16
|
83
|
Chris@16
|
84 void
|
Chris@16
|
85 test_results::clear()
|
Chris@16
|
86 {
|
Chris@16
|
87 p_assertions_passed.value = 0;
|
Chris@16
|
88 p_assertions_failed.value = 0;
|
Chris@16
|
89 p_expected_failures.value = 0;
|
Chris@16
|
90 p_test_cases_passed.value = 0;
|
Chris@16
|
91 p_test_cases_failed.value = 0;
|
Chris@16
|
92 p_test_cases_skipped.value = 0;
|
Chris@16
|
93 p_test_cases_aborted.value = 0;
|
Chris@16
|
94 p_aborted.value = false;
|
Chris@16
|
95 p_skipped.value = true;
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 //____________________________________________________________________________//
|
Chris@16
|
99
|
Chris@16
|
100 // ************************************************************************** //
|
Chris@16
|
101 // ************** results_collector ************** //
|
Chris@16
|
102 // ************************************************************************** //
|
Chris@16
|
103
|
Chris@16
|
104 #if !BOOST_WORKAROUND(BOOST_MSVC, <1300)
|
Chris@16
|
105
|
Chris@16
|
106 namespace {
|
Chris@16
|
107
|
Chris@16
|
108 struct results_collector_impl {
|
Chris@16
|
109 std::map<test_unit_id,test_results> m_results_store;
|
Chris@16
|
110 };
|
Chris@16
|
111
|
Chris@16
|
112 results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
|
Chris@16
|
113
|
Chris@16
|
114 } // local namespace
|
Chris@16
|
115
|
Chris@16
|
116 #else
|
Chris@16
|
117
|
Chris@16
|
118 struct results_collector_impl {
|
Chris@16
|
119 std::map<test_unit_id,test_results> m_results_store;
|
Chris@16
|
120 };
|
Chris@16
|
121
|
Chris@16
|
122 static results_collector_impl& s_rc_impl() { static results_collector_impl the_inst; return the_inst; }
|
Chris@16
|
123
|
Chris@16
|
124 #endif
|
Chris@16
|
125
|
Chris@16
|
126 //____________________________________________________________________________//
|
Chris@16
|
127
|
Chris@16
|
128 void
|
Chris@16
|
129 results_collector_t::test_start( counter_t )
|
Chris@16
|
130 {
|
Chris@16
|
131 s_rc_impl().m_results_store.clear();
|
Chris@16
|
132 }
|
Chris@16
|
133
|
Chris@16
|
134 //____________________________________________________________________________//
|
Chris@16
|
135
|
Chris@16
|
136 void
|
Chris@16
|
137 results_collector_t::test_finish()
|
Chris@16
|
138 {
|
Chris@16
|
139 // do nothing
|
Chris@16
|
140 }
|
Chris@16
|
141
|
Chris@16
|
142 //____________________________________________________________________________//
|
Chris@16
|
143
|
Chris@16
|
144 void
|
Chris@16
|
145 results_collector_t::test_aborted()
|
Chris@16
|
146 {
|
Chris@16
|
147 // do nothing
|
Chris@16
|
148 }
|
Chris@16
|
149
|
Chris@16
|
150 //____________________________________________________________________________//
|
Chris@16
|
151
|
Chris@16
|
152 void
|
Chris@16
|
153 results_collector_t::test_unit_start( test_unit const& tu )
|
Chris@16
|
154 {
|
Chris@16
|
155 // init test_results entry
|
Chris@16
|
156 test_results& tr = s_rc_impl().m_results_store[tu.p_id];
|
Chris@16
|
157
|
Chris@16
|
158 tr.clear();
|
Chris@16
|
159
|
Chris@16
|
160 tr.p_expected_failures.value = tu.p_expected_failures;
|
Chris@16
|
161 tr.p_skipped.value = false;
|
Chris@16
|
162 }
|
Chris@16
|
163
|
Chris@16
|
164 //____________________________________________________________________________//
|
Chris@16
|
165
|
Chris@16
|
166 class results_collect_helper : public test_tree_visitor {
|
Chris@16
|
167 public:
|
Chris@16
|
168 explicit results_collect_helper( test_results& tr, test_unit const& ts ) : m_tr( tr ), m_ts( ts ) {}
|
Chris@16
|
169
|
Chris@16
|
170 void visit( test_case const& tc )
|
Chris@16
|
171 {
|
Chris@16
|
172 test_results const& tr = results_collector.results( tc.p_id );
|
Chris@16
|
173 m_tr += tr;
|
Chris@16
|
174
|
Chris@16
|
175 if( tr.passed() )
|
Chris@16
|
176 m_tr.p_test_cases_passed.value++;
|
Chris@16
|
177 else if( tr.p_skipped )
|
Chris@16
|
178 m_tr.p_test_cases_skipped.value++;
|
Chris@16
|
179 else {
|
Chris@16
|
180 if( tr.p_aborted )
|
Chris@16
|
181 m_tr.p_test_cases_aborted.value++;
|
Chris@16
|
182 m_tr.p_test_cases_failed.value++;
|
Chris@16
|
183 }
|
Chris@16
|
184 }
|
Chris@16
|
185 bool test_suite_start( test_suite const& ts )
|
Chris@16
|
186 {
|
Chris@16
|
187 if( m_ts.p_id == ts.p_id )
|
Chris@16
|
188 return true;
|
Chris@16
|
189 else {
|
Chris@16
|
190 m_tr += results_collector.results( ts.p_id );
|
Chris@16
|
191 return false;
|
Chris@16
|
192 }
|
Chris@16
|
193 }
|
Chris@16
|
194
|
Chris@16
|
195 private:
|
Chris@16
|
196 // Data members
|
Chris@16
|
197 test_results& m_tr;
|
Chris@16
|
198 test_unit const& m_ts;
|
Chris@16
|
199 };
|
Chris@16
|
200
|
Chris@16
|
201 //____________________________________________________________________________//
|
Chris@16
|
202
|
Chris@16
|
203 void
|
Chris@16
|
204 results_collector_t::test_unit_finish( test_unit const& tu, unsigned long )
|
Chris@16
|
205 {
|
Chris@16
|
206 if( tu.p_type == tut_suite ) {
|
Chris@16
|
207 results_collect_helper ch( s_rc_impl().m_results_store[tu.p_id], tu );
|
Chris@16
|
208
|
Chris@16
|
209 traverse_test_tree( tu, ch );
|
Chris@16
|
210 }
|
Chris@16
|
211 else {
|
Chris@16
|
212 test_results const& tr = s_rc_impl().m_results_store[tu.p_id];
|
Chris@16
|
213
|
Chris@16
|
214 bool num_failures_match = tr.p_aborted || tr.p_assertions_failed >= tr.p_expected_failures;
|
Chris@16
|
215 if( !num_failures_match )
|
Chris@16
|
216 BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " has fewer failures than expected" );
|
Chris@16
|
217
|
Chris@16
|
218 bool check_any_assertions = tr.p_aborted || (tr.p_assertions_failed != 0) || (tr.p_assertions_passed != 0);
|
Chris@16
|
219 if( !check_any_assertions )
|
Chris@16
|
220 BOOST_TEST_MESSAGE( "Test case " << tu.p_name << " did not check any assertions" );
|
Chris@16
|
221 }
|
Chris@16
|
222 }
|
Chris@16
|
223
|
Chris@16
|
224 //____________________________________________________________________________//
|
Chris@16
|
225
|
Chris@16
|
226 void
|
Chris@16
|
227 results_collector_t::test_unit_skipped( test_unit const& tu )
|
Chris@16
|
228 {
|
Chris@16
|
229 if( tu.p_type == tut_suite ) {
|
Chris@16
|
230 test_case_counter tcc;
|
Chris@16
|
231 traverse_test_tree( tu, tcc );
|
Chris@16
|
232
|
Chris@16
|
233 test_results& tr = s_rc_impl().m_results_store[tu.p_id];
|
Chris@16
|
234
|
Chris@16
|
235 tr.clear();
|
Chris@16
|
236
|
Chris@16
|
237 tr.p_skipped.value = true;
|
Chris@16
|
238 tr.p_test_cases_skipped.value = tcc.p_count;
|
Chris@16
|
239 }
|
Chris@16
|
240 }
|
Chris@16
|
241
|
Chris@16
|
242 //____________________________________________________________________________//
|
Chris@16
|
243
|
Chris@16
|
244 void
|
Chris@16
|
245 results_collector_t::assertion_result( bool passed )
|
Chris@16
|
246 {
|
Chris@16
|
247 test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
|
Chris@16
|
248
|
Chris@16
|
249 if( passed )
|
Chris@16
|
250 tr.p_assertions_passed.value++;
|
Chris@16
|
251 else
|
Chris@16
|
252 tr.p_assertions_failed.value++;
|
Chris@16
|
253
|
Chris@16
|
254 if( tr.p_assertions_failed == 1 )
|
Chris@16
|
255 first_failed_assertion();
|
Chris@16
|
256 }
|
Chris@16
|
257
|
Chris@16
|
258 //____________________________________________________________________________//
|
Chris@16
|
259
|
Chris@16
|
260 void
|
Chris@16
|
261 results_collector_t::exception_caught( execution_exception const& )
|
Chris@16
|
262 {
|
Chris@16
|
263 test_results& tr = s_rc_impl().m_results_store[framework::current_test_case().p_id];
|
Chris@16
|
264
|
Chris@16
|
265 tr.p_assertions_failed.value++;
|
Chris@16
|
266 }
|
Chris@16
|
267
|
Chris@16
|
268 //____________________________________________________________________________//
|
Chris@16
|
269
|
Chris@16
|
270 void
|
Chris@16
|
271 results_collector_t::test_unit_aborted( test_unit const& tu )
|
Chris@16
|
272 {
|
Chris@16
|
273 s_rc_impl().m_results_store[tu.p_id].p_aborted.value = true;
|
Chris@16
|
274 }
|
Chris@16
|
275
|
Chris@16
|
276 //____________________________________________________________________________//
|
Chris@16
|
277
|
Chris@16
|
278 test_results const&
|
Chris@16
|
279 results_collector_t::results( test_unit_id id ) const
|
Chris@16
|
280 {
|
Chris@16
|
281 return s_rc_impl().m_results_store[id];
|
Chris@16
|
282 }
|
Chris@16
|
283
|
Chris@16
|
284 //____________________________________________________________________________//
|
Chris@16
|
285
|
Chris@16
|
286 } // namespace unit_test
|
Chris@16
|
287
|
Chris@16
|
288 } // namespace boost
|
Chris@16
|
289
|
Chris@16
|
290 //____________________________________________________________________________//
|
Chris@16
|
291
|
Chris@16
|
292 #include <boost/test/detail/enable_warnings.hpp>
|
Chris@16
|
293
|
Chris@16
|
294 #endif // BOOST_TEST_RESULTS_COLLECTOR_IPP_021105GER
|