testing: Evaluate expressions only once in EXPECT_EQ_STR().
[collectd.git] / src / testing.h
index 5df1b83..1bcc276 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * collectd - src/tests/macros.h
- * Copyright (C) 2013       Florian octo Forster
+ * Copyright (C) 2013-2015  Florian octo Forster
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
  *   Florian octo Forster <octo at collectd.org>
  */
 
+#ifndef TESTING_H
+#define TESTING_H 1
+
+#include <inttypes.h>
+
 static int fail_count__ = 0;
 static int check_count__ = 0;
 
-#define DEF_TEST(func) static int test_##func ()
+#ifndef DBL_PRECISION
+# define DBL_PRECISION 1e-12
+#endif
+
+#define DEF_TEST(func) static int test_##func (void)
 
 #define RUN_TEST(func) do { \
   int status; \
@@ -42,16 +51,56 @@ static int check_count__ = 0;
 #define OK1(cond, text) do { \
   _Bool result = (cond); \
   printf ("%s %i - %s\n", result ? "ok" : "not ok", ++check_count__, text); \
+  if (!result) { return -1; } \
 } while (0)
 #define OK(cond) OK1(cond, #cond)
 
-#define STREQ(expect, actual) do { \
-  if (strcmp (expect, actual) != 0) { \
-    printf ("not ok %i - %s incorrect: expected \"%s\", got \"%s\"\n", \
-        ++check_count__, #actual, expect, actual); \
+#define EXPECT_EQ_STR(expect, actual) do { \
+  /* Evaluate 'actual' only once. */ \
+  const char *got__ = actual; \
+  if (strcmp (expect, got__) != 0) { \
+    printf ("not ok %i - %s = \"%s\", want \"%s\"\n", \
+        ++check_count__, #actual, got__, expect); \
     return (-1); \
   } \
-  printf ("ok %i - %s evaluates to \"%s\"\n", ++check_count__, #actual, expect); \
+  printf ("ok %i - %s = \"%s\"\n", ++check_count__, #actual, got__); \
+} while (0)
+
+#define EXPECT_EQ_INT(expect, actual) do { \
+  int want__ = (int) expect; \
+  int got__  = (int) actual; \
+  if (got__ != want__) { \
+    printf ("not ok %i - %s = %d, want %d\n", \
+        ++check_count__, #actual, got__, want__); \
+    return (-1); \
+  } \
+  printf ("ok %i - %s = %d\n", ++check_count__, #actual, got__); \
+} while (0)
+
+#define EXPECT_EQ_UINT64(expect, actual) do { \
+  uint64_t want__ = (uint64_t) expect; \
+  uint64_t got__  = (uint64_t) actual; \
+  if (got__ != want__) { \
+    printf ("not ok %i - %s = %"PRIu64", want %"PRIu64"\n", \
+        ++check_count__, #actual, got__, want__); \
+    return (-1); \
+  } \
+  printf ("ok %i - %s = %"PRIu64"\n", ++check_count__, #actual, got__); \
+} while (0)
+
+#define EXPECT_EQ_DOUBLE(expect, actual) do { \
+  double want__ = (double) expect; \
+  double got__  = (double) actual; \
+  if (isnan (want__) && !isnan (got__)) { \
+    printf ("not ok %i - %s = %.15g, want %.15g\n", \
+        ++check_count__, #actual, got__, want__); \
+    return (-1); \
+  } else if (!isnan (want__) && (((want__-got__) < -DBL_PRECISION) || ((want__-got__) > DBL_PRECISION))) { \
+    printf ("not ok %i - %s = %.15g, want %.15g\n", \
+        ++check_count__, #actual, got__, want__); \
+    return (-1); \
+  } \
+  printf ("ok %i - %s = %.15g\n", ++check_count__, #actual, got__); \
 } while (0)
 
 #define CHECK_NOT_NULL(expr) do { \
@@ -65,3 +114,5 @@ static int check_count__ = 0;
   status_ = (long) (expr); \
   OK1(status_ == 0L, #expr); \
 } while (0)
+
+#endif /* TESTING_H */