mirror of
				https://gitlab.gnome.org/GNOME/glib.git
				synced 2025-11-04 01:58:54 +01:00 
			
		
		
		
	Add fuzzy floating point comparison macro
Add a test macro that allows comparing two floating point values for equality within a certain tolerance. This macro has been independently reimplemented by various projects: * Clutter * Graphene * colord https://gitlab.gnome.org/GNOME/glib/issues/914
This commit is contained in:
		@@ -3147,6 +3147,7 @@ g_assert_cmpint
 | 
			
		||||
g_assert_cmpuint
 | 
			
		||||
g_assert_cmphex
 | 
			
		||||
g_assert_cmpfloat
 | 
			
		||||
g_assert_cmpfloat_with_epsilon
 | 
			
		||||
g_assert_cmpmem
 | 
			
		||||
g_assert_no_error
 | 
			
		||||
g_assert_error
 | 
			
		||||
 
 | 
			
		||||
@@ -89,10 +89,11 @@
 | 
			
		||||
 *
 | 
			
		||||
 * In addition to the traditional g_assert(), the test framework provides
 | 
			
		||||
 * an extended set of assertions for comparisons: g_assert_cmpfloat(),
 | 
			
		||||
 * g_assert_cmpint(), g_assert_cmpuint(), g_assert_cmphex(),
 | 
			
		||||
 * g_assert_cmpstr(), and g_assert_cmpmem(). The advantage of these
 | 
			
		||||
 * variants over plain g_assert() is that the assertion messages can be
 | 
			
		||||
 * more elaborate, and include the values of the compared entities.
 | 
			
		||||
 * g_assert_cmpfloat_with_epsilon(), g_assert_cmpint(), g_assert_cmpuint(),
 | 
			
		||||
 * g_assert_cmphex(), g_assert_cmpstr(), and g_assert_cmpmem(). The
 | 
			
		||||
 * advantage of these variants over plain g_assert() is that the assertion
 | 
			
		||||
 * messages can be more elaborate, and include the values of the compared
 | 
			
		||||
 * entities.
 | 
			
		||||
 *
 | 
			
		||||
 * A full example of creating a test suite with two tests using fixtures:
 | 
			
		||||
 * |[<!-- language="C" -->
 | 
			
		||||
@@ -636,6 +637,23 @@
 | 
			
		||||
 * Since: 2.16
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_assert_cmpfloat_with_epsilon:
 | 
			
		||||
 * @n1: an floating point number
 | 
			
		||||
 * @n2: another floating point number
 | 
			
		||||
 * @epsilon: a numeric value that expresses the expected tolerance
 | 
			
		||||
 *   between @n1 and @n2
 | 
			
		||||
 *
 | 
			
		||||
 * Debugging macro to compare two floating point numbers within an epsilon.
 | 
			
		||||
 *
 | 
			
		||||
 * The effect of `g_assert_cmpfloat_with_epsilon (n1, n2, epsilon)` is
 | 
			
		||||
 * the same as `g_assert_true (abs (n1 - n2) < epsilon)`. The advantage
 | 
			
		||||
 * of this macro is that it can produce a message that includes the
 | 
			
		||||
 * actual values of @n1 and @n2.
 | 
			
		||||
 *
 | 
			
		||||
 * Since: 2.58
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * g_assert_cmpmem:
 | 
			
		||||
 * @m1: pointer to a buffer
 | 
			
		||||
 
 | 
			
		||||
@@ -69,6 +69,13 @@ typedef void (*GTestFixtureFunc) (gpointer      fixture,
 | 
			
		||||
                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
 | 
			
		||||
                                                 #n1 " " #cmp " " #n2, (long double) __n1, #cmp, (long double) __n2, 'f'); \
 | 
			
		||||
                                        } G_STMT_END
 | 
			
		||||
#define g_assert_cmpfloat_with_epsilon(n1,n2,epsilon) \
 | 
			
		||||
                                        G_STMT_START { \
 | 
			
		||||
                                             double __n1 = (n1), __n2 = (n2), __epsilon = (epsilon); \
 | 
			
		||||
                                             if (G_APPROX_VALUE (__n1,  __n2, __epsilon)) ; else \
 | 
			
		||||
                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
 | 
			
		||||
                                                 #n1 " == " #n2 " (+/- " #epsilon ")", __n1, "==", __n2, 'f'); \
 | 
			
		||||
                                        } G_STMT_END
 | 
			
		||||
#define g_assert_cmpmem(m1, l1, m2, l2) G_STMT_START {\
 | 
			
		||||
                                             gconstpointer __m1 = m1, __m2 = m2; \
 | 
			
		||||
                                             int __l1 = l1, __l2 = l2; \
 | 
			
		||||
 
 | 
			
		||||
@@ -60,6 +60,13 @@ test_assertions_bad_cmpmem_data (void)
 | 
			
		||||
  exit (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_assertions_bad_cmpfloat_epsilon (void)
 | 
			
		||||
{
 | 
			
		||||
  g_assert_cmpfloat_with_epsilon (3.14, 3.15, 0.001);
 | 
			
		||||
  exit (0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void
 | 
			
		||||
test_assertions (void)
 | 
			
		||||
{
 | 
			
		||||
@@ -68,6 +75,8 @@ test_assertions (void)
 | 
			
		||||
  g_assert_cmphex (2, ==, 2);
 | 
			
		||||
  g_assert_cmpfloat (3.3, !=, 7);
 | 
			
		||||
  g_assert_cmpfloat (7, <=, 3 + 4);
 | 
			
		||||
  g_assert_cmpfloat_with_epsilon (3.14, 3.15, 0.01);
 | 
			
		||||
  g_assert_cmpfloat_with_epsilon (3.14159, 3.1416, 0.0001);
 | 
			
		||||
  g_assert (TRUE);
 | 
			
		||||
  g_assert_cmpstr ("foo", !=, "faa");
 | 
			
		||||
  fuu = g_strdup_printf ("f%s", "uu");
 | 
			
		||||
@@ -98,6 +107,10 @@ test_assertions (void)
 | 
			
		||||
  g_test_trap_assert_failed ();
 | 
			
		||||
  g_test_trap_assert_stderr ("*assertion failed*");
 | 
			
		||||
  g_test_trap_assert_stderr_unmatched ("*assertion failed*len*");
 | 
			
		||||
 | 
			
		||||
  g_test_trap_subprocess ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", 0, 0);
 | 
			
		||||
  g_test_trap_assert_failed ();
 | 
			
		||||
  g_test_trap_assert_stderr ("*assertion failed*");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* test g_test_timer* API */
 | 
			
		||||
@@ -740,6 +753,7 @@ main (int   argc,
 | 
			
		||||
  g_test_add_func ("/misc/assertions/subprocess/bad_cmpint", test_assertions_bad_cmpint);
 | 
			
		||||
  g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_len", test_assertions_bad_cmpmem_len);
 | 
			
		||||
  g_test_add_func ("/misc/assertions/subprocess/bad_cmpmem_data", test_assertions_bad_cmpmem_data);
 | 
			
		||||
  g_test_add_func ("/misc/assertions/subprocess/bad_cmpfloat_epsilon", test_assertions_bad_cmpfloat_epsilon);
 | 
			
		||||
  g_test_add_data_func ("/misc/test-data", (void*) 0xc0c0baba, test_data_test);
 | 
			
		||||
  g_test_add ("/misc/primetoul", Fixturetest, (void*) 0xc0cac01a, fixturetest_setup, fixturetest_test, fixturetest_teardown);
 | 
			
		||||
  if (g_test_perf())
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user