From 567ae61e784383921b57f1fe4884b5f3a333d04e Mon Sep 17 00:00:00 2001
From: Alexander Alekhin <alexander.a.alekhin@gmail.com>
Date: Fri, 23 Feb 2018 09:24:44 +0000
Subject: [PATCH] core: add "check" macros

Backported by Mike Gorse <mgorse@suse.com>
---
diff -urNp opencv-3.3.1.orig/modules/core/include/opencv2/core/base.hpp opencv-3.3.1/modules/core/include/opencv2/core/base.hpp
--- opencv-3.3.1.orig/modules/core/include/opencv2/core/base.hpp	2017-10-23 10:41:12.000000000 -0500
+++ opencv-3.3.1/modules/core/include/opencv2/core/base.hpp	2019-10-16 15:42:15.696481857 -0500
@@ -741,5 +741,6 @@ CV_EXPORTS_W void setUseIPP_NE(bool flag
 
 #include "opencv2/core/neon_utils.hpp"
 #include "opencv2/core/vsx_utils.hpp"
+#include "opencv2/core/check.hpp"
 
 #endif //OPENCV_CORE_BASE_HPP
diff -urNp opencv-3.3.1.orig/modules/core/include/opencv2/core/check.hpp opencv-3.3.1/modules/core/include/opencv2/core/check.hpp
--- opencv-3.3.1.orig/modules/core/include/opencv2/core/check.hpp	1969-12-31 18:00:00.000000000 -0600
+++ opencv-3.3.1/modules/core/include/opencv2/core/check.hpp	2019-10-16 15:42:15.696481857 -0500
@@ -0,0 +1,135 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#ifndef OPENCV_CORE_CHECK_HPP
+#define OPENCV_CORE_CHECK_HPP
+
+#include <opencv2/core/base.hpp>
+
+namespace cv {
+
+/** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or "<invalid depth>" */
+CV_EXPORTS const char* depthToString(int depth);
+
+/** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or "<invalid type>" */
+CV_EXPORTS const String typeToString(int type);
+
+
+//! @cond IGNORED
+namespace detail {
+
+/** Returns string of cv::Mat depth value: CV_8U -> "CV_8U" or NULL */
+CV_EXPORTS const char* depthToString_(int depth);
+
+/** Returns string of cv::Mat depth value: CV_8UC3 -> "CV_8UC3" or cv::String() */
+CV_EXPORTS const cv::String typeToString_(int type);
+
+enum TestOp {
+  TEST_CUSTOM = 0,
+  TEST_EQ = 1,
+  TEST_NE = 2,
+  TEST_LE = 3,
+  TEST_LT = 4,
+  TEST_GE = 5,
+  TEST_GT = 6,
+  CV__LAST_TEST_OP
+};
+
+struct CheckContext {
+    const char* func;
+    const char* file;
+    int line;
+    enum TestOp testOp;
+    const char* message;
+    const char* p1_str;
+    const char* p2_str;
+};
+
+#ifndef CV__CHECK_FILENAME
+# define CV__CHECK_FILENAME __FILE__
+#endif
+
+#ifndef CV__CHECK_FUNCTION
+# if defined _MSC_VER
+#   define CV__CHECK_FUNCTION __FUNCSIG__
+# elif defined __GNUC__
+#   define CV__CHECK_FUNCTION __PRETTY_FUNCTION__
+# else
+#   define CV__CHECK_FUNCTION "<unknown>"
+# endif
+#endif
+
+#define CV__CHECK_LOCATION_VARNAME(id) CVAUX_CONCAT(CVAUX_CONCAT(__cv_check_, id), __LINE__)
+#define CV__DEFINE_CHECK_CONTEXT(id, message, testOp, p1_str, p2_str) \
+    static const cv::detail::CheckContext CV__CHECK_LOCATION_VARNAME(id) = \
+            { CV__CHECK_FUNCTION, CV__CHECK_FILENAME, __LINE__, testOp, message, p1_str, p2_str }
+
+CV_EXPORTS void CV_NORETURN check_failed_auto(const int v1, const int v2, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_auto(const float v1, const float v2, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_auto(const double v1, const double v2, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v1, const int v2, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx);
+
+CV_EXPORTS void CV_NORETURN check_failed_auto(const int v, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_auto(const float v, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_auto(const double v, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_MatDepth(const int v, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_MatType(const int v, const CheckContext& ctx);
+CV_EXPORTS void CV_NORETURN check_failed_MatChannels(const int v, const CheckContext& ctx);
+
+
+#define CV__TEST_EQ(v1, v2) ((v1) == (v2))
+#define CV__TEST_NE(v1, v2) ((v1) != (v2))
+#define CV__TEST_LE(v1, v2) ((v1) <= (v2))
+#define CV__TEST_LT(v1, v2) ((v1) < (v2))
+#define CV__TEST_GE(v1, v2) ((v1) >= (v2))
+#define CV__TEST_GT(v1, v2) ((v1) > (v2))
+
+#define CV__CHECK(id, op, type, v1, v2, v1_str, v2_str, msg_str) do { \
+    if(CV__TEST_##op((v1), (v2))) ; else { \
+        CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_ ## op, v1_str, v2_str); \
+        cv::detail::check_failed_ ## type((v1), (v2), CV__CHECK_LOCATION_VARNAME(id)); \
+    } \
+} while (0)
+
+#define CV__CHECK_CUSTOM_TEST(id, type, v, test_expr, v_str, test_expr_str, msg_str) do { \
+    if(!!(test_expr)) ; else { \
+        CV__DEFINE_CHECK_CONTEXT(id, msg_str, cv::detail::TEST_CUSTOM, v_str, test_expr_str); \
+        cv::detail::check_failed_ ## type((v), CV__CHECK_LOCATION_VARNAME(id)); \
+    } \
+} while (0)
+
+} // namespace
+//! @endcond
+
+
+/// Supported values of these types: int, float, double
+#define CV_CheckEQ(v1, v2, msg)  CV__CHECK(_, EQ, auto, v1, v2, #v1, #v2, msg)
+#define CV_CheckNE(v1, v2, msg)  CV__CHECK(_, NE, auto, v1, v2, #v1, #v2, msg)
+#define CV_CheckLE(v1, v2, msg)  CV__CHECK(_, LE, auto, v1, v2, #v1, #v2, msg)
+#define CV_CheckLT(v1, v2, msg)  CV__CHECK(_, LT, auto, v1, v2, #v1, #v2, msg)
+#define CV_CheckGE(v1, v2, msg)  CV__CHECK(_, GE, auto, v1, v2, #v1, #v2, msg)
+#define CV_CheckGT(v1, v2, msg)  CV__CHECK(_, GT, auto, v1, v2, #v1, #v2, msg)
+
+/// Check with additional "decoding" of type values in error message
+#define CV_CheckTypeEQ(t1, t2, msg)  CV__CHECK(_, EQ, MatType, t1, t2, #t1, #t2, msg)
+/// Check with additional "decoding" of depth values in error message
+#define CV_CheckDepthEQ(d1, d2, msg)  CV__CHECK(_, EQ, MatDepth, d1, d2, #d1, #d2, msg)
+
+#define CV_CheckChannelsEQ(c1, c2, msg)  CV__CHECK(_, EQ, MatChannels, c1, c2, #c1, #c2, msg)
+
+
+/// Example: type == CV_8UC1 || type == CV_8UC3
+#define CV_CheckType(t, test_expr, msg)  CV__CHECK_CUSTOM_TEST(_, MatType, t, (test_expr), #t, #test_expr, msg)
+
+/// Example: depth == CV_32F || depth == CV_64F
+#define CV_CheckDepth(t, test_expr, msg)  CV__CHECK_CUSTOM_TEST(_, MatDepth, t, (test_expr), #t, #test_expr, msg)
+
+/// Some complex conditions: CV_Check(src2, src2.empty() || (src2.type() == src1.type() && src2.size() == src1.size()), "src2 should have same size/type as src1")
+// TODO define pretty-printers: #define CV_Check(v, test_expr, msg)  CV__CHECK_CUSTOM_TEST(_, auto, v, (test_expr), #v, #test_expr, msg)
+
+} // namespace
+
+#endif // OPENCV_CORE_CHECK_HPP
diff -urNp opencv-3.3.1.orig/modules/core/src/check.cpp opencv-3.3.1/modules/core/src/check.cpp
--- opencv-3.3.1.orig/modules/core/src/check.cpp	1969-12-31 18:00:00.000000000 -0600
+++ opencv-3.3.1/modules/core/src/check.cpp	2019-10-16 15:42:15.696481857 -0500
@@ -0,0 +1,160 @@
+// This file is part of OpenCV project.
+// It is subject to the license terms in the LICENSE file found in the top-level directory
+// of this distribution and at http://opencv.org/license.html.
+
+#include "precomp.hpp"
+
+#include "opencv2/core/check.hpp"
+
+namespace cv {
+
+const char* depthToString(int depth)
+{
+    const char* s = detail::depthToString_(depth);
+    return s ? s : "<invalid depth>";
+}
+
+const cv::String typeToString(int type)
+{
+    cv::String s = detail::typeToString_(type);
+    if (s.empty())
+    {
+        static cv::String invalidType("<invalid type>");
+        return invalidType;
+    }
+    return s;
+}
+
+
+namespace detail {
+
+static const char* getTestOpPhraseStr(unsigned testOp)
+{
+    static const char* _names[] = { "{custom check}", "equal to", "not equal to", "less than or equal to", "less than", "greater than or equal to", "greater than" };
+    CV_DbgAssert(testOp < CV__LAST_TEST_OP);
+    return testOp < CV__LAST_TEST_OP ? _names[testOp] : "???";
+}
+static const char* getTestOpMath(unsigned testOp)
+{
+    static const char* _names[] = { "???", "==", "!=", "<=", "<", ">=", ">" };
+    CV_DbgAssert(testOp < CV__LAST_TEST_OP);
+    return testOp < CV__LAST_TEST_OP ? _names[testOp] : "???";
+}
+
+const char* depthToString_(int depth)
+{
+    static const char* depthNames[] = { "CV_8U", "CV_8S", "CV_16U", "CV_16S", "CV_32S", "CV_32F", "CV_64F", "CV_USRTYPE1" };
+    return depth <= CV_USRTYPE1 ? depthNames[depth] : NULL;
+}
+
+const cv::String typeToString_(int type)
+{
+    int depth = CV_MAT_DEPTH(type);
+    int cn = CV_MAT_CN(type);
+    if (depth >= 0 && depth <= CV_USRTYPE1)
+        return cv::format("%sC%d", depthToString_(depth), cn);
+    return cv::String();
+}
+
+template<typename T> static CV_NORETURN
+void check_failed_auto_(const T& v1, const T& v2, const CheckContext& ctx)
+{
+    std::stringstream ss;
+    ss  << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl
+        << "    '" << ctx.p1_str << "' is " << v1 << std::endl;
+    if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP)
+    {
+        ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl;
+    }
+    ss  << "    '" << ctx.p2_str << "' is " << v2;
+    cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
+}
+void check_failed_MatDepth(const int v1, const int v2, const CheckContext& ctx)
+{
+    std::stringstream ss;
+    ss  << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl
+        << "    '" << ctx.p1_str << "' is " << v1 << " (" << depthToString(v1) << ")" << std::endl;
+    if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP)
+    {
+        ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl;
+    }
+    ss  << "    '" << ctx.p2_str << "' is " << v2 << " (" << depthToString(v2) << ")";
+    cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
+}
+void check_failed_MatType(const int v1, const int v2, const CheckContext& ctx)
+{
+    std::stringstream ss;
+    ss  << ctx.message << " (expected: '" << ctx.p1_str << " " << getTestOpMath(ctx.testOp) << " " << ctx.p2_str << "'), where" << std::endl
+        << "    '" << ctx.p1_str << "' is " << v1 << " (" << typeToString(v1) << ")" << std::endl;
+    if (ctx.testOp != TEST_CUSTOM && ctx.testOp < CV__LAST_TEST_OP)
+    {
+        ss << "must be " << getTestOpPhraseStr(ctx.testOp) << std::endl;
+    }
+    ss  << "    '" << ctx.p2_str << "' is " << v2 << " (" << typeToString(v2) << ")";
+    cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
+}
+void check_failed_MatChannels(const int v1, const int v2, const CheckContext& ctx)
+{
+    check_failed_auto_<int>(v1, v2, ctx);
+}
+void check_failed_auto(const int v1, const int v2, const CheckContext& ctx)
+{
+    check_failed_auto_<int>(v1, v2, ctx);
+}
+void check_failed_auto(const float v1, const float v2, const CheckContext& ctx)
+{
+    check_failed_auto_<float>(v1, v2, ctx);
+}
+void check_failed_auto(const double v1, const double v2, const CheckContext& ctx)
+{
+    check_failed_auto_<double>(v1, v2, ctx);
+}
+
+
+template<typename T> static CV_NORETURN
+void check_failed_auto_(const T& v, const CheckContext& ctx)
+{
+    std::stringstream ss;
+    ss  << ctx.message << ":" << std::endl
+        << "    '" << ctx.p2_str << "'" << std::endl
+        << "where" << std::endl
+        << "    '" << ctx.p1_str << "' is " << v;
+    cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
+}
+void check_failed_MatDepth(const int v, const CheckContext& ctx)
+{
+    std::stringstream ss;
+    ss  << ctx.message << ":" << std::endl
+        << "    '" << ctx.p2_str << "'" << std::endl
+        << "where" << std::endl
+        << "    '" << ctx.p1_str << "' is " << v << " (" << depthToString(v) << ")";
+    cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
+}
+void check_failed_MatType(const int v, const CheckContext& ctx)
+{
+    std::stringstream ss;
+    ss  << ctx.message << ":" << std::endl
+        << "    '" << ctx.p2_str << "'" << std::endl
+        << "where" << std::endl
+        << "    '" << ctx.p1_str << "' is " << v << " (" << typeToString(v) << ")";
+    cv::errorNoReturn(cv::Error::StsError, ss.str(), ctx.func, ctx.file, ctx.line);
+}
+void check_failed_MatChannels(const int v, const CheckContext& ctx)
+{
+    check_failed_auto_<int>(v, ctx);
+}
+void check_failed_auto(const int v, const CheckContext& ctx)
+{
+    check_failed_auto_<int>(v, ctx);
+}
+void check_failed_auto(const float v, const CheckContext& ctx)
+{
+    check_failed_auto_<float>(v, ctx);
+}
+void check_failed_auto(const double v, const CheckContext& ctx)
+{
+    check_failed_auto_<double>(v, ctx);
+}
+
+
+}} // namespace
diff -urNp opencv-3.3.1.orig/modules/core/src/system.cpp opencv-3.3.1/modules/core/src/system.cpp
--- opencv-3.3.1.orig/modules/core/src/system.cpp	2017-10-23 10:41:12.000000000 -0500
+++ opencv-3.3.1/modules/core/src/system.cpp	2019-10-16 15:45:50.173618708 -0500
@@ -248,10 +248,34 @@ const char* Exception::what() const thro
 
 void Exception::formatMessage()
 {
-    if( func.size() > 0 )
-        msg = format("%s:%d: error: (%d) %s in function %s\n", file.c_str(), line, code, err.c_str(), func.c_str());
+    size_t pos = err.find('\n');
+    bool multiline = pos != cv::String::npos;
+    if (multiline)
+    {
+        std::stringstream ss;
+        size_t prev_pos = 0;
+        while (pos != cv::String::npos)
+        {
+           ss << "> " << err.substr(prev_pos, pos - prev_pos) << std::endl;
+           prev_pos = pos + 1;
+           pos = err.find('\n', prev_pos);
+        }
+        ss << "> " << err.substr(prev_pos);
+        if (err[err.size() - 1] != '\n')
+            ss << std::endl;
+        err = ss.str();
+    }
+    if (func.size() > 0)
+    {
+        if (multiline)
+            msg = format("OpenCV(%s) %s:%d: error: (%d:%s) in function '%s'\n%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), func.c_str(), err.c_str());
+        else
+            msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s in function '%s'\n", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), func.c_str());
+    }
     else
-        msg = format("%s:%d: error: (%d) %s\n", file.c_str(), line, code, err.c_str());
+    {
+        msg = format("OpenCV(%s) %s:%d: error: (%d:%s) %s%s", CV_VERSION, file.c_str(), line, code, cvErrorStr(code), err.c_str(), multiline ? "" : "\n");
+    }
 }
 
 static const char* g_hwFeatureNames[CV_HARDWARE_MAX_FEATURE] = { NULL };
diff -urNp opencv-3.3.1.orig/modules/core/test/test_misc.cpp opencv-3.3.1/modules/core/test/test_misc.cpp
--- opencv-3.3.1.orig/modules/core/test/test_misc.cpp	2017-10-23 10:41:12.000000000 -0500
+++ opencv-3.3.1/modules/core/test/test_misc.cpp	2019-10-16 15:48:06.830342985 -0500
@@ -154,3 +154,500 @@ TEST(Core_Copy, repeat_regression_8972)
                          repeat(src, 5, 1, src);
                      });
 }
+
+
+//
+// Test core/check.hpp macros
+//
+
+void test_check_eq_1(int value_1, int value_2)
+{
+    CV_CheckEQ(value_1, value_2, "Validation check failed");
+}
+TEST(Core_Check, testEQ_int_fail)
+{
+    try
+    {
+        test_check_eq_1(123, 5678);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation check failed (expected: 'value_1 == value_2'), where\n"
+">     'value_1' is 123\n"
+"> must be equal to\n"
+">     'value_2' is 5678\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testEQ_int_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_eq_1(1234, 1234);
+    });
+}
+
+
+void test_check_eq_2(float value_1, float value_2)
+{
+    CV_CheckEQ(value_1, value_2, "Validation check failed (float)");
+}
+TEST(Core_Check, testEQ_float_fail)
+{
+    try
+    {
+        test_check_eq_2(1234.5f, 1234.55f);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation check failed (float) (expected: 'value_1 == value_2'), where\n"
+">     'value_1' is 1234.5\n"  // TODO Locale handling (use LC_ALL=C on Linux)
+"> must be equal to\n"
+">     'value_2' is 1234.55\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testEQ_float_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_eq_2(1234.6f, 1234.6f);
+    });
+}
+
+
+void test_check_eq_3(double value_1, double value_2)
+{
+    CV_CheckEQ(value_1, value_2, "Validation check failed (double)");
+}
+TEST(Core_Check, testEQ_double_fail)
+{
+    try
+    {
+        test_check_eq_3(1234.5, 1234.56);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation check failed (double) (expected: 'value_1 == value_2'), where\n"
+">     'value_1' is 1234.5\n"  // TODO Locale handling (use LC_ALL=C on Linux)
+"> must be equal to\n"
+">     'value_2' is 1234.56\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testEQ_double_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_eq_3(1234.0f, 1234.0f);
+    });
+}
+
+
+void test_check_ne_1(int value_1, int value_2)
+{
+    CV_CheckNE(value_1, value_2, "Validation NE check failed");
+}
+TEST(Core_Check, testNE_int_fail)
+{
+    try
+    {
+        test_check_ne_1(123, 123);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation NE check failed (expected: 'value_1 != value_2'), where\n"
+">     'value_1' is 123\n"
+"> must be not equal to\n"
+">     'value_2' is 123\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testNE_int_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_ne_1(123, 1234);
+    });
+}
+
+
+void test_check_le_1(int value_1, int value_2)
+{
+    CV_CheckLE(value_1, value_2, "Validation LE check failed");
+}
+TEST(Core_Check, testLE_int_fail)
+{
+    try
+    {
+        test_check_le_1(1234, 123);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation LE check failed (expected: 'value_1 <= value_2'), where\n"
+">     'value_1' is 1234\n"
+"> must be less than or equal to\n"
+">     'value_2' is 123\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testLE_int_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_le_1(1234, 1234);
+    });
+    EXPECT_NO_THROW(
+    {
+        test_check_le_1(123, 1234);
+    });
+}
+
+void test_check_lt_1(int value_1, int value_2)
+{
+    CV_CheckLT(value_1, value_2, "Validation LT check failed");
+}
+TEST(Core_Check, testLT_int_fail)
+{
+    try
+    {
+        test_check_lt_1(1234, 123);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation LT check failed (expected: 'value_1 < value_2'), where\n"
+">     'value_1' is 1234\n"
+"> must be less than\n"
+">     'value_2' is 123\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testLT_int_fail_eq)
+{
+    try
+    {
+        test_check_lt_1(123, 123);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation LT check failed (expected: 'value_1 < value_2'), where\n"
+">     'value_1' is 123\n"
+"> must be less than\n"
+">     'value_2' is 123\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testLT_int_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_lt_1(123, 1234);
+    });
+}
+
+
+void test_check_ge_1(int value_1, int value_2)
+{
+    CV_CheckGE(value_1, value_2, "Validation GE check failed");
+}
+TEST(Core_Check, testGE_int_fail)
+{
+    try
+    {
+        test_check_ge_1(123, 1234);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation GE check failed (expected: 'value_1 >= value_2'), where\n"
+">     'value_1' is 123\n"
+"> must be greater than or equal to\n"
+">     'value_2' is 1234\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testGE_int_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_ge_1(1234, 1234);
+    });
+    EXPECT_NO_THROW(
+    {
+        test_check_ge_1(1234, 123);
+    });
+}
+
+void test_check_gt_1(int value_1, int value_2)
+{
+    CV_CheckGT(value_1, value_2, "Validation GT check failed");
+}
+TEST(Core_Check, testGT_int_fail)
+{
+    try
+    {
+        test_check_gt_1(123, 1234);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation GT check failed (expected: 'value_1 > value_2'), where\n"
+">     'value_1' is 123\n"
+"> must be greater than\n"
+">     'value_2' is 1234\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testGT_int_fail_eq)
+{
+    try
+    {
+        test_check_gt_1(123, 123);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Validation GT check failed (expected: 'value_1 > value_2'), where\n"
+">     'value_1' is 123\n"
+"> must be greater than\n"
+">     'value_2' is 123\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+TEST(Core_Check, testGT_int_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_gt_1(1234, 123);
+    });
+}
+
+
+void test_check_MatType_1(int src_type)
+{
+    CV_CheckTypeEQ(src_type, CV_32FC1, "Unsupported source type");
+}
+TEST(Core_Check, testMatType_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_MatType_1(CV_MAKE_TYPE(CV_32F, 1));
+    });
+}
+TEST(Core_Check, testMatType_fail_1)
+{
+    try
+    {
+        test_check_MatType_1(CV_8UC1);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Unsupported source type (expected: 'src_type == CV_32FC1'), where\n"
+">     'src_type' is 0 (CV_8UC1)\n"
+"> must be equal to\n"
+">     'CV_32FC1' is 5 (CV_32FC1)\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+
+void test_check_MatType_2(int src_type)
+{
+    CV_CheckType(src_type, src_type == CV_32FC1 || src_type == CV_32FC3, "Unsupported src");
+}
+TEST(Core_Check, testMatType_fail_2)
+{
+    try
+    {
+        test_check_MatType_2(CV_8UC1);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Unsupported src:\n"
+">     'src_type == CV_32FC1 || src_type == CV_32FC3'\n"
+"> where\n>     'src_type' is 0 (CV_8UC1)\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+
+void test_check_MatDepth_1(int src_depth)
+{
+    CV_CheckDepthEQ(src_depth, CV_32F, "Unsupported source depth");
+}
+TEST(Core_Check, testMatDepth_pass)
+{
+    EXPECT_NO_THROW(
+    {
+        test_check_MatDepth_1(CV_MAKE_TYPE(CV_32F, 1));
+    });
+}
+TEST(Core_Check, testMatDepth_fail_1)
+{
+    try
+    {
+        test_check_MatDepth_1(CV_8U);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Unsupported source depth (expected: 'src_depth == CV_32F'), where\n"
+">     'src_depth' is 0 (CV_8U)\n"
+"> must be equal to\n"
+">     'CV_32F' is 5 (CV_32F)\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
+
+void test_check_MatDepth_2(int src_depth)
+{
+    CV_CheckDepth(src_depth, src_depth == CV_32F || src_depth == CV_64F, "Unsupported src");
+}
+TEST(Core_Check, testMatDepth_fail_2)
+{
+    try
+    {
+        test_check_MatDepth_2(CV_8U);
+        FAIL() << "Unreachable code called";
+    }
+    catch (const cv::Exception& e)
+    {
+        EXPECT_STREQ(e.err.c_str(),
+"> Unsupported src:\n"
+">     'src_depth == CV_32F || src_depth == CV_64F'\n"
+"> where\n>     'src_depth' is 0 (CV_8U)\n"
+);
+    }
+    catch (const std::exception& e)
+    {
+        FAIL() << "Unexpected C++ exception: " << e.what();
+    }
+    catch (...)
+    {
+        FAIL() << "Unexpected unknown exception";
+    }
+}
