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 simple text based progress monitor 13// *************************************************************************** 14 15#ifndef BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER 16#define BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER 17 18// Boost.Test 19#include <boost/test/progress_monitor.hpp> 20#include <boost/test/unit_test_parameters.hpp> 21 22#include <boost/test/utils/setcolor.hpp> 23 24#include <boost/test/tree/test_unit.hpp> 25#include <boost/test/tree/test_case_counter.hpp> 26#include <boost/test/tree/traverse.hpp> 27 28// Boost 29#include <boost/scoped_ptr.hpp> 30 31#include <boost/test/detail/suppress_warnings.hpp> 32 33//____________________________________________________________________________// 34 35namespace boost { 36namespace unit_test { 37 38// ************************************************************************** // 39// ************** progress_monitor ************** // 40// ************************************************************************** // 41 42struct progress_display { 43 progress_display( counter_t expected_count, std::ostream& os ) 44 : m_os(os) 45 , m_count( 0 ) 46 , m_expected_count( expected_count ) 47 , m_next_tic_count( 0 ) 48 , m_tic( 0 ) 49 { 50 51 m_os << "\n0% 10 20 30 40 50 60 70 80 90 100%" 52 << "\n|----|----|----|----|----|----|----|----|----|----|" 53 << std::endl; 54 55 if( !m_expected_count ) 56 m_expected_count = 1; // prevent divide by zero 57 } 58 59 unsigned long operator+=( unsigned long increment ) 60 { 61 if( (m_count += increment) < m_next_tic_count ) 62 return m_count; 63 64 // use of floating point ensures that both large and small counts 65 // work correctly. static_cast<>() is also used several places 66 // to suppress spurious compiler warnings. 67 unsigned int tics_needed = static_cast<unsigned int>( 68 (static_cast<double>(m_count)/m_expected_count)*50.0 ); 69 70 do { 71 m_os << '*' << std::flush; 72 } while( ++m_tic < tics_needed ); 73 74 m_next_tic_count = static_cast<unsigned long>((m_tic/50.0) * m_expected_count); 75 76 if( m_count == m_expected_count ) { 77 if( m_tic < 51 ) 78 m_os << '*'; 79 80 m_os << std::endl; 81 } 82 83 return m_count; 84 } 85 unsigned long operator++() { return operator+=( 1 ); } 86 unsigned long count() const { return m_count; } 87 88private: 89 BOOST_DELETED_FUNCTION(progress_display(progress_display const&)) 90 BOOST_DELETED_FUNCTION(progress_display& operator=(progress_display const&)) 91 92 std::ostream& m_os; // may not be present in all imps 93 94 unsigned long m_count; 95 unsigned long m_expected_count; 96 unsigned long m_next_tic_count; 97 unsigned int m_tic; 98}; 99 100namespace { 101 102struct progress_monitor_impl { 103 // Constructor 104 progress_monitor_impl() 105 : m_stream( &std::cout ) 106 , m_color_output( false ) 107 { 108 } 109 110 std::ostream* m_stream; 111 scoped_ptr<progress_display> m_progress_display; 112 bool m_color_output; 113}; 114 115progress_monitor_impl& s_pm_impl() { static progress_monitor_impl the_inst; return the_inst; } 116 117#define PM_SCOPED_COLOR() \ 118 BOOST_TEST_SCOPE_SETCOLOR( s_pm_impl().m_color_output, *s_pm_impl().m_stream, term_attr::BRIGHT, term_color::MAGENTA ) 119 120} // local namespace 121 122//____________________________________________________________________________// 123 124void 125progress_monitor_t::test_start( counter_t test_cases_amount ) 126{ 127 s_pm_impl().m_color_output = runtime_config::get<bool>( runtime_config::btrt_color_output ); 128 129 PM_SCOPED_COLOR(); 130 131 s_pm_impl().m_progress_display.reset( new progress_display( test_cases_amount, *s_pm_impl().m_stream ) ); 132} 133 134//____________________________________________________________________________// 135 136void 137progress_monitor_t::test_aborted() 138{ 139 PM_SCOPED_COLOR(); 140 141 (*s_pm_impl().m_progress_display) += s_pm_impl().m_progress_display->count(); 142} 143 144//____________________________________________________________________________// 145 146void 147progress_monitor_t::test_unit_finish( test_unit const& tu, unsigned long ) 148{ 149 PM_SCOPED_COLOR(); 150 151 if( tu.p_type == TUT_CASE ) 152 ++(*s_pm_impl().m_progress_display); 153} 154 155//____________________________________________________________________________// 156 157void 158progress_monitor_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ ) 159{ 160 PM_SCOPED_COLOR(); 161 162 test_case_counter tcc; 163 traverse_test_tree( tu, tcc ); 164 165 (*s_pm_impl().m_progress_display) += tcc.p_count; 166} 167 168//____________________________________________________________________________// 169 170void 171progress_monitor_t::set_stream( std::ostream& ostr ) 172{ 173 s_pm_impl().m_stream = &ostr; 174} 175 176//____________________________________________________________________________// 177 178#undef PM_SCOPED_COLOR 179 180} // namespace unit_test 181} // namespace boost 182 183#include <boost/test/detail/enable_warnings.hpp> 184 185#endif // BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER 186