test: add a macro to compare two doubles with a specific epsilon
authorPeter Hutterer <peter.hutterer@who-t.net>
Mon, 16 Sep 2024 06:05:11 +0000 (16:05 +1000)
committerPeter Hutterer <peter.hutterer@who-t.net>
Tue, 15 Oct 2024 02:44:27 +0000 (12:44 +1000)
Same as ck_assert_double_tol

Part-of: <https://gitlab.freedesktop.org/libinput/libinput/-/merge_requests/1059>

test/litest-selftest.c
test/litest.h

index b7fbdb56453b874b01f94f8f42a4c65053dca73a..b3c504babcf32d171a36ded19992e4a29e0e68fa 100644 (file)
@@ -348,6 +348,78 @@ START_TEST(ck_double_ge_fails)
 }
 END_TEST
 
+START_TEST(litest_double_eq_and_ne)
+{
+       litest_assert_double_eq(0.4,0.4);
+       litest_assert_double_eq(0.4,0.4 + 1E-6);
+       litest_assert_double_ne(0.4,0.4 + 1E-3);
+
+       litest_assert_double_eq_epsilon(0.4, 0.5, 0.1);
+       litest_assert_double_eq_epsilon(0.4, 0.5, 0.2);
+       litest_assert_double_ne_epsilon(0.4, 0.6, 0.1);
+       litest_assert_double_ne_epsilon(0.4, 0.41, 0.005);
+}
+END_TEST
+
+START_TEST(litest_double_lt_gt)
+{
+       litest_assert_double_lt(12.0,13.0);
+       litest_assert_double_gt(15.4,13.0);
+       litest_assert_double_le(12.0,12.0);
+       litest_assert_double_le(12.0,20.0);
+       litest_assert_double_ge(12.0,12.0);
+       litest_assert_double_ge(20.0,12.0);
+}
+END_TEST
+
+START_TEST(litest_double_eq_fails)
+{
+       litest_assert_double_eq(0.41,0.4);
+}
+END_TEST
+
+START_TEST(litest_double_eq_epsilon_fails)
+{
+       litest_assert_double_eq_epsilon(0.4,0.5,0.05);
+}
+END_TEST
+
+START_TEST(litest_double_ne_fails)
+{
+       litest_assert_double_ne(0.4 + 1E-7,0.4);
+}
+END_TEST
+
+START_TEST(litest_double_ne_epsilon_fails)
+{
+       litest_assert_double_ne_epsilon(0.4, 0.5, 0.2);
+}
+END_TEST
+
+START_TEST(litest_double_lt_fails)
+{
+       litest_assert_double_lt(6.0, 5.0);
+}
+END_TEST
+
+START_TEST(litest_double_gt_fails)
+{
+       litest_assert_double_gt(5.0, 6.0);
+}
+END_TEST
+
+START_TEST(litest_double_le_fails)
+{
+       litest_assert_double_le(6.0, 5.0);
+}
+END_TEST
+
+START_TEST(litest_double_ge_fails)
+{
+       litest_assert_double_ge(5.0, 6.0);
+}
+END_TEST
+
 START_TEST(zalloc_overflow)
 {
        zalloc((size_t)-1);
@@ -429,6 +501,17 @@ litest_assert_macros_suite(void)
        tcase_add_exit_test(tc, ck_double_gt_fails, 1);
        tcase_add_exit_test(tc, ck_double_le_fails, 1);
        tcase_add_exit_test(tc, ck_double_ge_fails, 1);
+
+       tcase_add_test(tc, litest_double_eq_and_ne);
+       tcase_add_test(tc, litest_double_lt_gt);
+       tcase_add_test_raise_signal(tc, litest_double_eq_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_eq_epsilon_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_ne_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_ne_epsilon_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_lt_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_gt_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_le_fails, SIGABRT);
+       tcase_add_test_raise_signal(tc, litest_double_ge_fails, SIGABRT);
        suite_add_tcase(s, tc);
 
        tc = tcase_create("zalloc ");
index 842e0a6e5b4eb797570a571629d68b83e6991b15..98ca00f9ca5333991d572fe2647d23f9e7f4ff26 100644 (file)
@@ -222,34 +222,88 @@ litest_fail_comparison_ptr(const char *file,
 #define litest_assert_ptr_notnull(a_) \
        litest_assert_comparison_ptr_(a_, !=, NULL)
 
-#define litest_assert_comparison_double_(a_, op_, b_) \
+#define LITEST_DEFAULT_EPSILON  0.001
+
+#define litest_assert_double_eq_epsilon(a_, b_, epsilon_)\
+       do { \
+               __typeof__(a_) _a = a_; \
+               __typeof__(b_) _b = b_; \
+               if (!(fabs((_a) - (_b)) < epsilon_))  \
+                       litest_fail_comparison_double(__FILE__, __LINE__, __func__,\
+                                                     "==", _a, _b, \
+                                                     #a_, #b_); \
+       } while(0)
+
+#define litest_assert_double_ne_epsilon(a_, b_, epsilon_)\
+       do { \
+               __typeof__(a_) _a = a_; \
+               __typeof__(b_) _b = b_; \
+               if (!(fabs((_a) - (_b)) > epsilon_))  \
+                       litest_fail_comparison_double(__FILE__, __LINE__, __func__,\
+                                                     "!=", _a, _b, \
+                                                     #a_, #b_); \
+       } while(0)
+
+#define litest_assert_double_gt_epsilon(a_, b_, epsilon_)\
        do { \
-               const double EPSILON = 1.0/256; \
                __typeof__(a_) _a = a_; \
                __typeof__(b_) _b = b_; \
-               if (!((_a) op_ (_b)) && fabs((_a) - (_b)) > EPSILON)  \
+               if (!(_a - (epsilon_) > _b))  \
                        litest_fail_comparison_double(__FILE__, __LINE__, __func__,\
-                                                     #op_, _a, _b, \
+                                                     ">", _a, _b, \
                                                      #a_, #b_); \
        } while(0)
 
+#define litest_assert_double_ge_epsilon(a_, b_, epsilon_)\
+       do { \
+               __typeof__(a_) _a = a_; \
+               __typeof__(b_) _b = b_; \
+               if (!(_a > _b || fabs((_a) - (_b)) < epsilon_))  \
+                       litest_fail_comparison_double(__FILE__, __LINE__, __func__,\
+                                                     ">=", _a, _b, \
+                                                     #a_, #b_); \
+       } while(0)
+
+#define litest_assert_double_lt_epsilon(a_, b_, epsilon_)\
+       do { \
+               __typeof__(a_) _a = a_; \
+               __typeof__(b_) _b = b_; \
+               if (!(_a < _b - (epsilon_)))  \
+                       litest_fail_comparison_double(__FILE__, __LINE__, __func__,\
+                                                     "<", _a, _b, \
+                                                     #a_, #b_); \
+       } while(0)
+
+#define litest_assert_double_le_epsilon(a_, b_, epsilon_)\
+       do { \
+               __typeof__(a_) _a = a_; \
+               __typeof__(b_) _b = b_; \
+               if (!(_a < _b || fabs((_a) - (_b)) < epsilon_))  \
+                       litest_fail_comparison_double(__FILE__, __LINE__, __func__,\
+                                                     "<=", _a, _b, \
+                                                     #a_, #b_); \
+       } while(0)
+
+#define litest_assert_comparison_double_(a_, op_, b_) \
+       litest_assert_comparison_double_epsilon_(a_, op_, b_, LITEST_DEFAULT_EPSILON)
+
 #define litest_assert_double_eq(a_, b_)\
-       litest_assert_comparison_double_((a_), ==, (b_))
+       litest_assert_double_eq_epsilon((a_), (b_), LITEST_DEFAULT_EPSILON)
 
 #define litest_assert_double_ne(a_, b_)\
-       litest_assert_comparison_double_((a_), !=, (b_))
+       litest_assert_double_ne_epsilon((a_), (b_),LITEST_DEFAULT_EPSILON)
 
 #define litest_assert_double_lt(a_, b_)\
-       litest_assert_comparison_double_((a_), <, (b_))
+       litest_assert_double_lt_epsilon((a_), (b_),LITEST_DEFAULT_EPSILON)
 
 #define litest_assert_double_le(a_, b_)\
-       litest_assert_comparison_double_((a_), <=, (b_))
+       litest_assert_double_le_epsilon((a_), (b_),LITEST_DEFAULT_EPSILON)
 
 #define litest_assert_double_gt(a_, b_)\
-       litest_assert_comparison_double_((a_), >, (b_))
+       litest_assert_double_gt_epsilon((a_), (b_),LITEST_DEFAULT_EPSILON)
 
 #define litest_assert_double_ge(a_, b_)\
-       litest_assert_comparison_double_((a_), >=, (b_))
+       litest_assert_double_ge_epsilon((a_), (b_),LITEST_DEFAULT_EPSILON)
 
 enum litest_device_type {
        LITEST_NO_DEVICE = -1,