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