42 #ifndef TEUCHOS_TESTING_HELPERS_HPP 43 #define TEUCHOS_TESTING_HELPERS_HPP 54 #include "Teuchos_FancyOStream.hpp" 71 inline const std::string
passfail(
const bool result);
78 TEUCHOSCORE_LIB_DLL_EXPORT
const std::string
passfail_with_location(
const bool result,
const std::string &file,
const int lineNumber);
98 template <
bool hasMachineParameters,
class Scalar>
101 static Scalar smallNumber()
112 template <
class Scalar>
115 static Scalar smallNumber()
126 template <
class Scalar>
129 static Scalar smallNumber()
140 template <
class Scalar>
154 template <
class Scalar>
156 relErr(
const Scalar &s1,
const Scalar &s2 );
165 template<
class Scalar>
167 const std::string &v1_name,
169 const std::string &v2_name,
171 const std::string &maxRelErr_error_name,
173 const std::string &maxRelErr_warning_name,
175 const Ptr<std::ostream> &out
190 template<
class Array1,
class Array2>
192 const Array1 &a1,
const std::string &a1_name,
193 const Array2 &a2,
const std::string &a2_name,
210 template<
class Array1,
class Array2,
class ScalarMag>
212 const Array1 &a1,
const std::string &a1_name,
213 const Array2 &a2,
const std::string &a2_name,
214 const ScalarMag &tol,
230 #define TEUCHOS_PASS_FAIL(RESULT) \ 231 Teuchos::passfail_with_location((RESULT), __FILE__, __LINE__) 240 #define TEUCHOS_ECHO( statement, out ) \ 241 (out) << #statement ";\n"; \ 250 #define TEUCHOS_TEST_EQUALITY_CONST( v1, v2, out, success ) \ 252 (out) << #v1" = "<<Teuchos::toString(v1)<<" == "<<Teuchos::toString(v2)<<" : "; \ 253 const bool l_result = (v1) == (v2); \ 254 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 255 if (!l_result) (success) = false; \ 264 #define TEUCHOS_TEST_ASSERT( v1, out, success ) \ 266 const bool l_result = v1; \ 267 (out) << #v1" = "<<l_result<<" == true : "; \ 268 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 269 if (!l_result) (success) = false; \ 278 #define TEUCHOS_TEST_EQUALITY( v1, v2, out, success ) \ 280 (out) << #v1" = "<<Teuchos::toString(v1)<<" == "#v2" = "<<Teuchos::toString(v2)<<" : "; \ 281 const bool l_result = (v1) == (v2); \ 282 if (!l_result) (success) = false; \ 283 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 293 #define TEUCHOS_TEST_INEQUALITY_CONST( v1, v2, out, success ) \ 295 (out) << #v1" = "<<Teuchos::toString(v1)<<" != "<<Teuchos::toString(v2)<<" : "; \ 296 const bool l_result = (v1) != (v2); \ 297 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 298 if (!l_result) (success) = false; \ 308 #define TEUCHOS_TEST_INEQUALITY( v1, v2, out, success ) \ 310 (out) << #v1" = "<<Teuchos::toString(v1)<<" != "#v2" = "<<Teuchos::toString(v2)<<" : "; \ 311 const bool l_result = (v1) != (v2); \ 312 if (!l_result) (success) = false; \ 313 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 323 #define TEUCHOS_TEST_FLOATING_EQUALITY( v1, v2, tol, out, success ) \ 325 const bool l_result = Teuchos::testRelErr( \ 326 #v1, v1, #v2, v2, "tol", tol, "tol", tol, Teuchos::outArg(out) ); \ 327 if (!l_result) (success) = false; \ 340 #define TEUCHOS_TEST_ITER_EQUALITY( iter1, iter2, out, success ) \ 342 (out) << #iter1" == "#iter2" = : "; \ 343 const bool l_result = (iter1) == (iter2); \ 344 if (!l_result) (success) = false; \ 345 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 358 #define TEUCHOS_TEST_ITER_INEQUALITY( iter1, iter2, out, success ) \ 360 (out) << #iter1" != "#iter2" = : "; \ 361 const bool l_result = (iter1) != (iter2); \ 362 if (!l_result) (success) = false; \ 363 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 373 #define TEUCHOS_TEST_ARRAY_ELE_EQUALITY( a, i, val, printPass, out, success ) \ 375 const bool l_result = ( (a)[i] == (val) ); \ 376 if (!l_result) (success) = false; \ 377 if (printPass || !(l_result)) { \ 378 out << #a"["<<i<<"] = " << Teuchos::toString((a)[i]) << " == "#val" = " << Teuchos::toString(val) \ 379 << " : " << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 390 #define TEUCHOS_TEST_ARRAY_ELE_INEQUALITY( a, i, val, printPass, out, success ) \ 392 const bool l_result = ( (a)[i] != (val) ); \ 393 if (!l_result) (success) = false; \ 394 if (printPass || !(l_result)) { \ 395 out << #a"["<<i<<"] = " << Teuchos::toString((a)[i]) << " != "#val" = " << Teuchos::toString(val) \ 396 << " : " << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 408 #define TEUCHOS_TEST_MATRIX_ELE_FLOATING_EQUALITY( a, i, j, val, tol, printPass, out, success ) \ 410 std::ostringstream a_i_str; \ 411 a_i_str <<#a<<"("<<i<<","<<j<<")"; \ 412 const bool l_result = Teuchos::testRelErr( \ 413 a_i_str.str(), (a)(i,j), #val, val, "tol", tol, "tol", tol, \ 414 (printPass) ? Teuchos::outArg(out) : Teuchos::null ); \ 415 if (!l_result) (success) = false; \ 425 #define TEUCHOS_TEST_MATRIX_ELE_EQUALITY( a, i, j, val, printPass, out, success ) \ 427 const bool l_result = ( (a)(i,j) == (val) ); \ 428 if (!l_result) (success) = false; \ 429 if (printPass || !(l_result)) { \ 430 out << #a"("<<i<<","<<j<<") = " << (a)(i,j) << " == "#val" = " << (val) \ 431 << " : " << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 445 #define TEUCHOS_TEST_COMPARE( v1, comp, v2, out, success ) \ 447 out << #v1" = "<<(v1)<<" "#comp" "#v2" = "<<(v2)<<" : "; \ 448 const bool l_result = (v1) comp (v2); \ 449 if (!l_result) (success) = false; \ 450 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 464 #define TEUCHOS_TEST_COMPARE_CONST( v1, comp, v2, out, success ) \ 466 out << #v1" = "<<(v1)<<" "#comp" "<<(v2)<<" : "; \ 467 const bool l_result = (v1) comp (v2); \ 468 if (!l_result) (success) = false; \ 469 (out) << TEUCHOS_PASS_FAIL(l_result) << "\n"; \ 487 #define TEUCHOS_TEST_THROW( code, ExceptType, out, success ) \ 489 std::ostream& l_out = (out); \ 491 l_out << "Test that code {"#code";} throws " \ 492 << Teuchos::TypeNameTraits<ExceptType>::name () << ": "; \ 495 l_out << "failed (code did not throw an exception at all)\n"; \ 497 catch (const ExceptType& except) { \ 498 l_out << "passed\n"; \ 499 l_out << "\nException message for expected exception:\n\n"; \ 501 Teuchos::OSTab l_tab (out); \ 502 l_out << except.what () << "\n\n"; \ 505 catch (std::exception& except) { \ 506 l_out << "The code was supposed to throw an exception of type " \ 507 << Teuchos::TypeNameTraits<ExceptType>::name () << ", but " \ 508 << "instead threw an exception of type " \ 509 << typeid (except).name () << ", which is a subclass of " \ 510 << "std::exception. The exception's message is:\n\n"; \ 512 Teuchos::OSTab l_tab (out); \ 513 l_out << except.what () << "\n\n"; \ 515 l_out << "failed\n"; \ 518 l_out << "The code was supposed to throw an exception of type " \ 519 << Teuchos::TypeNameTraits<ExceptType>::name () << ", but " \ 520 << "instead threw an exception of some unknown type, which is " \ 521 << "not a subclass of std::exception. This means we cannot " \ 522 << "show you the exception's message, if it even has one.\n\n"; \ 523 l_out << "failed\n"; \ 534 #define TEUCHOS_TEST_NOTHROW( code, out, success ) \ 536 std::ostream& l_out = (out); \ 538 l_out << "Test that code {"#code";} does not throw : "; \ 540 l_out << "passed\n"; \ 542 catch (std::exception& except) { \ 544 l_out << "The code was not supposed to throw an exception, but " \ 545 << "instead threw an exception of type " \ 546 << typeid (except).name () << ", which is a subclass of " \ 547 << "std::exception. The exception's message is:\n\n"; \ 549 Teuchos::OSTab l_tab (out); \ 550 l_out << except.what () << "\n\n"; \ 552 l_out << "failed\n"; \ 556 l_out << "The code was not supposed to throw an exception, but " \ 557 << "instead threw an exception of some unknown type, which is " \ 558 << "not a subclass of std::exception. This means we cannot " \ 559 << "show you the exception's message, if it even has one.\n\n"; \ 560 l_out << "failed\n"; \ 572 if (!result) success =
false;
586 template <
class Scalar>
592 ST::magnitude( s1 - s2 )
595 RelErrSmallNumber<ST::hasMachineParameters,Scalar>::smallNumber()
597 + std::max( ST::magnitude(s1), ST::magnitude(s2) )
602 template<
class Scalar>
604 const std::string &v1_name,
606 const std::string &v2_name,
608 const std::string &maxRelErr_error_name,
610 const std::string &maxRelErr_warning_name,
617 typedef typename ST::magnitudeType ScalarMag;
619 const ScalarMag rel_err =
relErr( v1, v2 );
620 const bool success = ( !SMT::isnaninf(rel_err) && !SMT::isnaninf(maxRelErr_error)
621 && rel_err <= maxRelErr_error );
625 <<
"Check: rel_err(" << v1_name <<
", " << v2_name <<
")\n" 626 <<
" = rel_err(" << v1 <<
", " << v2 <<
") " 627 <<
"= " << rel_err << endl
628 <<
" <= " << maxRelErr_error_name
629 <<
" = " << maxRelErr_error <<
" : " <<
passfail(success) << endl;
630 if( success && rel_err >= maxRelErr_warning ) {
632 <<
"Warning! rel_err(" << v1_name <<
", " << v2_name <<
")\n" 633 <<
" = rel_err(" << v1 <<
", " << v2 <<
") " 634 <<
"= " << rel_err << endl
635 <<
" >= " << maxRelErr_warning_name
636 <<
" = " << maxRelErr_warning <<
"!\n";
643 template<
class Array1,
class Array2>
645 const Array1 &a1,
const std::string &a1_name,
646 const Array2 &a2,
const std::string &a2_name,
653 out <<
"Comparing " << a1_name <<
" == " << a2_name <<
" ... ";
655 const int n = a1.size();
658 if (as<int>(a2.size()) != n) {
659 out <<
"\nError, "<<a1_name<<
".size() = "<<a1.size()<<
" == " 660 << a2_name<<
".size() = "<<a2.size()<<
" : failed!\n";
665 for(
int i = 0; i < n; ++i ) {
666 const bool result = ( a1[i] == a2[i] );
668 out <<
"\nError, "<<a1_name<<
"["<<i<<
"] = "<<a1[i]<<
" == " 669 << a2_name<<
"["<<i<<
"] = "<<a2[i]<<
": failed!\n";
682 template<
class Array1,
class Array2,
class ScalarMag>
684 const Array1 &a1,
const std::string &a1_name,
685 const Array2 &a2,
const std::string &a2_name,
686 const ScalarMag &tol,
693 out <<
"Comparing " << a1_name <<
" == " << a2_name <<
" ... ";
695 const int n = a1.size();
698 if (as<int>(a2.size()) != n) {
699 out <<
"\nError, "<<a1_name<<
".size() = "<<a1.size()<<
" == " 700 << a2_name<<
".size() = "<<a2.size()<<
" : failed!\n";
705 for(
int i = 0; i < n; ++i ) {
706 const ScalarMag err =
relErr( a1[i], a2[i] );
707 if ( !(err <= tol) ) {
709 <<
"\nError, relErr("<<a1_name<<
"["<<i<<
"]," 710 <<a2_name<<
"["<<i<<
"]) = relErr("<<a1[i]<<
","<<a2[i]<<
") = " 711 <<err<<
" <= tol = "<<tol<<
": failed!\n";
724 #endif // TEUCHOS_TESTING_HELPERS_HPP bool compareFloatingArrays(const Array1 &a1, const std::string &a1_name, const Array2 &a2, const std::string &a2_name, const ScalarMag &tol, Teuchos::FancyOStream &out)
Compare if two array objects are the same or not up to a relative floating point precision.
T magnitudeType
Mandatory typedef for result of magnitude.
static magnitudeType eps()
Returns relative machine precision.
bool compareArrays(const Array1 &a1, const std::string &a1_name, const Array2 &a2, const std::string &a2_name, Teuchos::FancyOStream &out)
Compare if two array objects are the same or not.
TEUCHOSCORE_LIB_DLL_EXPORT const std::string passfail_with_location(const bool result, const std::string &file, const int lineNumber)
Helper function for TEUCHOS_PASS_FAIL(...).
const std::string passfail(const bool result)
Return "passed" or "failed".
Teuchos header file which uses auto-configuration information to include necessary C++ headers...
bool is_null(const ArrayRCP< T > &p)
Returns true if p.get()==NULL.
This structure defines some basic traits for a scalar field type.
Scalar defaultSmallNumber()
void showTestFailureLocation(bool)
Set if TEUCHOS_PASS_FAIL(...) should print test failure location.
std::ostream subclass that performs the magic of indenting data sent to an std::ostream object among ...
ScalarTraits< Scalar >::magnitudeType relErr(const Scalar &s1, const Scalar &s2)
Return relative error of two scalars.
void updateSuccess(const bool result, bool &success)
Update the success bool flag.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos, as well as a number of utility routines.
TypeTo as(const TypeFrom &t)
Convert from one value type to another.
Defines basic traits for the scalar field type.
bool testRelErr(const std::string &v1_name, const Scalar &v1, const std::string &v2_name, const Scalar &v2, const std::string &maxRelErr_error_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &maxRelErr_error, const std::string &maxRelErr_warning_name, const typename Teuchos::ScalarTraits< Scalar >::magnitudeType &maxRelErr_warning, const Ptr< std::ostream > &out)
Compute, check and optionally print the relative error in two scalars.
Defines basic traits returning the name of a type in a portable and readable way. ...
Simple wrapper class for raw pointers to single objects where no persisting relationship exists...