12 #if defined(TUT_USE_SEH)
50 std::logic_error(grp){};
69 std::logic_error(msg){};
78 failure(
const std::string& msg) : std::logic_error(msg){};
87 warning(
const std::string& msg) : std::logic_error(msg){};
93 class seh :
public std::logic_error
96 seh(
const std::string& msg) : std::logic_error(msg){};
154 const std::exception&
ex)
170 virtual void rewind() = 0;
231 typedef std::map<std::string,group_base*>
groups;
254 throw std::invalid_argument(
"group shall be non-null");
260 std::string msg(
"attempt to add already existent group "+name);
262 std::cerr << msg << std::endl;
263 throw std::logic_error(msg);
295 ret.push_back(i->first);
316 run_all_tests_in_group_(i);
346 run_all_tests_in_group_(i);
425 extern test_runner_singleton
runner;
432 template <
class Data>
468 if( !cond )
throw failure(
"");
476 void ensure(
const T msg,
bool cond)
478 if( !cond )
throw failure(msg);
488 template <
class T,
class Q>
491 if( expected != actual )
493 std::stringstream ss;
494 ss << (msg?msg:
"") << (msg?
": ":
"") <<
"expected " << expected <<
" actual " <<
actual;
495 throw failure(ss.str().c_str());
499 template <
class T,
class Q>
502 ensure_equals<>(0,
actual,expected);
515 void ensure_distance(
const char* msg,
const T& actual,
const T& expected,
const T& distance)
517 if( expected-distance >= actual || expected+distance <= actual )
519 std::stringstream ss;
520 ss << (msg?msg:
"") << (msg?
": ":
"") <<
"expected [" << expected-distance <<
";"
521 << expected+distance <<
"] actual " <<
actual;
522 throw failure(ss.str().c_str());
527 void ensure_distance(
const T& actual,
const T& expected,
const T& distance)
529 ensure_distance<>(0,
actual,expected,distance);
535 void fail(
const char* msg=
"")
545 template <
class Test,
class Group,
int n>
548 static void reg(Group& group)
550 group.reg(n,&Test::template test<n>);
555 template<
class Test,
class Group>
558 static void reg(Group&){};
566 template <
class Data,
int MaxTestsInGroup = 50>
572 typedef std::map<int,testmethod> tests;
574 typedef typename tests::const_iterator tests_const_iterator;
575 typedef typename tests::const_reverse_iterator
576 tests_const_reverse_iterator;
577 typedef typename tests::size_type size_type;
580 tests_iterator current_test_;
589 bool permit_throw_in_dtor;
591 safe_holder(
const safe_holder&);
592 safe_holder& operator = (
const safe_holder&);
595 safe_holder() : p_(0),permit_throw_in_dtor(
false)
604 T* operator -> ()
const {
return p_; };
605 T*
get()
const {
return p_; };
612 void permit_throw(){ permit_throw_in_dtor =
true; }
624 if( delete_obj() ==
false )
626 throw warning(
"destructor of test object raised an SEH exception");
629 catch(
const std::exception& ex )
631 if( permit_throw_in_dtor )
633 std::string msg =
"destructor of test object raised exception: ";
640 if( permit_throw_in_dtor )
642 throw warning(
"destructor of test object raised an exception");
653 permit_throw_in_dtor =
false;
659 #if defined(TUT_USE_SEH)
666 #if defined(TUT_USE_SEH)
668 __except(handle_seh_(::GetExceptionCode()))
670 if( permit_throw_in_dtor )
713 void reg(
int n,testmethod tm)
723 current_test_ = tests_.begin();
731 if( current_test_ == tests_.end() )
737 safe_holder<object> obj;
738 while( current_test_ != tests_.end() )
742 return run_test_(current_test_++,obj);
763 tests_iterator ti = tests_.find(n);
766 safe_holder<object> obj;
767 return run_test_(ti,obj);
775 test_result run_test_(
const tests_iterator& ti,safe_holder<object>& obj)
779 if( run_test_seh_(ti->second,obj) ==
false )
782 catch(
const no_such_test&)
786 catch(
const warning& ex)
792 catch(
const failure& ex)
804 catch(
const bad_ctor& ex)
810 catch(
const std::exception& ex)
831 bool run_test_seh_(testmethod tm,safe_holder<object>& obj)
833 #if defined(TUT_USE_SEH)
841 obj->called_method_was_a_dummy_test_ =
false;
843 #if defined(TUT_USE_SEH)
848 #if defined(TUT_USE_SEH)
850 __except(handle_seh_(::GetExceptionCode()))
857 if( obj->called_method_was_a_dummy_test_ )
860 throw no_such_test();
865 #if defined(TUT_USE_SEH)
867 __except(handle_seh_(::GetExceptionCode()))
875 void reset_holder_(safe_holder<object>& obj)
881 catch(
const std::exception& ex)
883 throw bad_ctor(ex.what());
887 throw bad_ctor(
"test constructor has generated an exception; group execution is terminated");
892 #if defined(TUT_USE_SEH)
896 inline int handle_seh_(DWORD excode)
900 case EXCEPTION_ACCESS_VIOLATION:
901 case EXCEPTION_DATATYPE_MISALIGNMENT:
902 case EXCEPTION_BREAKPOINT:
903 case EXCEPTION_SINGLE_STEP:
904 case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
905 case EXCEPTION_FLT_DENORMAL_OPERAND:
906 case EXCEPTION_FLT_DIVIDE_BY_ZERO:
907 case EXCEPTION_FLT_INEXACT_RESULT:
908 case EXCEPTION_FLT_INVALID_OPERATION:
909 case EXCEPTION_FLT_OVERFLOW:
910 case EXCEPTION_FLT_STACK_CHECK:
911 case EXCEPTION_FLT_UNDERFLOW:
912 case EXCEPTION_INT_DIVIDE_BY_ZERO:
913 case EXCEPTION_INT_OVERFLOW:
914 case EXCEPTION_PRIV_INSTRUCTION:
915 case EXCEPTION_IN_PAGE_ERROR:
916 case EXCEPTION_ILLEGAL_INSTRUCTION:
917 case EXCEPTION_NONCONTINUABLE_EXCEPTION:
918 case EXCEPTION_STACK_OVERFLOW:
919 case EXCEPTION_INVALID_DISPOSITION:
920 case EXCEPTION_GUARD_PAGE:
921 case EXCEPTION_INVALID_HANDLE:
922 return EXCEPTION_EXECUTE_HANDLER;
925 return EXCEPTION_CONTINUE_SEARCH;