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