]> granicus.if.org Git - check/commitdiff
Fix START_TEST to look like valid C code.
authorFilipe Brandenburger <filbranden@google.com>
Tue, 12 Jun 2018 17:08:07 +0000 (10:08 -0700)
committerFilipe Brandenburger <filbranden@google.com>
Fri, 15 Jun 2018 01:15:44 +0000 (18:15 -0700)
Instead of exporting the defined name as a bare function, export a
struct that has a pointer to the function, but also its name, file and
line number where it is defined.

Store that information into a new `struct TTest`.

After this commit, START_TEST(<testname>) will create three definitions:
- <testname>_fn: The actual function;
- <testname>_ttest: A `struct TTest` with the information about it;
- <testname>: A pointer to <testname>_ttest.

Functions `tcase_add_test()` and friends are updated to take a `TTest *`
argument rather than a `TFun` and separate name. The runners are updated
to find that information inside the linked `tc->ttest`. The call to
`tcase_fn_start()` is moved from the defined functions to the runners
(both the "fork" and the "nofork" one) which call it just before
invoking the test function.

A nice side-effect is that END_TEST is now optional, though the empty
`#define` is kept for backwards compability.

v2: Initialize the struct TTest by position to be compatible with older
compilers that do not recognize named fields (e.g. VS 2010, VS 2012.)

Tested:
- `make check` still passes.
- Removing END_TEST from test cases still produces valid code that
  builds and passes tests.

src/check.c
src/check.h.in
src/check_impl.h
src/check_log.c
src/check_run.c

index e42636ed3d402458b8dec1a6b85f815c70307e94..9f9b251c802b6c875b9cc8c099c58a47a69ba180 100644 (file)
@@ -247,21 +247,21 @@ void suite_add_tcase(Suite * s, TCase * tc)
     check_list_add_end(s->tclst, tc);
 }
 
-void _tcase_add_test(TCase * tc, TFun fn, const char *name, int _signal,
-                     int allowed_exit_value, int start, int end)
+void _tcase_add_test(TCase * tc, const TTest * ttest,
+                     int _signal, int allowed_exit_value,
+                     int start, int end)
 {
     TF *tf;
 
-    if(tc == NULL || fn == NULL || name == NULL)
+    if(tc == NULL || ttest == NULL)
         return;
     tf = (TF *)emalloc(sizeof(TF));   /* freed in tcase_free */
-    tf->fn = fn;
+    tf->ttest = ttest;
     tf->loop_start = start;
     tf->loop_end = end;
     tf->signal = _signal;       /* 0 means no signal expected */
     tf->allowed_exit_value =
       (WEXITSTATUS_MASK & allowed_exit_value);   /* 0 is default successful exit */
-    tf->name = name;
     check_list_add_end(tc->tflst, tf);
 }
 
index 9e03d206794c4fd8e8111cefa61a173f8ec1d5ca..d5467279d0c1d7c6aa6162a3e9de6db947452e21 100644 (file)
@@ -121,6 +121,16 @@ typedef void (*SFun) (void);
  */
 typedef struct Suite Suite;
 
+/**
+ * Type for a test, which wraps a test function
+ */
+typedef struct TTest {
+    const char *name;
+    TFun fn;
+    const char *file;
+    int line;
+} TTest;
+
 /**
  * Creates a test suite with the given name.
  *
@@ -214,8 +224,8 @@ CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc,
  *
  * @since 0.9.2
  * */
-#define tcase_add_test_raise_signal(tc,tf,signal) \
-   _tcase_add_test((tc),(tf),"" # tf "",(signal), 0, 0, 1)
+#define tcase_add_test_raise_signal(tc,ttest,signal) \
+   _tcase_add_test((tc),(ttest),(signal), 0, 0, 1)
 
 /**
  * Add a test function with an expected exit value to a test case
@@ -229,8 +239,8 @@ CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc,
  *
  * @since 0.9.7
  */
-#define tcase_add_exit_test(tc, tf, expected_exit_value) \
-  _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),0,1)
+#define tcase_add_exit_test(tc, ttest, expected_exit_value) \
+  _tcase_add_test((tc),(ttest),0,(expected_exit_value),0,1)
 
 /**
  * Add a looping test function to a test case
@@ -246,8 +256,8 @@ CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc,
  *
  * @since 0.9.4
  */
-#define tcase_add_loop_test(tc,tf,s,e) \
-  _tcase_add_test((tc),(tf),"" # tf "",0,0,(s),(e))
+#define tcase_add_loop_test(tc,ttest,s,e) \
+  _tcase_add_test((tc),(ttest),0,0,(s),(e))
 
 /**
  * Add a looping test function with signal handling to a test case
@@ -267,8 +277,8 @@ CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc,
  *
  * @since 0.9.5
  */
-#define tcase_add_loop_test_raise_signal(tc,tf,signal,s,e) \
-  _tcase_add_test((tc),(tf),"" # tf "",(signal),0,(s),(e))
+#define tcase_add_loop_test_raise_signal(tc,ttest,signal,s,e) \
+  _tcase_add_test((tc),(ttest),(signal),0,(s),(e))
 
 /**
  * Add a looping test function with an expected exit value to a test case
@@ -288,16 +298,15 @@ CK_DLL_EXP void CK_EXPORT tcase_set_tags(TCase * tc,
  *
  * @since 0.9.7
  */
-#define tcase_add_loop_exit_test(tc,tf,expected_exit_value,s,e) \
-  _tcase_add_test((tc),(tf),"" # tf "",0,(expected_exit_value),(s),(e))
+#define tcase_add_loop_exit_test(tc,ttest,expected_exit_value,s,e) \
+  _tcase_add_test((tc),(ttest),0,(expected_exit_value),(s),(e))
 
 /* Add a test function to a test case
   (function version -- use this when the macro won't work
 */
-CK_DLL_EXP void CK_EXPORT _tcase_add_test(TCase * tc, TFun tf,
-                                          const char *fname, int _signal,
-                                          int allowed_exit_value, int start,
-                                          int end);
+CK_DLL_EXP void CK_EXPORT _tcase_add_test(TCase * tc, const TTest * ttest,
+                                          int _signal, int allowed_exit_value,
+                                          int start, int end);
 
 /**
  * Add unchecked fixture setup/teardown functions to a test case
@@ -400,16 +409,17 @@ CK_DLL_EXP const char* CK_EXPORT tcase_name(void);
  * @since 0.6.0
  */
 #define START_TEST(__testname)\
-static void __testname (int _i CK_ATTRIBUTE_UNUSED)\
-{\
-  tcase_fn_start (""# __testname, __FILE__, __LINE__);
+static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED);\
+static const TTest __testname ## _ttest = {""# __testname, __testname ## _fn, __FILE__, __LINE__};\
+static const TTest * __testname = & __testname ## _ttest;\
+static void __testname ## _fn (int _i CK_ATTRIBUTE_UNUSED)
 
 /**
  *  End a unit test
  *
  * @since 0.6.0
  */
-#define END_TEST }
+#define END_TEST
 
 /*
  * Fail the test case unless expr is false
index bddd18682944dfd661e443b20f26e45f8aa92ec6..f4e8c59034bc356e7315ba04839d5fcbc5acb40d 100644 (file)
 
 typedef struct TF
 {
-    TFun fn;
+    const TTest * ttest;
     int loop_start;
     int loop_end;
-    const char *name;
     int signal;
     signed char allowed_exit_value;
 } TF;
index 2af8321045805308fc0422335137cda957f03298..c785b33c92f008d1580ee6c13d02964e71584fd8 100644 (file)
@@ -152,7 +152,7 @@ void log_test_start(SRunner * sr, TCase * tc, TF * tfun)
 {
     char buffer[100];
 
-    snprintf(buffer, 99, "%s:%s", tc->name, tfun->name);
+    snprintf(buffer, 99, "%s:%s", tc->name, tfun->ttest->name);
     srunner_send_evt(sr, buffer, CLSTART_T);
 }
 
index da1f40f147a3d5610fe849cb772b6306fbcf4324..7e212e02ad18ca04679d7080d58126f6ec702e8f 100644 (file)
@@ -415,11 +415,12 @@ static TestResult *tcase_run_tfun_nofork(SRunner * sr, TCase * tc, TF * tfun,
         clock_gettime(check_get_clockid(), &ts_start);
         if(0 == setjmp(error_jmp_buffer))
         {
-            tfun->fn(i);
+            tcase_fn_start(tfun->ttest->name, tfun->ttest->file, tfun->ttest->line);
+            tfun->ttest->fn(i);
         }
         clock_gettime(check_get_clockid(), &ts_end);
         tcase_run_checked_teardown(tc);
-        return receive_result_info_nofork(tc->name, tfun->name, i,
+        return receive_result_info_nofork(tc->name, tfun->ttest->name, i,
                                           DIFF_IN_USEC(ts_start, ts_end));
     }
 
@@ -491,7 +492,8 @@ static TestResult *tcase_run_tfun_fork(SRunner * sr, TCase * tc, TF * tfun,
         tr = tcase_run_checked_setup(sr, tc);
         free(tr);
         clock_gettime(check_get_clockid(), &ts_start);
-        tfun->fn(i);
+        tcase_fn_start(tfun->ttest->name, tfun->ttest->file, tfun->ttest->line);
+        tfun->ttest->fn(i);
         clock_gettime(check_get_clockid(), &ts_end);
         tcase_run_checked_teardown(tc);
         send_duration_info(DIFF_IN_USEC(ts_start, ts_end));
@@ -535,7 +537,7 @@ static TestResult *tcase_run_tfun_fork(SRunner * sr, TCase * tc, TF * tfun,
 
     killpg(pid, SIGKILL);       /* Kill remaining processes. */
 
-    return receive_result_info_fork(tc->name, tfun->name, i, status,
+    return receive_result_info_fork(tc->name, tfun->ttest->name, i, status,
                                     tfun->signal, tfun->allowed_exit_value);
 }