Chris@16
|
1 // (C) Copyright Gennadiy Rozental 2001-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 : main function implementation for Unit Test Framework
|
Chris@16
|
13 // ***************************************************************************
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
|
Chris@16
|
16 #define BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
|
Chris@16
|
17
|
Chris@16
|
18 // Boost.Test
|
Chris@16
|
19 #include <boost/test/framework.hpp>
|
Chris@16
|
20 #include <boost/test/results_collector.hpp>
|
Chris@16
|
21 #include <boost/test/unit_test_suite_impl.hpp>
|
Chris@16
|
22 #include <boost/test/results_reporter.hpp>
|
Chris@16
|
23
|
Chris@16
|
24 #include <boost/test/detail/unit_test_parameters.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 #if !defined(__BORLANDC__) && !BOOST_WORKAROUND( BOOST_MSVC, < 1300 ) && !BOOST_WORKAROUND( __SUNPRO_CC, < 0x5100 )
|
Chris@16
|
27 #define BOOST_TEST_SUPPORT_RUN_BY_NAME
|
Chris@16
|
28 #include <boost/test/utils/iterator/token_iterator.hpp>
|
Chris@16
|
29 #endif
|
Chris@16
|
30
|
Chris@16
|
31 // Boost
|
Chris@16
|
32 #include <boost/cstdlib.hpp>
|
Chris@16
|
33 #include <boost/bind.hpp>
|
Chris@16
|
34
|
Chris@16
|
35 // STL
|
Chris@16
|
36 #include <stdexcept>
|
Chris@16
|
37 #include <iostream>
|
Chris@16
|
38
|
Chris@16
|
39 #include <boost/test/detail/suppress_warnings.hpp>
|
Chris@16
|
40
|
Chris@16
|
41 //____________________________________________________________________________//
|
Chris@16
|
42
|
Chris@16
|
43 namespace boost {
|
Chris@16
|
44
|
Chris@16
|
45 namespace unit_test {
|
Chris@16
|
46
|
Chris@16
|
47 // ************************************************************************** //
|
Chris@16
|
48 // ************** test_case_filter ************** //
|
Chris@16
|
49 // ************************************************************************** //
|
Chris@16
|
50
|
Chris@16
|
51 class test_case_filter : public test_tree_visitor {
|
Chris@16
|
52 public:
|
Chris@16
|
53 struct single_filter {
|
Chris@16
|
54 single_filter( const_string in )
|
Chris@16
|
55 {
|
Chris@16
|
56 if( in == "*" )
|
Chris@16
|
57 m_kind = SFK_ALL;
|
Chris@16
|
58 else if( first_char( in ) == '*' && last_char( in ) == '*' ) {
|
Chris@16
|
59 m_kind = SFK_SUBSTR;
|
Chris@16
|
60 m_value = in.substr( 1, in.size()-1 );
|
Chris@16
|
61 }
|
Chris@16
|
62 else if( first_char( in ) == '*' ) {
|
Chris@16
|
63 m_kind = SFK_TRAILING;
|
Chris@16
|
64 m_value = in.substr( 1 );
|
Chris@16
|
65 }
|
Chris@16
|
66 else if( last_char( in ) == '*' ) {
|
Chris@16
|
67 m_kind = SFK_LEADING;
|
Chris@16
|
68 m_value = in.substr( 0, in.size()-1 );
|
Chris@16
|
69 }
|
Chris@16
|
70 else {
|
Chris@16
|
71 m_kind = SFK_MATCH;
|
Chris@16
|
72 m_value = in;
|
Chris@16
|
73 }
|
Chris@16
|
74 };
|
Chris@16
|
75
|
Chris@16
|
76 bool pass( test_unit const& tu ) const
|
Chris@16
|
77 {
|
Chris@16
|
78 const_string name( tu.p_name );
|
Chris@16
|
79
|
Chris@16
|
80 switch( m_kind ) {
|
Chris@16
|
81 default:
|
Chris@16
|
82 case SFK_ALL:
|
Chris@16
|
83 return true;
|
Chris@16
|
84
|
Chris@16
|
85 case SFK_LEADING:
|
Chris@16
|
86 return name.substr( 0, m_value.size() ) == m_value;
|
Chris@16
|
87
|
Chris@16
|
88 case SFK_TRAILING:
|
Chris@16
|
89 return name.size() >= m_value.size() && name.substr( name.size() - m_value.size() ) == m_value;
|
Chris@16
|
90
|
Chris@16
|
91 case SFK_SUBSTR:
|
Chris@16
|
92 return name.find( m_value ) != const_string::npos;
|
Chris@16
|
93
|
Chris@16
|
94 case SFK_MATCH:
|
Chris@16
|
95 return m_value == tu.p_name.get();
|
Chris@16
|
96 }
|
Chris@16
|
97 }
|
Chris@16
|
98 enum kind { SFK_ALL, SFK_LEADING, SFK_TRAILING, SFK_SUBSTR, SFK_MATCH };
|
Chris@16
|
99
|
Chris@16
|
100 kind m_kind;
|
Chris@16
|
101 const_string m_value;
|
Chris@16
|
102 };
|
Chris@16
|
103 // Constructor
|
Chris@16
|
104 #ifndef BOOST_TEST_SUPPORT_RUN_BY_NAME
|
Chris@16
|
105 explicit test_case_filter( const_string ) : m_depth( 0 ) {}
|
Chris@16
|
106 #else
|
Chris@16
|
107 explicit test_case_filter( const_string tc_to_run )
|
Chris@16
|
108 : m_depth( 0 )
|
Chris@16
|
109 {
|
Chris@16
|
110 string_token_iterator tit( tc_to_run, (dropped_delimeters = "/", kept_delimeters = dt_none) );
|
Chris@16
|
111
|
Chris@16
|
112 while( tit != string_token_iterator() ) {
|
Chris@16
|
113 m_filters.push_back(
|
Chris@16
|
114 std::vector<single_filter>( string_token_iterator( *tit, (dropped_delimeters = ",", kept_delimeters = dt_none) ),
|
Chris@16
|
115 string_token_iterator() ) );
|
Chris@16
|
116
|
Chris@16
|
117 ++tit;
|
Chris@16
|
118 }
|
Chris@16
|
119 }
|
Chris@16
|
120 #endif
|
Chris@16
|
121
|
Chris@16
|
122 void filter_unit( test_unit const& tu )
|
Chris@16
|
123 {
|
Chris@16
|
124 if( (++m_depth - 1) > m_filters.size() ) {
|
Chris@16
|
125 tu.p_enabled.value = true;
|
Chris@16
|
126 return;
|
Chris@16
|
127 }
|
Chris@16
|
128
|
Chris@16
|
129 if( m_depth == 1 )
|
Chris@16
|
130 return;
|
Chris@16
|
131
|
Chris@16
|
132 std::vector<single_filter> const& filters = m_filters[m_depth-2];
|
Chris@16
|
133
|
Chris@16
|
134 tu.p_enabled.value =
|
Chris@16
|
135 std::find_if( filters.begin(), filters.end(), bind( &single_filter::pass, _1, boost::ref(tu) ) ) != filters.end();
|
Chris@16
|
136 }
|
Chris@16
|
137
|
Chris@16
|
138 // test tree visitor interface
|
Chris@16
|
139 virtual void visit( test_case const& tc )
|
Chris@16
|
140 {
|
Chris@16
|
141 if( m_depth < m_filters.size() ) {
|
Chris@16
|
142 tc.p_enabled.value = false;
|
Chris@16
|
143 return;
|
Chris@16
|
144 }
|
Chris@16
|
145
|
Chris@16
|
146 filter_unit( tc );
|
Chris@16
|
147
|
Chris@16
|
148 --m_depth;
|
Chris@16
|
149 }
|
Chris@16
|
150
|
Chris@16
|
151 virtual bool test_suite_start( test_suite const& ts )
|
Chris@16
|
152 {
|
Chris@16
|
153 filter_unit( ts );
|
Chris@16
|
154
|
Chris@16
|
155 if( !ts.p_enabled )
|
Chris@16
|
156 --m_depth;
|
Chris@16
|
157
|
Chris@16
|
158 return ts.p_enabled;
|
Chris@16
|
159 }
|
Chris@16
|
160
|
Chris@16
|
161 virtual void test_suite_finish( test_suite const& ) { --m_depth; }
|
Chris@16
|
162
|
Chris@16
|
163 private:
|
Chris@16
|
164 // Data members
|
Chris@16
|
165 std::vector<std::vector<single_filter> > m_filters;
|
Chris@16
|
166 unsigned m_depth;
|
Chris@16
|
167 };
|
Chris@16
|
168
|
Chris@16
|
169 // ************************************************************************** //
|
Chris@16
|
170 // ************** unit_test_main ************** //
|
Chris@16
|
171 // ************************************************************************** //
|
Chris@16
|
172
|
Chris@16
|
173 int BOOST_TEST_DECL
|
Chris@16
|
174 unit_test_main( init_unit_test_func init_func, int argc, char* argv[] )
|
Chris@16
|
175 {
|
Chris@16
|
176 try {
|
Chris@16
|
177 framework::init( init_func, argc, argv );
|
Chris@16
|
178
|
Chris@16
|
179 if( !runtime_config::test_to_run().is_empty() ) {
|
Chris@16
|
180 test_case_filter filter( runtime_config::test_to_run() );
|
Chris@16
|
181
|
Chris@16
|
182 traverse_test_tree( framework::master_test_suite().p_id, filter );
|
Chris@16
|
183 }
|
Chris@16
|
184
|
Chris@16
|
185 framework::run();
|
Chris@16
|
186
|
Chris@16
|
187 results_reporter::make_report();
|
Chris@16
|
188
|
Chris@16
|
189 return runtime_config::no_result_code()
|
Chris@16
|
190 ? boost::exit_success
|
Chris@16
|
191 : results_collector.results( framework::master_test_suite().p_id ).result_code();
|
Chris@16
|
192 }
|
Chris@16
|
193 catch( framework::nothing_to_test const& ) {
|
Chris@16
|
194 return boost::exit_success;
|
Chris@16
|
195 }
|
Chris@16
|
196 catch( framework::internal_error const& ex ) {
|
Chris@16
|
197 results_reporter::get_stream() << "Boost.Test framework internal error: " << ex.what() << std::endl;
|
Chris@16
|
198
|
Chris@16
|
199 return boost::exit_exception_failure;
|
Chris@16
|
200 }
|
Chris@16
|
201 catch( framework::setup_error const& ex ) {
|
Chris@16
|
202 results_reporter::get_stream() << "Test setup error: " << ex.what() << std::endl;
|
Chris@16
|
203
|
Chris@16
|
204 return boost::exit_exception_failure;
|
Chris@16
|
205 }
|
Chris@16
|
206 catch( ... ) {
|
Chris@16
|
207 results_reporter::get_stream() << "Boost.Test framework internal error: unknown reason" << std::endl;
|
Chris@16
|
208
|
Chris@16
|
209 return boost::exit_exception_failure;
|
Chris@16
|
210 }
|
Chris@16
|
211 }
|
Chris@16
|
212
|
Chris@16
|
213 } // namespace unit_test
|
Chris@16
|
214
|
Chris@16
|
215 } // namespace boost
|
Chris@16
|
216
|
Chris@16
|
217 #if !defined(BOOST_TEST_DYN_LINK) && !defined(BOOST_TEST_NO_MAIN)
|
Chris@16
|
218
|
Chris@16
|
219 // ************************************************************************** //
|
Chris@16
|
220 // ************** main function for tests using lib ************** //
|
Chris@16
|
221 // ************************************************************************** //
|
Chris@16
|
222
|
Chris@16
|
223 int BOOST_TEST_CALL_DECL
|
Chris@16
|
224 main( int argc, char* argv[] )
|
Chris@16
|
225 {
|
Chris@16
|
226 // prototype for user's unit test init function
|
Chris@16
|
227 #ifdef BOOST_TEST_ALTERNATIVE_INIT_API
|
Chris@16
|
228 extern bool init_unit_test();
|
Chris@16
|
229
|
Chris@16
|
230 boost::unit_test::init_unit_test_func init_func = &init_unit_test;
|
Chris@16
|
231 #else
|
Chris@16
|
232 extern ::boost::unit_test::test_suite* init_unit_test_suite( int argc, char* argv[] );
|
Chris@16
|
233
|
Chris@16
|
234 boost::unit_test::init_unit_test_func init_func = &init_unit_test_suite;
|
Chris@16
|
235 #endif
|
Chris@16
|
236
|
Chris@16
|
237 return ::boost::unit_test::unit_test_main( init_func, argc, argv );
|
Chris@16
|
238 }
|
Chris@16
|
239
|
Chris@16
|
240 #endif // !BOOST_TEST_DYN_LINK && !BOOST_TEST_NO_MAIN
|
Chris@16
|
241
|
Chris@16
|
242 //____________________________________________________________________________//
|
Chris@16
|
243
|
Chris@16
|
244 #include <boost/test/detail/enable_warnings.hpp>
|
Chris@16
|
245
|
Chris@16
|
246 #endif // BOOST_TEST_UNIT_TEST_MAIN_IPP_012205GER
|