Line data Source code
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 : 35 : namespace boost { 36 : namespace unit_test { 37 : 38 : // ************************************************************************** // 39 : // ************** progress_monitor ************** // 40 : // ************************************************************************** // 41 : 42 : struct progress_display { 43 0 : progress_display( counter_t expected_count, std::ostream& os ) 44 0 : : m_os(os) 45 0 : , m_count( 0 ) 46 0 : , m_expected_count( expected_count ) 47 0 : , m_next_tic_count( 0 ) 48 0 : , m_tic( 0 ) 49 0 : { 50 : 51 0 : m_os << "\n0% 10 20 30 40 50 60 70 80 90 100%" 52 0 : << "\n|----|----|----|----|----|----|----|----|----|----|" 53 0 : << std::endl; 54 : 55 0 : if( !m_expected_count ) 56 0 : m_expected_count = 1; // prevent divide by zero 57 0 : } 58 : 59 0 : unsigned long operator+=( unsigned long increment ) 60 : { 61 0 : if( (m_count += increment) < m_next_tic_count ) 62 0 : 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 0 : unsigned int tics_needed = static_cast<unsigned int>( 68 0 : (static_cast<double>(m_count)/m_expected_count)*50.0 ); 69 : 70 0 : do { 71 0 : m_os << '*' << std::flush; 72 0 : } while( ++m_tic < tics_needed ); 73 : 74 0 : m_next_tic_count = static_cast<unsigned long>((m_tic/50.0) * m_expected_count); 75 : 76 0 : if( m_count == m_expected_count ) { 77 0 : if( m_tic < 51 ) 78 0 : m_os << '*'; 79 : 80 0 : m_os << std::endl; 81 0 : } 82 : 83 0 : return m_count; 84 0 : } 85 0 : unsigned long operator++() { return operator+=( 1 ); } 86 0 : unsigned long count() const { return m_count; } 87 : 88 : private: 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 : 100 : namespace { 101 : 102 : struct progress_monitor_impl { 103 : // Constructor 104 0 : progress_monitor_impl() 105 0 : : m_stream( &std::cout ) 106 0 : , m_color_output( false ) 107 0 : { 108 0 : } 109 : 110 : std::ostream* m_stream; 111 : scoped_ptr<progress_display> m_progress_display; 112 : bool m_color_output; 113 : }; 114 : 115 0 : progress_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 : 124 146 : BOOST_TEST_SINGLETON_CONS_IMPL(progress_monitor_t) 125 : 126 : //____________________________________________________________________________// 127 : 128 : void 129 0 : progress_monitor_t::test_start( counter_t test_cases_amount, test_unit_id ) 130 : { 131 0 : s_pm_impl().m_color_output = runtime_config::get<bool>( runtime_config::btrt_color_output ); 132 : 133 0 : PM_SCOPED_COLOR(); 134 : 135 0 : s_pm_impl().m_progress_display.reset( new progress_display( test_cases_amount, *s_pm_impl().m_stream ) ); 136 0 : } 137 : 138 : //____________________________________________________________________________// 139 : 140 : void 141 0 : progress_monitor_t::test_aborted() 142 : { 143 0 : PM_SCOPED_COLOR(); 144 : 145 0 : (*s_pm_impl().m_progress_display) += s_pm_impl().m_progress_display->count(); 146 0 : } 147 : 148 : //____________________________________________________________________________// 149 : 150 : void 151 0 : progress_monitor_t::test_unit_finish( test_unit const& tu, unsigned long ) 152 : { 153 0 : PM_SCOPED_COLOR(); 154 : 155 0 : if( tu.p_type == TUT_CASE ) 156 0 : ++(*s_pm_impl().m_progress_display); 157 0 : } 158 : 159 : //____________________________________________________________________________// 160 : 161 : void 162 0 : progress_monitor_t::test_unit_skipped( test_unit const& tu, const_string /*reason*/ ) 163 : { 164 0 : PM_SCOPED_COLOR(); 165 : 166 0 : test_case_counter tcc; 167 0 : traverse_test_tree( tu, tcc ); 168 : 169 0 : (*s_pm_impl().m_progress_display) += tcc.p_count; 170 0 : } 171 : 172 : //____________________________________________________________________________// 173 : 174 : void 175 0 : progress_monitor_t::set_stream( std::ostream& ostr ) 176 : { 177 0 : s_pm_impl().m_stream = &ostr; 178 0 : } 179 : 180 : //____________________________________________________________________________// 181 : 182 : #undef PM_SCOPED_COLOR 183 : 184 : } // namespace unit_test 185 : } // namespace boost 186 : 187 : #include <boost/test/detail/enable_warnings.hpp> 188 : 189 : #endif // BOOST_TEST_PROGRESS_MONITOR_IPP_020105GER