r21523 - gnucash/trunk/src/test-core - [Testing] Test facility for QofEvents and improve fatal-handling

John Ralls jralls at code.gnucash.org
Sat Nov 5 19:04:23 EDT 2011


Author: jralls
Date: 2011-11-05 19:04:23 -0400 (Sat, 05 Nov 2011)
New Revision: 21523
Trac: http://svn.gnucash.org/trac/changeset/21523

Modified:
   gnucash/trunk/src/test-core/Makefile.am
   gnucash/trunk/src/test-core/test-stuff.c
   gnucash/trunk/src/test-core/test-stuff.h
Log:
[Testing] Test facility for QofEvents and improve fatal-handling

For use from tests based on glib testing. Create a private structure to
compare to and register a handler which tests the event parameters
against the private structure and counts the number of valid hits.
Provides a test function for checking that the event handler has been
hit the requisite number of times.

Pass through, rather than testing, logs with a lower (i.e., less
important rather than lower-value) loglevel than the one the handler was
set up for. Test the log message rather than overwriting the pre-set one
with the actual message.

Modified: gnucash/trunk/src/test-core/Makefile.am
===================================================================
--- gnucash/trunk/src/test-core/Makefile.am	2011-11-05 23:04:11 UTC (rev 21522)
+++ gnucash/trunk/src/test-core/Makefile.am	2011-11-05 23:04:23 UTC (rev 21523)
@@ -9,4 +9,5 @@
 
 AM_CPPFLAGS = \
   -I${top_srcdir}/src \
+  -I${top_srcdir}/src/libqof/qof \
   ${GLIB_CFLAGS}

Modified: gnucash/trunk/src/test-core/test-stuff.c
===================================================================
--- gnucash/trunk/src/test-core/test-stuff.c	2011-11-05 23:04:11 UTC (rev 21522)
+++ gnucash/trunk/src/test-core/test-stuff.c	2011-11-05 23:04:23 UTC (rev 21523)
@@ -373,14 +373,21 @@
     TestErrorStruct *tdata = (TestErrorStruct*)user_data;
     if (tdata == NULL)
     {
-        g_printf("Recieved Error Message %s\n", msg);
+        g_printf("Received Log Message %s\n", msg);
         return FALSE;
     }
+/* If it's a lower loglevel than we expected, report it and move on */
+    if (tdata->log_level && log_level < tdata->log_level)
+    {
+	g_printf ("Received Log Message %s\n", msg);
+	return FALSE;
+    }
     if (tdata->log_domain != NULL)
-        g_assert(g_strcmp0(tdata->log_domain, log_domain) == 0);
+        g_assert_cmpstr (tdata->log_domain, ==, log_domain);
     if (tdata->log_level)
-        g_assert(log_level == tdata->log_level);
-    tdata->msg = g_strdup(msg);
+        g_assert_cmpuint (tdata->log_level, ==, log_level);
+    if (tdata->log_level)
+        g_assert_cmpstr (tdata->msg, ==, msg);
     return FALSE;
 }
 
@@ -390,7 +397,7 @@
     tdata.called = val;
 }
 
-const gboolean
+gboolean
 test_reset_called( void )
 {
     const gboolean called  = tdata.called;
@@ -404,7 +411,7 @@
     tdata.data = val;
 }
 
-const gpointer
+gpointer
 test_reset_data( void )
 {
     const gpointer data  = tdata.data;
@@ -418,3 +425,55 @@
     if (!data) return;
     g_free(data);
 }
+
+
+typedef struct
+{
+    QofInstance *entity;
+    QofEventId event_type;
+    gpointer event_data;
+    gint hdlr;
+    guint hits;
+} _TestSignal;
+
+static void
+mock_signal_handler (QofInstance *entity, QofEventId event_type,
+		     gpointer handler_data, gpointer event_data)
+{
+    _TestSignal *signal = (_TestSignal*)handler_data;
+    if ((signal->entity == entity || signal->entity == NULL)
+	&& signal->event_type == event_type)
+    {
+	if (signal->event_data)
+	    g_assert (signal->event_data == event_data);
+	signal->hits += 1;
+    }
+}
+
+TestSignal
+test_signal_new (QofInstance *entity, QofEventId event_type,
+		 gpointer event_data)
+{
+    _TestSignal *sig = g_slice_new (_TestSignal);
+    sig->entity = entity;
+    sig->event_type = event_type;
+    sig->event_data = event_data;
+    sig->hits = 0;
+    sig->hdlr = qof_event_register_handler (mock_signal_handler, (gpointer)sig);
+    return (TestSignal)sig;
+}
+
+void
+test_signal_free (TestSignal sigp)
+{
+    _TestSignal *sig = (_TestSignal *)sigp;
+    qof_event_unregister_handler (sig->hdlr);
+    g_slice_free (_TestSignal, sig);
+}
+
+void
+test_signal_assert_hits (TestSignal sigp, guint hits)
+{
+    _TestSignal *sig = (_TestSignal *)sigp;
+    g_assert_cmpint (sig->hits, ==, hits);
+}

Modified: gnucash/trunk/src/test-core/test-stuff.h
===================================================================
--- gnucash/trunk/src/test-core/test-stuff.h	2011-11-05 23:04:11 UTC (rev 21522)
+++ gnucash/trunk/src/test-core/test-stuff.h	2011-11-05 23:04:23 UTC (rev 21523)
@@ -36,6 +36,7 @@
 
 #include <glib.h>
 #include <stdlib.h>
+#include <qof.h>
 
 /**
  * Use this to indicate the result of a test.
@@ -120,7 +121,7 @@
  * Destructively tests (meaning that it resets called to FALSE) and
  * returns the value of called.
  */
-const gboolean test_reset_called( void );
+gboolean test_reset_called( void );
 
 /**
  * Set the test data pointer with the what you expect your mock to be
@@ -132,7 +133,7 @@
  * Destructively retrieves the test data pointer. Call from your mock
  * to ensure that it received the expected data.
  */
-const gpointer test_reset_data( void );
+gpointer test_reset_data( void );
 
 /**
  * A handy function to use to free memory from lists of simple
@@ -214,4 +215,26 @@
 double get_random_double(void);
 const char* get_random_string_in_array(const char* str_list[]);
 
+/* TestSignal is an opaque struct used to mock handling signals
+ * emitted by functions-under-test. It registers a handler and counts
+ * how many times it is called with the right instance and type.  The
+ * struct is allocated using g_slice_new, and it registers a
+ * qof_event_handler; test_signal_free cleans up at the end of the
+ * test function (or sooner, if you want to reuse a TestSignal).  If
+ * event_data isn't NULL, the mock signal handler will test that it
+ * matches the event_data passed with the signal and assert if it
+ * isn't the same object (pointer comparison). If the actual event
+ * data is a local variable, it won't be accessible, so the event_data
+ * passed to test_signal_new should be NULL to avoid the test.
+ */
+typedef gpointer TestSignal;
+TestSignal test_signal_new (QofInstance *entity, QofEventId eventType,
+			     gpointer event_data);
+/* test_signal_assert_hits calls g_assert_cmpuint with an ==
+ * operator. Use it in a test program to see if a TestSignal has been
+ * emitted the number of times you expect.
+ */
+void test_signal_assert_hits (TestSignal sig, guint hits);
+void test_signal_free (TestSignal sig);
+
 #endif /* TEST_STUFF_H */



More information about the gnucash-changes mailing list