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 : implements compiler like Log formatter |
13 | // *************************************************************************** |
14 | |
15 | #ifndef BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER |
16 | #define BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER |
17 | |
18 | // Boost.Test |
19 | #include <boost/test/output/compiler_log_formatter.hpp> |
20 | |
21 | #include <boost/test/framework.hpp> |
22 | #include <boost/test/execution_monitor.hpp> |
23 | #include <boost/test/unit_test_parameters.hpp> |
24 | |
25 | #include <boost/test/tree/test_unit.hpp> |
26 | |
27 | #include <boost/test/utils/basic_cstring/io.hpp> |
28 | #include <boost/test/utils/lazy_ostream.hpp> |
29 | |
30 | // Boost |
31 | #include <boost/version.hpp> |
32 | |
33 | // STL |
34 | #include <iostream> |
35 | |
36 | #include <boost/test/detail/suppress_warnings.hpp> |
37 | |
38 | //____________________________________________________________________________// |
39 | |
40 | namespace boost { |
41 | namespace unit_test { |
42 | namespace output { |
43 | |
44 | // ************************************************************************** // |
45 | // ************** compiler_log_formatter ************** // |
46 | // ************************************************************************** // |
47 | |
48 | namespace { |
49 | |
50 | std::string |
51 | test_phase_identifier() |
52 | { |
53 | return framework::test_in_progress() ? framework::current_test_unit().full_name() : std::string( "Test setup" ); |
54 | } |
55 | |
56 | } // local namespace |
57 | |
58 | //____________________________________________________________________________// |
59 | |
60 | void |
61 | compiler_log_formatter::log_start( std::ostream& output, counter_t test_cases_amount ) |
62 | { |
63 | m_color_output = runtime_config::get<bool>( parameter_name: runtime_config::btrt_color_output ); |
64 | |
65 | if( test_cases_amount > 0 ) |
66 | output << "Running " << test_cases_amount << " test " |
67 | << (test_cases_amount > 1 ? "cases" : "case" ) << "...\n" ; |
68 | } |
69 | |
70 | //____________________________________________________________________________// |
71 | |
72 | void |
73 | compiler_log_formatter::log_finish( std::ostream& ostr ) |
74 | { |
75 | ostr.flush(); |
76 | } |
77 | |
78 | //____________________________________________________________________________// |
79 | |
80 | void |
81 | compiler_log_formatter::log_build_info( std::ostream& output, bool log_build_info ) |
82 | { |
83 | if(log_build_info) { |
84 | output << "Platform: " << BOOST_PLATFORM << '\n' |
85 | << "Compiler: " << BOOST_COMPILER << '\n' |
86 | << "STL : " << BOOST_STDLIB << '\n' |
87 | << "Boost : " << BOOST_VERSION/100000 << "." |
88 | << BOOST_VERSION/100 % 1000 << "." |
89 | << BOOST_VERSION % 100 << std::endl; |
90 | } |
91 | } |
92 | |
93 | //____________________________________________________________________________// |
94 | |
95 | void |
96 | compiler_log_formatter::test_unit_start( std::ostream& output, test_unit const& tu ) |
97 | { |
98 | BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::BLUE ); |
99 | |
100 | print_prefix( output, file: tu.p_file_name, line: tu.p_line_num ); |
101 | |
102 | output << "Entering test " << tu.p_type_name << " \"" << tu.p_name << "\"" << std::endl; |
103 | } |
104 | |
105 | //____________________________________________________________________________// |
106 | |
107 | void |
108 | compiler_log_formatter::test_unit_finish( std::ostream& output, test_unit const& tu, unsigned long elapsed ) |
109 | { |
110 | BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::BLUE ); |
111 | |
112 | print_prefix( output, file: tu.p_file_name, line: tu.p_line_num ); |
113 | |
114 | output << "Leaving test " << tu.p_type_name << " \"" << tu.p_name << "\"" ; |
115 | |
116 | if( elapsed > 0 ) { |
117 | output << "; testing time: " ; |
118 | if( elapsed % 1000 == 0 ) |
119 | output << elapsed/1000 << "ms" ; |
120 | else |
121 | output << elapsed << "us" ; |
122 | } |
123 | |
124 | output << std::endl; |
125 | } |
126 | |
127 | //____________________________________________________________________________// |
128 | |
129 | void |
130 | compiler_log_formatter::test_unit_skipped( std::ostream& output, test_unit const& tu, const_string reason ) |
131 | { |
132 | BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::YELLOW ); |
133 | |
134 | print_prefix( output, file: tu.p_file_name, line: tu.p_line_num ); |
135 | |
136 | output << "Test " << tu.p_type_name << " \"" << tu.full_name() << "\"" << " is skipped because " << reason << std::endl; |
137 | } |
138 | |
139 | //____________________________________________________________________________// |
140 | |
141 | void |
142 | compiler_log_formatter::log_exception_start( std::ostream& output, log_checkpoint_data const& checkpoint_data, execution_exception const& ex ) |
143 | { |
144 | execution_exception::location const& loc = ex.where(); |
145 | |
146 | print_prefix( output, file: loc.m_file_name, line: loc.m_line_num ); |
147 | |
148 | { |
149 | BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::UNDERLINE, term_color::RED ); |
150 | |
151 | output << "fatal error: in \"" << (loc.m_function.is_empty() ? test_phase_identifier() : loc.m_function ) << "\": " |
152 | << ex.what(); |
153 | } |
154 | |
155 | if( !checkpoint_data.m_file_name.is_empty() ) { |
156 | output << '\n'; |
157 | print_prefix( output, file: checkpoint_data.m_file_name, line: checkpoint_data.m_line_num ); |
158 | |
159 | BOOST_TEST_SCOPE_SETCOLOR( m_color_output, output, term_attr::BRIGHT, term_color::CYAN ); |
160 | |
161 | output << "last checkpoint" ; |
162 | if( !checkpoint_data.m_message.empty() ) |
163 | output << ": " << checkpoint_data.m_message; |
164 | } |
165 | } |
166 | |
167 | //____________________________________________________________________________// |
168 | |
169 | void |
170 | compiler_log_formatter::log_exception_finish( std::ostream& output ) |
171 | { |
172 | output << std::endl; |
173 | } |
174 | |
175 | //____________________________________________________________________________// |
176 | |
177 | void |
178 | compiler_log_formatter::log_entry_start( std::ostream& output, log_entry_data const& entry_data, log_entry_types let ) |
179 | { |
180 | using namespace utils; |
181 | |
182 | switch( let ) { |
183 | case BOOST_UTL_ET_INFO: |
184 | print_prefix( output, file: entry_data.m_file_name, line: entry_data.m_line_num ); |
185 | output << setcolor( m_color_output, term_attr::BRIGHT, term_color::GREEN, term_color::ORIGINAL, &m_color_state); |
186 | output << "info: " ; |
187 | break; |
188 | case BOOST_UTL_ET_MESSAGE: |
189 | output << setcolor( m_color_output, term_attr::BRIGHT, term_color::CYAN, term_color::ORIGINAL, &m_color_state); |
190 | break; |
191 | case BOOST_UTL_ET_WARNING: |
192 | print_prefix( output, file: entry_data.m_file_name, line: entry_data.m_line_num ); |
193 | output << setcolor( m_color_output, term_attr::BRIGHT, term_color::YELLOW, term_color::ORIGINAL, &m_color_state); |
194 | output << "warning: in \"" << test_phase_identifier() << "\": " ; |
195 | break; |
196 | case BOOST_UTL_ET_ERROR: |
197 | print_prefix( output, file: entry_data.m_file_name, line: entry_data.m_line_num ); |
198 | output << setcolor( m_color_output, term_attr::BRIGHT, term_color::RED, term_color::ORIGINAL, &m_color_state); |
199 | output << "error: in \"" << test_phase_identifier() << "\": " ; |
200 | break; |
201 | case BOOST_UTL_ET_FATAL_ERROR: |
202 | print_prefix( output, file: entry_data.m_file_name, line: entry_data.m_line_num ); |
203 | output << setcolor( m_color_output, term_attr::UNDERLINE, term_color::RED, term_color::ORIGINAL, &m_color_state); |
204 | output << "fatal error: in \"" << test_phase_identifier() << "\": " ; |
205 | break; |
206 | } |
207 | } |
208 | |
209 | //____________________________________________________________________________// |
210 | |
211 | void |
212 | compiler_log_formatter::log_entry_value( std::ostream& output, const_string value ) |
213 | { |
214 | output << value; |
215 | } |
216 | |
217 | //____________________________________________________________________________// |
218 | |
219 | void |
220 | compiler_log_formatter::log_entry_value( std::ostream& output, lazy_ostream const& value ) |
221 | { |
222 | output << value; |
223 | } |
224 | |
225 | //____________________________________________________________________________// |
226 | |
227 | void |
228 | compiler_log_formatter::log_entry_finish( std::ostream& output ) |
229 | { |
230 | if( m_color_output ) |
231 | output << utils::setcolor(m_color_output, &m_color_state); |
232 | |
233 | output << std::endl; |
234 | } |
235 | |
236 | |
237 | //____________________________________________________________________________// |
238 | |
239 | void |
240 | compiler_log_formatter::print_prefix( std::ostream& output, const_string file_name, std::size_t line_num ) |
241 | { |
242 | if( !file_name.empty() ) { |
243 | #ifdef __APPLE_CC__ |
244 | // Xcode-compatible logging format, idea by Richard Dingwall at |
245 | // <http://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3/>. |
246 | output << file_name << ':' << line_num << ": " ; |
247 | #else |
248 | output << file_name << '(' << line_num << "): " ; |
249 | #endif |
250 | } |
251 | } |
252 | |
253 | //____________________________________________________________________________// |
254 | |
255 | void |
256 | compiler_log_formatter::entry_context_start( std::ostream& output, log_level l ) |
257 | { |
258 | if( l == log_messages ) { |
259 | output << "\n[context:" ; |
260 | } |
261 | else { |
262 | output << (l == log_successful_tests ? "\nAssertion" : "\nFailure" ) << " occurred in a following context:" ; |
263 | } |
264 | } |
265 | |
266 | //____________________________________________________________________________// |
267 | |
268 | void |
269 | compiler_log_formatter::entry_context_finish( std::ostream& output, log_level l ) |
270 | { |
271 | if( l == log_messages ) { |
272 | output << "]" ; |
273 | } |
274 | output.flush(); |
275 | } |
276 | |
277 | //____________________________________________________________________________// |
278 | |
279 | void |
280 | compiler_log_formatter::log_entry_context( std::ostream& output, log_level /*l*/, const_string context_descr ) |
281 | { |
282 | output << "\n " << context_descr; |
283 | } |
284 | |
285 | //____________________________________________________________________________// |
286 | |
287 | } // namespace output |
288 | } // namespace unit_test |
289 | } // namespace boost |
290 | |
291 | #include <boost/test/detail/enable_warnings.hpp> |
292 | |
293 | #endif // BOOST_TEST_COMPILER_LOG_FORMATTER_IPP_020105GER |
294 | |