Chris@16
|
1 // (C) Copyright Gennadiy Rozental 2005-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 : supplies offline implementation for the Test Tools
|
Chris@16
|
13 // ***************************************************************************
|
Chris@16
|
14
|
Chris@16
|
15 #ifndef BOOST_TEST_TEST_TOOLS_IPP_012205GER
|
Chris@16
|
16 #define BOOST_TEST_TEST_TOOLS_IPP_012205GER
|
Chris@16
|
17
|
Chris@16
|
18 // Boost.Test
|
Chris@16
|
19 #include <boost/test/test_tools.hpp>
|
Chris@16
|
20 #include <boost/test/unit_test_log.hpp>
|
Chris@16
|
21 #include <boost/test/output_test_stream.hpp>
|
Chris@16
|
22 #include <boost/test/framework.hpp>
|
Chris@16
|
23 #include <boost/test/execution_monitor.hpp> // execution_aborted
|
Chris@16
|
24 #include <boost/test/unit_test_suite_impl.hpp>
|
Chris@16
|
25
|
Chris@16
|
26 // Boost
|
Chris@16
|
27 #include <boost/config.hpp>
|
Chris@16
|
28
|
Chris@16
|
29 // STL
|
Chris@16
|
30 #include <fstream>
|
Chris@16
|
31 #include <string>
|
Chris@16
|
32 #include <cstring>
|
Chris@16
|
33 #include <cctype>
|
Chris@16
|
34 #include <cwchar>
|
Chris@16
|
35 #include <stdexcept>
|
Chris@16
|
36 #include <ios>
|
Chris@16
|
37
|
Chris@16
|
38 // !! should we use #include <cstdarg>
|
Chris@16
|
39 #include <stdarg.h>
|
Chris@16
|
40
|
Chris@16
|
41 #include <boost/test/detail/suppress_warnings.hpp>
|
Chris@16
|
42
|
Chris@16
|
43 //____________________________________________________________________________//
|
Chris@16
|
44
|
Chris@16
|
45 # ifdef BOOST_NO_STDC_NAMESPACE
|
Chris@16
|
46 namespace std { using ::strcmp; using ::strlen; using ::isprint; }
|
Chris@16
|
47 #if !defined( BOOST_NO_CWCHAR )
|
Chris@16
|
48 namespace std { using ::wcscmp; }
|
Chris@16
|
49 #endif
|
Chris@16
|
50 # endif
|
Chris@16
|
51
|
Chris@16
|
52 namespace boost {
|
Chris@16
|
53
|
Chris@16
|
54 namespace test_tools {
|
Chris@16
|
55
|
Chris@16
|
56 // ************************************************************************** //
|
Chris@16
|
57 // ************** print_log_value ************** //
|
Chris@16
|
58 // ************************************************************************** //
|
Chris@16
|
59
|
Chris@16
|
60 void
|
Chris@16
|
61 print_log_value<char>::operator()( std::ostream& ostr, char t )
|
Chris@16
|
62 {
|
Chris@16
|
63 if( (std::isprint)( static_cast<unsigned char>(t) ) )
|
Chris@16
|
64 ostr << '\'' << t << '\'';
|
Chris@16
|
65 else
|
Chris@16
|
66 ostr << std::hex
|
Chris@16
|
67 #if BOOST_TEST_USE_STD_LOCALE
|
Chris@16
|
68 << std::showbase
|
Chris@16
|
69 #else
|
Chris@16
|
70 << "0x"
|
Chris@16
|
71 #endif
|
Chris@16
|
72 << static_cast<int>(t);
|
Chris@16
|
73 }
|
Chris@16
|
74
|
Chris@16
|
75 //____________________________________________________________________________//
|
Chris@16
|
76
|
Chris@16
|
77 void
|
Chris@16
|
78 print_log_value<unsigned char>::operator()( std::ostream& ostr, unsigned char t )
|
Chris@16
|
79 {
|
Chris@16
|
80 ostr << std::hex
|
Chris@16
|
81 // showbase is only available for new style streams:
|
Chris@16
|
82 #if BOOST_TEST_USE_STD_LOCALE
|
Chris@16
|
83 << std::showbase
|
Chris@16
|
84 #else
|
Chris@16
|
85 << "0x"
|
Chris@16
|
86 #endif
|
Chris@16
|
87 << static_cast<int>(t);
|
Chris@16
|
88 }
|
Chris@16
|
89
|
Chris@16
|
90 //____________________________________________________________________________//
|
Chris@16
|
91
|
Chris@16
|
92 void
|
Chris@16
|
93 print_log_value<char const*>::operator()( std::ostream& ostr, char const* t )
|
Chris@16
|
94 {
|
Chris@16
|
95 ostr << ( t ? t : "null string" );
|
Chris@16
|
96 }
|
Chris@16
|
97
|
Chris@16
|
98 //____________________________________________________________________________//
|
Chris@16
|
99
|
Chris@16
|
100 void
|
Chris@16
|
101 print_log_value<wchar_t const*>::operator()( std::ostream& ostr, wchar_t const* t )
|
Chris@16
|
102 {
|
Chris@16
|
103 ostr << ( t ? t : L"null string" );
|
Chris@16
|
104 }
|
Chris@16
|
105
|
Chris@16
|
106 //____________________________________________________________________________//
|
Chris@16
|
107
|
Chris@16
|
108 namespace tt_detail {
|
Chris@16
|
109
|
Chris@16
|
110 // ************************************************************************** //
|
Chris@16
|
111 // ************** TOOL BOX Implementation ************** //
|
Chris@16
|
112 // ************************************************************************** //
|
Chris@16
|
113
|
Chris@16
|
114 using ::boost::unit_test::lazy_ostream;
|
Chris@16
|
115
|
Chris@16
|
116 bool
|
Chris@16
|
117 check_impl( predicate_result const& pr, lazy_ostream const& check_descr,
|
Chris@16
|
118 const_string file_name, std::size_t line_num,
|
Chris@16
|
119 tool_level tl, check_type ct,
|
Chris@16
|
120 std::size_t num_of_args, ... )
|
Chris@16
|
121 {
|
Chris@16
|
122 using namespace unit_test;
|
Chris@16
|
123
|
Chris@16
|
124 if( !framework::is_initialized() )
|
Chris@16
|
125 throw std::runtime_error( "can't use testing tools before framework is initialized" );
|
Chris@16
|
126
|
Chris@16
|
127 if( !!pr )
|
Chris@16
|
128 tl = PASS;
|
Chris@16
|
129
|
Chris@16
|
130 log_level ll;
|
Chris@16
|
131 char const* prefix;
|
Chris@16
|
132 char const* suffix;
|
Chris@16
|
133
|
Chris@16
|
134 switch( tl ) {
|
Chris@16
|
135 case PASS:
|
Chris@16
|
136 ll = log_successful_tests;
|
Chris@16
|
137 prefix = "check ";
|
Chris@16
|
138 suffix = " passed";
|
Chris@16
|
139 break;
|
Chris@16
|
140 case WARN:
|
Chris@16
|
141 ll = log_warnings;
|
Chris@16
|
142 prefix = "condition ";
|
Chris@16
|
143 suffix = " is not satisfied";
|
Chris@16
|
144 break;
|
Chris@16
|
145 case CHECK:
|
Chris@16
|
146 ll = log_all_errors;
|
Chris@16
|
147 prefix = "check ";
|
Chris@16
|
148 suffix = " failed";
|
Chris@16
|
149 break;
|
Chris@16
|
150 case REQUIRE:
|
Chris@16
|
151 ll = log_fatal_errors;
|
Chris@16
|
152 prefix = "critical check ";
|
Chris@16
|
153 suffix = " failed";
|
Chris@16
|
154 break;
|
Chris@16
|
155 default:
|
Chris@16
|
156 return true;
|
Chris@16
|
157 }
|
Chris@16
|
158
|
Chris@16
|
159 switch( ct ) {
|
Chris@16
|
160 case CHECK_PRED:
|
Chris@16
|
161 unit_test_log << unit_test::log::begin( file_name, line_num )
|
Chris@16
|
162 << ll << prefix << check_descr << suffix;
|
Chris@16
|
163
|
Chris@16
|
164 if( !pr.has_empty_message() )
|
Chris@16
|
165 unit_test_log << ". " << pr.message();
|
Chris@16
|
166
|
Chris@16
|
167 unit_test_log << unit_test::log::end();
|
Chris@16
|
168 break;
|
Chris@16
|
169
|
Chris@16
|
170 case CHECK_MSG:
|
Chris@16
|
171 unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
|
Chris@16
|
172
|
Chris@16
|
173 if( tl == PASS )
|
Chris@16
|
174 unit_test_log << prefix << "'" << check_descr << "'" << suffix;
|
Chris@16
|
175 else
|
Chris@16
|
176 unit_test_log << check_descr;
|
Chris@16
|
177
|
Chris@16
|
178 if( !pr.has_empty_message() )
|
Chris@16
|
179 unit_test_log << ". " << pr.message();
|
Chris@16
|
180
|
Chris@16
|
181 unit_test_log << unit_test::log::end();
|
Chris@16
|
182 break;
|
Chris@16
|
183
|
Chris@16
|
184 case CHECK_EQUAL:
|
Chris@16
|
185 case CHECK_NE:
|
Chris@16
|
186 case CHECK_LT:
|
Chris@16
|
187 case CHECK_LE:
|
Chris@16
|
188 case CHECK_GT:
|
Chris@16
|
189 case CHECK_GE: {
|
Chris@16
|
190 static char const* check_str [] = { " == ", " != ", " < " , " <= ", " > " , " >= " };
|
Chris@16
|
191 static char const* rever_str [] = { " != ", " == ", " >= ", " > " , " <= ", " < " };
|
Chris@16
|
192
|
Chris@16
|
193 va_list args;
|
Chris@16
|
194
|
Chris@16
|
195 va_start( args, num_of_args );
|
Chris@16
|
196 char const* arg1_descr = va_arg( args, char const* );
|
Chris@16
|
197 lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
198 char const* arg2_descr = va_arg( args, char const* );
|
Chris@16
|
199 lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
200
|
Chris@16
|
201 unit_test_log << unit_test::log::begin( file_name, line_num )
|
Chris@16
|
202 << ll << prefix << arg1_descr << check_str[ct-CHECK_EQUAL] << arg2_descr << suffix;
|
Chris@16
|
203
|
Chris@16
|
204 if( tl != PASS )
|
Chris@16
|
205 unit_test_log << " [" << *arg1_val << rever_str[ct-CHECK_EQUAL] << *arg2_val << "]" ;
|
Chris@16
|
206
|
Chris@16
|
207 va_end( args );
|
Chris@16
|
208
|
Chris@16
|
209 if( !pr.has_empty_message() )
|
Chris@16
|
210 unit_test_log << ". " << pr.message();
|
Chris@16
|
211
|
Chris@16
|
212 unit_test_log << unit_test::log::end();
|
Chris@16
|
213 break;
|
Chris@16
|
214 }
|
Chris@16
|
215
|
Chris@16
|
216 case CHECK_CLOSE:
|
Chris@16
|
217 case CHECK_CLOSE_FRACTION: {
|
Chris@16
|
218 va_list args;
|
Chris@16
|
219
|
Chris@16
|
220 va_start( args, num_of_args );
|
Chris@16
|
221 char const* arg1_descr = va_arg( args, char const* );
|
Chris@16
|
222 lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
223 char const* arg2_descr = va_arg( args, char const* );
|
Chris@16
|
224 lazy_ostream const* arg2_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
225 /* toler_descr = */ va_arg( args, char const* );
|
Chris@16
|
226 lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
227
|
Chris@16
|
228 unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
|
Chris@16
|
229
|
Chris@16
|
230 unit_test_log << "difference{" << pr.message() << (ct == CHECK_CLOSE ? "%" : "")
|
Chris@16
|
231 << "} between " << arg1_descr << "{" << *arg1_val
|
Chris@16
|
232 << "} and " << arg2_descr << "{" << *arg2_val
|
Chris@16
|
233 << ( tl == PASS ? "} doesn't exceed " : "} exceeds " )
|
Chris@16
|
234 << *toler_val;
|
Chris@16
|
235 if( ct == CHECK_CLOSE )
|
Chris@16
|
236 unit_test_log << "%";
|
Chris@16
|
237
|
Chris@16
|
238 va_end( args );
|
Chris@16
|
239
|
Chris@16
|
240 unit_test_log << unit_test::log::end();
|
Chris@16
|
241 break;
|
Chris@16
|
242 }
|
Chris@16
|
243 case CHECK_SMALL: {
|
Chris@16
|
244 va_list args;
|
Chris@16
|
245
|
Chris@16
|
246 va_start( args, num_of_args );
|
Chris@16
|
247 char const* arg1_descr = va_arg( args, char const* );
|
Chris@16
|
248 lazy_ostream const* arg1_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
249 /* toler_descr = */ va_arg( args, char const* );
|
Chris@16
|
250 lazy_ostream const* toler_val = va_arg( args, lazy_ostream const* );
|
Chris@16
|
251
|
Chris@16
|
252 unit_test_log << unit_test::log::begin( file_name, line_num ) << ll;
|
Chris@16
|
253
|
Chris@16
|
254 unit_test_log << "absolute value of " << arg1_descr << "{" << *arg1_val << "}"
|
Chris@16
|
255 << ( tl == PASS ? " doesn't exceed " : " exceeds " )
|
Chris@16
|
256 << *toler_val;
|
Chris@16
|
257
|
Chris@16
|
258 va_end( args );
|
Chris@16
|
259
|
Chris@16
|
260 if( !pr.has_empty_message() )
|
Chris@16
|
261 unit_test_log << ". " << pr.message();
|
Chris@16
|
262
|
Chris@16
|
263 unit_test_log << unit_test::log::end();
|
Chris@16
|
264 break;
|
Chris@16
|
265 }
|
Chris@16
|
266
|
Chris@16
|
267 case CHECK_PRED_WITH_ARGS: {
|
Chris@16
|
268 unit_test_log << unit_test::log::begin( file_name, line_num )
|
Chris@16
|
269 << ll << prefix << check_descr;
|
Chris@16
|
270
|
Chris@16
|
271 // print predicate call description
|
Chris@16
|
272 {
|
Chris@16
|
273 va_list args;
|
Chris@16
|
274 va_start( args, num_of_args );
|
Chris@16
|
275
|
Chris@16
|
276 unit_test_log << "( ";
|
Chris@16
|
277 for( std::size_t i = 0; i < num_of_args; ++i ) {
|
Chris@16
|
278 unit_test_log << va_arg( args, char const* );
|
Chris@16
|
279 va_arg( args, lazy_ostream const* ); // skip argument value;
|
Chris@16
|
280
|
Chris@16
|
281 if( i != num_of_args-1 )
|
Chris@16
|
282 unit_test_log << ", ";
|
Chris@16
|
283 }
|
Chris@16
|
284 unit_test_log << " )" << suffix;
|
Chris@16
|
285 va_end( args );
|
Chris@16
|
286 }
|
Chris@16
|
287
|
Chris@16
|
288 if( tl != PASS ) {
|
Chris@16
|
289 va_list args;
|
Chris@16
|
290 va_start( args, num_of_args );
|
Chris@16
|
291
|
Chris@16
|
292 unit_test_log << " for ( ";
|
Chris@16
|
293 for( std::size_t i = 0; i < num_of_args; ++i ) {
|
Chris@16
|
294 va_arg( args, char const* ); // skip argument description;
|
Chris@16
|
295 unit_test_log << *va_arg( args, lazy_ostream const* );
|
Chris@16
|
296
|
Chris@16
|
297 if( i != num_of_args-1 )
|
Chris@16
|
298 unit_test_log << ", ";
|
Chris@16
|
299 }
|
Chris@16
|
300 unit_test_log << " )";
|
Chris@16
|
301 va_end( args );
|
Chris@16
|
302 }
|
Chris@16
|
303
|
Chris@16
|
304 if( !pr.has_empty_message() )
|
Chris@16
|
305 unit_test_log << ". " << pr.message();
|
Chris@16
|
306
|
Chris@16
|
307 unit_test_log << unit_test::log::end();
|
Chris@16
|
308 break;
|
Chris@16
|
309 }
|
Chris@16
|
310
|
Chris@16
|
311 case CHECK_EQUAL_COLL: {
|
Chris@16
|
312 va_list args;
|
Chris@16
|
313
|
Chris@16
|
314 va_start( args, num_of_args );
|
Chris@16
|
315 char const* left_begin_descr = va_arg( args, char const* );
|
Chris@16
|
316 char const* left_end_descr = va_arg( args, char const* );
|
Chris@16
|
317 char const* right_begin_descr = va_arg( args, char const* );
|
Chris@16
|
318 char const* right_end_descr = va_arg( args, char const* );
|
Chris@16
|
319
|
Chris@16
|
320 unit_test_log << unit_test::log::begin( file_name, line_num )
|
Chris@16
|
321 << ll << prefix
|
Chris@16
|
322 << "{ " << left_begin_descr << ", " << left_end_descr << " } == { "
|
Chris@16
|
323 << right_begin_descr << ", " << right_end_descr << " }"
|
Chris@16
|
324 << suffix;
|
Chris@16
|
325
|
Chris@16
|
326 va_end( args );
|
Chris@16
|
327
|
Chris@16
|
328 if( !pr.has_empty_message() )
|
Chris@16
|
329 unit_test_log << ". " << pr.message();
|
Chris@16
|
330
|
Chris@16
|
331 unit_test_log << unit_test::log::end();
|
Chris@16
|
332 break;
|
Chris@16
|
333 }
|
Chris@16
|
334
|
Chris@16
|
335 case CHECK_BITWISE_EQUAL: {
|
Chris@16
|
336 va_list args;
|
Chris@16
|
337
|
Chris@16
|
338 va_start( args, num_of_args );
|
Chris@16
|
339 char const* left_descr = va_arg( args, char const* );
|
Chris@16
|
340 char const* right_descr = va_arg( args, char const* );
|
Chris@16
|
341
|
Chris@16
|
342 unit_test_log << unit_test::log::begin( file_name, line_num )
|
Chris@16
|
343 << ll << prefix << left_descr << " =.= " << right_descr << suffix;
|
Chris@16
|
344
|
Chris@16
|
345 va_end( args );
|
Chris@16
|
346
|
Chris@16
|
347 if( !pr.has_empty_message() )
|
Chris@16
|
348 unit_test_log << ". " << pr.message();
|
Chris@16
|
349
|
Chris@16
|
350 unit_test_log << unit_test::log::end();
|
Chris@16
|
351 break;
|
Chris@16
|
352 }
|
Chris@16
|
353 }
|
Chris@16
|
354
|
Chris@16
|
355 switch( tl ) {
|
Chris@16
|
356 case PASS:
|
Chris@16
|
357 framework::assertion_result( true );
|
Chris@16
|
358 return true;
|
Chris@16
|
359
|
Chris@16
|
360 case WARN:
|
Chris@16
|
361 return false;
|
Chris@16
|
362
|
Chris@16
|
363 case CHECK:
|
Chris@16
|
364 framework::assertion_result( false );
|
Chris@16
|
365 return false;
|
Chris@16
|
366
|
Chris@16
|
367 case REQUIRE:
|
Chris@16
|
368 framework::assertion_result( false );
|
Chris@16
|
369
|
Chris@16
|
370 framework::test_unit_aborted( framework::current_test_case() );
|
Chris@16
|
371
|
Chris@16
|
372 throw execution_aborted();
|
Chris@16
|
373 }
|
Chris@16
|
374
|
Chris@16
|
375 return true;
|
Chris@16
|
376 }
|
Chris@16
|
377
|
Chris@16
|
378 //____________________________________________________________________________//
|
Chris@16
|
379
|
Chris@16
|
380 predicate_result
|
Chris@16
|
381 equal_impl( char const* left, char const* right )
|
Chris@16
|
382 {
|
Chris@16
|
383 return (left && right) ? std::strcmp( left, right ) == 0 : (left == right);
|
Chris@16
|
384 }
|
Chris@16
|
385
|
Chris@16
|
386 //____________________________________________________________________________//
|
Chris@16
|
387
|
Chris@16
|
388 #if !defined( BOOST_NO_CWCHAR )
|
Chris@16
|
389
|
Chris@16
|
390 predicate_result
|
Chris@16
|
391 equal_impl( wchar_t const* left, wchar_t const* right )
|
Chris@16
|
392 {
|
Chris@16
|
393 return (left && right) ? std::wcscmp( left, right ) == 0 : (left == right);
|
Chris@16
|
394 }
|
Chris@16
|
395
|
Chris@16
|
396 #endif // !defined( BOOST_NO_CWCHAR )
|
Chris@16
|
397
|
Chris@16
|
398 //____________________________________________________________________________//
|
Chris@16
|
399
|
Chris@16
|
400 bool
|
Chris@16
|
401 is_defined_impl( const_string symbol_name, const_string symbol_value )
|
Chris@16
|
402 {
|
Chris@16
|
403 symbol_value.trim_left( 2 );
|
Chris@16
|
404 return symbol_name != symbol_value;
|
Chris@16
|
405 }
|
Chris@16
|
406
|
Chris@16
|
407 //____________________________________________________________________________//
|
Chris@16
|
408
|
Chris@16
|
409 } // namespace tt_detail
|
Chris@16
|
410
|
Chris@16
|
411 // ************************************************************************** //
|
Chris@16
|
412 // ************** output_test_stream ************** //
|
Chris@16
|
413 // ************************************************************************** //
|
Chris@16
|
414
|
Chris@16
|
415 struct output_test_stream::Impl
|
Chris@16
|
416 {
|
Chris@16
|
417 std::fstream m_pattern;
|
Chris@16
|
418 bool m_match_or_save;
|
Chris@16
|
419 bool m_text_or_binary;
|
Chris@16
|
420 std::string m_synced_string;
|
Chris@16
|
421
|
Chris@16
|
422 char get_char()
|
Chris@16
|
423 {
|
Chris@16
|
424 char res;
|
Chris@16
|
425 do {
|
Chris@16
|
426 m_pattern.get( res );
|
Chris@16
|
427 } while( m_text_or_binary && res == '\r' && !m_pattern.fail() && !m_pattern.eof() );
|
Chris@16
|
428
|
Chris@16
|
429 return res;
|
Chris@16
|
430 }
|
Chris@16
|
431
|
Chris@16
|
432 void check_and_fill( predicate_result& res )
|
Chris@16
|
433 {
|
Chris@16
|
434 if( !res.p_predicate_value )
|
Chris@16
|
435 res.message() << "Output content: \"" << m_synced_string << '\"';
|
Chris@16
|
436 }
|
Chris@16
|
437 };
|
Chris@16
|
438
|
Chris@16
|
439 //____________________________________________________________________________//
|
Chris@16
|
440
|
Chris@16
|
441 output_test_stream::output_test_stream( const_string pattern_file_name, bool match_or_save, bool text_or_binary )
|
Chris@16
|
442 : m_pimpl( new Impl )
|
Chris@16
|
443 {
|
Chris@16
|
444 if( !pattern_file_name.is_empty() ) {
|
Chris@16
|
445 std::ios::openmode m = match_or_save ? std::ios::in : std::ios::out;
|
Chris@16
|
446 if( !text_or_binary )
|
Chris@16
|
447 m |= std::ios::binary;
|
Chris@16
|
448
|
Chris@16
|
449 m_pimpl->m_pattern.open( pattern_file_name.begin(), m );
|
Chris@16
|
450
|
Chris@16
|
451 BOOST_WARN_MESSAGE( m_pimpl->m_pattern.is_open(),
|
Chris@16
|
452 "Can't open pattern file " << pattern_file_name
|
Chris@16
|
453 << " for " << (match_or_save ? "reading" : "writing") );
|
Chris@16
|
454 }
|
Chris@16
|
455
|
Chris@16
|
456 m_pimpl->m_match_or_save = match_or_save;
|
Chris@16
|
457 m_pimpl->m_text_or_binary = text_or_binary;
|
Chris@16
|
458 }
|
Chris@16
|
459
|
Chris@16
|
460 //____________________________________________________________________________//
|
Chris@16
|
461
|
Chris@16
|
462 output_test_stream::~output_test_stream()
|
Chris@16
|
463 {
|
Chris@16
|
464 delete m_pimpl;
|
Chris@16
|
465 }
|
Chris@16
|
466
|
Chris@16
|
467 //____________________________________________________________________________//
|
Chris@16
|
468
|
Chris@16
|
469 predicate_result
|
Chris@16
|
470 output_test_stream::is_empty( bool flush_stream )
|
Chris@16
|
471 {
|
Chris@16
|
472 sync();
|
Chris@16
|
473
|
Chris@16
|
474 result_type res( m_pimpl->m_synced_string.empty() );
|
Chris@16
|
475
|
Chris@16
|
476 m_pimpl->check_and_fill( res );
|
Chris@16
|
477
|
Chris@16
|
478 if( flush_stream )
|
Chris@16
|
479 flush();
|
Chris@16
|
480
|
Chris@16
|
481 return res;
|
Chris@16
|
482 }
|
Chris@16
|
483
|
Chris@16
|
484 //____________________________________________________________________________//
|
Chris@16
|
485
|
Chris@16
|
486 predicate_result
|
Chris@16
|
487 output_test_stream::check_length( std::size_t length_, bool flush_stream )
|
Chris@16
|
488 {
|
Chris@16
|
489 sync();
|
Chris@16
|
490
|
Chris@16
|
491 result_type res( m_pimpl->m_synced_string.length() == length_ );
|
Chris@16
|
492
|
Chris@16
|
493 m_pimpl->check_and_fill( res );
|
Chris@16
|
494
|
Chris@16
|
495 if( flush_stream )
|
Chris@16
|
496 flush();
|
Chris@16
|
497
|
Chris@16
|
498 return res;
|
Chris@16
|
499 }
|
Chris@16
|
500
|
Chris@16
|
501 //____________________________________________________________________________//
|
Chris@16
|
502
|
Chris@16
|
503 predicate_result
|
Chris@16
|
504 output_test_stream::is_equal( const_string arg, bool flush_stream )
|
Chris@16
|
505 {
|
Chris@16
|
506 sync();
|
Chris@16
|
507
|
Chris@16
|
508 result_type res( const_string( m_pimpl->m_synced_string ) == arg );
|
Chris@16
|
509
|
Chris@16
|
510 m_pimpl->check_and_fill( res );
|
Chris@16
|
511
|
Chris@16
|
512 if( flush_stream )
|
Chris@16
|
513 flush();
|
Chris@16
|
514
|
Chris@16
|
515 return res;
|
Chris@16
|
516 }
|
Chris@16
|
517
|
Chris@16
|
518 //____________________________________________________________________________//
|
Chris@16
|
519
|
Chris@16
|
520 predicate_result
|
Chris@16
|
521 output_test_stream::match_pattern( bool flush_stream )
|
Chris@16
|
522 {
|
Chris@16
|
523 sync();
|
Chris@16
|
524
|
Chris@16
|
525 result_type result( true );
|
Chris@16
|
526
|
Chris@16
|
527 if( !m_pimpl->m_pattern.is_open() ) {
|
Chris@16
|
528 result = false;
|
Chris@16
|
529 result.message() << "Pattern file can't be opened!";
|
Chris@16
|
530 }
|
Chris@16
|
531 else {
|
Chris@16
|
532 if( m_pimpl->m_match_or_save ) {
|
Chris@16
|
533 for ( std::string::size_type i = 0; i < m_pimpl->m_synced_string.length(); ++i ) {
|
Chris@16
|
534 char c = m_pimpl->get_char();
|
Chris@16
|
535
|
Chris@16
|
536 result = !m_pimpl->m_pattern.fail() &&
|
Chris@16
|
537 !m_pimpl->m_pattern.eof() &&
|
Chris@16
|
538 (m_pimpl->m_synced_string[i] == c);
|
Chris@16
|
539
|
Chris@16
|
540 if( !result ) {
|
Chris@16
|
541 std::string::size_type suffix_size = (std::min)( m_pimpl->m_synced_string.length() - i,
|
Chris@16
|
542 static_cast<std::string::size_type>(5) );
|
Chris@16
|
543
|
Chris@16
|
544 // try to log area around the mismatch
|
Chris@16
|
545 result.message() << "Mismatch at position " << i << '\n'
|
Chris@16
|
546 << "..." << m_pimpl->m_synced_string.substr( i, suffix_size ) << "..." << '\n'
|
Chris@16
|
547 << "..." << c;
|
Chris@16
|
548
|
Chris@16
|
549 std::string::size_type counter = suffix_size;
|
Chris@16
|
550 while( --counter ) {
|
Chris@16
|
551 char c = m_pimpl->get_char();
|
Chris@16
|
552
|
Chris@16
|
553 if( m_pimpl->m_pattern.fail() || m_pimpl->m_pattern.eof() )
|
Chris@16
|
554 break;
|
Chris@16
|
555
|
Chris@16
|
556 result.message() << c;
|
Chris@16
|
557 }
|
Chris@16
|
558
|
Chris@16
|
559 result.message() << "...";
|
Chris@16
|
560
|
Chris@16
|
561 // skip rest of the bytes. May help for further matching
|
Chris@16
|
562 m_pimpl->m_pattern.ignore(
|
Chris@16
|
563 static_cast<std::streamsize>( m_pimpl->m_synced_string.length() - i - suffix_size) );
|
Chris@16
|
564 break;
|
Chris@16
|
565 }
|
Chris@16
|
566 }
|
Chris@16
|
567 }
|
Chris@16
|
568 else {
|
Chris@16
|
569 m_pimpl->m_pattern.write( m_pimpl->m_synced_string.c_str(),
|
Chris@16
|
570 static_cast<std::streamsize>( m_pimpl->m_synced_string.length() ) );
|
Chris@16
|
571 m_pimpl->m_pattern.flush();
|
Chris@16
|
572 }
|
Chris@16
|
573 }
|
Chris@16
|
574
|
Chris@16
|
575 if( flush_stream )
|
Chris@16
|
576 flush();
|
Chris@16
|
577
|
Chris@16
|
578 return result;
|
Chris@16
|
579 }
|
Chris@16
|
580
|
Chris@16
|
581 //____________________________________________________________________________//
|
Chris@16
|
582
|
Chris@16
|
583 void
|
Chris@16
|
584 output_test_stream::flush()
|
Chris@16
|
585 {
|
Chris@16
|
586 m_pimpl->m_synced_string.erase();
|
Chris@16
|
587
|
Chris@16
|
588 #ifndef BOOST_NO_STRINGSTREAM
|
Chris@16
|
589 str( std::string() );
|
Chris@16
|
590 #else
|
Chris@16
|
591 seekp( 0, std::ios::beg );
|
Chris@16
|
592 #endif
|
Chris@16
|
593 }
|
Chris@16
|
594
|
Chris@16
|
595 //____________________________________________________________________________//
|
Chris@16
|
596
|
Chris@16
|
597 std::size_t
|
Chris@16
|
598 output_test_stream::length()
|
Chris@16
|
599 {
|
Chris@16
|
600 sync();
|
Chris@16
|
601
|
Chris@16
|
602 return m_pimpl->m_synced_string.length();
|
Chris@16
|
603 }
|
Chris@16
|
604
|
Chris@16
|
605 //____________________________________________________________________________//
|
Chris@16
|
606
|
Chris@16
|
607 void
|
Chris@16
|
608 output_test_stream::sync()
|
Chris@16
|
609 {
|
Chris@16
|
610 #ifdef BOOST_NO_STRINGSTREAM
|
Chris@16
|
611 m_pimpl->m_synced_string.assign( str(), pcount() );
|
Chris@16
|
612 freeze( false );
|
Chris@16
|
613 #else
|
Chris@16
|
614 m_pimpl->m_synced_string = str();
|
Chris@16
|
615 #endif
|
Chris@16
|
616 }
|
Chris@16
|
617
|
Chris@16
|
618 //____________________________________________________________________________//
|
Chris@16
|
619
|
Chris@16
|
620 } // namespace test_tools
|
Chris@16
|
621
|
Chris@16
|
622 } // namespace boost
|
Chris@16
|
623
|
Chris@16
|
624 //____________________________________________________________________________//
|
Chris@16
|
625
|
Chris@16
|
626 #include <boost/test/detail/enable_warnings.hpp>
|
Chris@16
|
627
|
Chris@16
|
628 #endif // BOOST_TEST_TEST_TOOLS_IPP_012205GER
|