1 /********************************************************************
2  * unittest-support.h: Support structures for GLib Unit Testing     *
3  * Copyright 2011-12 John Ralls <jralls@ceridwen.us>		    *
4  * Copyright 2011 Muslim Chochlov <muslim.chochlov@gmail.com>       *
5  *                                                                  *
6  * This program is free software; you can redistribute it and/or    *
7  * modify it under the terms of the GNU General Public License as   *
8  * published by the Free Software Foundation; either version 2 of   *
9  * the License, or (at your option) any later version.              *
10  *                                                                  *
11  * This program is distributed in the hope that it will be useful,  *
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of   *
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    *
14  * GNU General Public License for more details.                     *
15  *                                                                  *
16  * You should have received a copy of the GNU General Public License*
17  * along with this program; if not, contact:                        *
18  *                                                                  *
19  * Free Software Foundation           Voice:  +1-617-542-5942       *
20  * 51 Franklin Street, Fifth Floor    Fax:    +1-617-542-2652       *
21  * Boston, MA  02110-1301,  USA       gnu@gnu.org                   *
22 ********************************************************************/
23 #ifndef UNITTEST_SUPPORT_H
24 #define UNITTEST_SUPPORT_H
25 
26 #include <glib.h>
27 #include <qof.h>
28 /** @file unittest-support.h
29  * @brief Macros and logging-capture functions to ease writing GLib-testing
30  *  based unit tests.
31  */
32 
33 /** @name Unit Test Macros
34  * These macros facilitate combining a suite name and a test name to make a path
35  * when registering a test function with the corresponding g_test_add and
36  * g_test_add_func. Create a const char* suitename somewhere in the file and
37  * pass it as the first parameter, and the test name as the second. The
38  * remaining parameters are the same as in the underlying function.
39  */
40 
41 /**
42  * Wraps gnc_test_add() for test functions needing a fixture.
43  */
44 
45 #define GNC_TEST_ADD( suite, path, fixture, data, setup, test, teardown )\
46 {\
47     gchar *testpath = g_strdup_printf( "%s/%s", suite, path );\
48     g_test_add( testpath, fixture, data, setup, test, teardown );\
49     g_free( testpath );\
50 }
51 
52 /**
53  * Wraps gnc_test_add_func() for test functions which don't require a fixture.
54  */
55 
56 #define GNC_TEST_ADD_FUNC( suite, path, test )\
57 {\
58     gchar *testpath = g_strdup_printf( "%s/%s", suite, path );\
59     g_test_add_func( testpath, test );\
60     g_free( testpath );\
61 }
62 /** @} */
63 /** @name Suppressing Expected Errors
64  *
65  * Functions for suppressing expected errors during tests. Pass
66  *
67  * Note that you need to call both g_log_set_handler *and*
68  * g_test_log_set_fatal_handler to both avoid the assertion and
69  * suppress the error message. The callbacks work in either role, just
70  * cast them appropriately for the use.
71  *
72  * To simplify the process a bit and make sure that everything gets
73  * cleaned up at the end of each test, add a GSList for handlers to
74  * your Fixture and set it to NULL in setup(), then call
75  * g_slist_free_full() on it with test_free_log_handler as the
76  * function. Create new TestErrorStruct instances with
77  * test_error_struct_new, and pass that along with your handler of
78  * choice to test_log_set_handler or test_log_set_fatal_handler. This
79  * is much simpler, as teardown will clean everything up for you and
80  * you need call only those functions. As an added bonus, the hit
81  * count won't be doubled as it is if you do everything by hand.
82  *
83  * NB: If you have more than one fatal error in a test function be
84  * sure to use the test_list_handler: You can have only one fatal
85  * handler.
86  * @{
87  */
88 
89 /**
90  * Struct to pass as user_data for the handlers. Setting a parameter
91  * to NULL or 0 will match any value in the error, so if you have the
92  * same message and log level being issued in two domains you can
93  * match both of them by setting log_domain = NULL.
94  *
95  */
96 
97 typedef struct
98 {
99     GLogLevelFlags log_level;
100     char *log_domain;
101     char *msg;
102     guint hits;
103 } TestErrorStruct;
104 
105 /**
106  * Convenience function to create an error struct. If you use this
107  * with test_set_log_handler it will get cleaned up at tesrdown,
108  * otherwise call test_error_free() at the end of your test function.
109  *
110  * NB: If you need to change the message, be sure to free the old one
111  * and to allocate the new one on the stack.
112  *
113  * @param log_domain: The string representing the domain of the log message
114  * @param log_level: The GLogLevelFlags for the message
115  * @param msg: The exact error message that the logger will emit
116  * @return: A TestErrorStruct *
117  */
118 TestErrorStruct* test_error_struct_new (const char *log_domain,
119                                         const GLogLevelFlags log_level,
120                                         const char *msg);
121 
122 /**
123  * Free a TestErrorStruct created with test_error_struct_new
124  * @param error: The TestErrorStruct to be freed
125  */
126 void test_error_struct_free (TestErrorStruct *);
127 
128 /**
129  * Holds a handler instance with its TestErrorStruct, handler id, and whether
130  * it's a list handler. A test fixture can be set up to hold a GSList of these
131  * so that they can be automatically unregistered and freed during teardown.
132  */
133 typedef struct
134 {
135     TestErrorStruct *error;
136     gint handler;
137     gboolean list_handler;
138 } TestLogHandler;
139 
140 
141 /**
142  * Set a log handler and add it to a GList for removal at teardown
143  *
144  * Don't pass a NULL TestErrorStruct! It's needed to set the
145  * parameters for g_log_set_handler. Use a TestErrorStruct created
146  * with test_error_struct_new() or you'll have errors with freeing it
147  * in teardown.
148  *
149  * @param handler_list: A GSList of LogHandlers
150  * @param error: A TestErrorStruct with the necessary data
151  * @param handler: The Handler to set the data with
152  * @return: The new GSList pointer.
153  */
154 GSList *test_log_set_handler (GSList *list, TestErrorStruct *error,
155                               GLogFunc handler);
156 
157 /**
158  * Set a log handler and add it to a GList for removal at teardown;
159  * also set the fatal handler so that the test program doesn't abort
160  * for fatal log messages. If a test function has more than one fatal
161  * message, be sure to use the test_list_handler!
162  *
163  * Don't pass a NULL TestErrorStruct! It's needed to set the
164  * parameters for g_log_set_handler. Use a TestErrorStruct created
165  * with test_error_struct_new() or you'll have errors with freeing it
166  * in teardown.
167  *
168  * @param handler_list: A GSList of LogHandlers
169  * @param error: A TestErrorStruct with the necessary data
170  * @param handler: The Handler to set the data with
171  * @return: The new GSList pointer.
172  */
173 GSList *test_log_set_fatal_handler (GSList *list, TestErrorStruct *error,
174                                     GLogFunc handler);
175 
176 /**
177  * Clears all the log handlers. Pass this to g_slist_free() in teardown.
178  */
179 void test_free_log_handler (gpointer item);
180 
181 /**
182  * Check that the user_data error message is a substring of the
183  * actual error otherwise assert.  Displays the error (and asserts
184  * if G_LOG_FLAG_FATAL is TRUE) if NULL is passed as user_data,
185  * but a NULL or 0 value member matches anything.
186  */
187 gboolean test_checked_substring_handler (const char *log_domain, GLogLevelFlags log_level,
188                                          const gchar *msg, gpointer user_data);
189 /**
190  * Check the user_data against the actual error and assert on any
191  * differences.  Displays the error (and asserts if G_LOG_FLAG_FATAL
192  * is TRUE) if NULL is passed as user_data, but a NULL or 0 value
193  * member matches anything.
194  */
195 gboolean test_checked_handler (const char *log_domain, GLogLevelFlags log_level,
196                                const gchar *msg, gpointer user_data);
197 
198 /**
199  * Just print the log message. Since GLib has a habit of eating its
200  * log messages, it's sometimes useful to call
201  * g_test_log_set_fatal_handler() with this to make sure that
202  * g_return_if_fail() error messages make it to the surface.
203  */
204 gboolean test_log_handler (const char *log_domain, GLogLevelFlags log_level,
205                            const gchar *msg, gpointer user_data);
206 /**
207  * Just returns FALSE or suppresses the message regardless of what the
208  * error is. Use this only as a last resort.
209  */
210 gboolean test_null_handler (const char *log_domain, GLogLevelFlags log_level,
211                             const gchar *msg, gpointer user_data );
212 /**
213  * Maintains an internal list of TestErrorStructs which are each
214  * checked by the list handler. If an error matches any entry on the
215  * list, test_list_handler will return FALSE, blocking the error from
216  * halting the program.
217  *
218  * Call test_add_error for each TestErrorStruct to check against and
219  * test_clear_error_list when you no longer expect the errors.
220  */
221 void test_add_error (TestErrorStruct *error);
222 void test_clear_error_list (void);
223 
224 /**
225  * Checks received errors against the list created by
226  * test_add_error. Rather than checking for an exact match, this function
227  * checks using a substring match. If the list is empty or nothing
228  * matches, passes control on to test_checked_substring_handler, giving
229  * the opportunity for an additional check that's not in the list
230  * (set user_data to NULL if you want test_checked_handler to
231  * immediately print the error).
232  */
233 gboolean test_list_substring_handler (const char *log_domain, GLogLevelFlags log_level,
234                       const gchar *msg, gpointer user_data);
235 
236 /**
237  * Checks received errors against the list created by
238  * test_add_error. If the list is empty or nothing matches, passes
239  * control on to test_checked_handler, giving the opportunity for an
240  * additional check that's not in the list (set user_data to NULL if
241  * you want test_checked_handler to immediately print the error).
242  */
243 gboolean test_list_handler (const char *log_domain,
244                             GLogLevelFlags log_level,
245                             const gchar *msg, gpointer user_data );
246 /**
247  * Call this from a mock object to indicate that the mock has in fact
248  * been called
249  */
250 void test_set_called( const gboolean val );
251 
252 /**
253  * Destructively tests (meaning that it resets called to FALSE) and
254  * returns the value of called.
255  */
256 gboolean test_reset_called( void );
257 
258 /**
259  * Set the test data pointer with the what you expect your mock to be
260  * called with.
261  */
262 void test_set_data( gpointer data );
263 
264 /**
265  * Destructively retrieves the test data pointer. Call from your mock
266  * to ensure that it received the expected data.
267  */
268 gpointer test_reset_data( void );
269 
270 /**
271  * A handy function to use to free memory from lists of simple
272  * pointers. Call g_list_free_full(list, (GDestroyNotify)*test_free).
273  */
274 void test_free( gpointer data );
275 
276 /** @}
277  */
278 /** @name Test Signals
279  * Test the emission of signals from objects. Signals are used to coordinate the
280  * behavior of the GUI with events in other parts of the program.  @{
281  */
282 /**
283  * TestSignal is an opaque struct used to mock handling signals
284  * emitted by functions-under-test. It registers a handler and counts
285  * how many times it is called with the right instance and type.  The
286  * struct is allocated using g_slice_new, and it registers a
287  * qof_event_handler; test_signal_free cleans up at the end of the
288  * test function (or sooner, if you want to reuse a TestSignal).  If
289  * event_data isn't NULL, the mock signal handler will test that it
290  * matches the event_data passed with the signal and assert if it
291  * isn't the same object (pointer comparison). If the actual event
292  * data is a local variable, it won't be accessible, so the event_data
293  * passed to test_signal_new should be NULL to avoid the test.
294  */
295 typedef gpointer TestSignal;
296 
297 /**
298  * Create a test signal.
299  * @param entity: The QofInstance emitting the signal
300  * @param eventType: The type of the signal
301  * @param event_data: Any data required by the signal or NULL if none is.
302  * @return A newly created TestSignal. Use test_signal_free to release it.
303  */
304 
305 TestSignal test_signal_new (QofInstance *entity, QofEventId eventType,
306                             gpointer event_data);
307 /**
308  * gets the number of times the TestSignal has been called.
309  */
310 guint test_signal_return_hits (TestSignal sig);
311 
312 /**
313  * Convenience macro which wraps test_signal_return_hits with and equality
314  * assertion.
315  */
316 
317 #define test_signal_assert_hits(sig, hits) \
318     g_assert_cmpint (test_signal_return_hits (sig), ==, hits)
319 
320 /**
321  * Free a test signal.
322  */
323 void test_signal_free (TestSignal sig);
324 
325 /** @}
326  */
327 
328 /** @name Testing for object disposal
329  * Sometimes we need to make sure that certain objects that we've created aren't leaking. These functions can help.
330  * @{
331  */
332 
333 /**
334  * Unrefs obj and returns true if its finalize method was called.
335  */
336 
337 gboolean test_object_checked_destroy (GObject *obj);
338 
339 /**
340  * Ensures that a GObject is still alive at the time
341  * it's called and that it is finalized. The first assertion will
342  * trigger if you pass it a ponter which isn't a GObject -- which
343  * could be the case if the object has already been finalized. Then it
344  * calls test_object_checked_destroy() on it, asserting if the
345  * finalize method wasn't called (which indicates a leak).
346  */
347 
348 #define test_destroy(obj) \
349     g_assert (obj != NULL && G_IS_OBJECT (obj));		\
350     g_assert (test_object_checked_destroy (G_OBJECT (obj)))
351 
352 /** @} */
353 /* For Scheme testing access:
354 void gnc_log_init_filename_special (gchar *filename);
355 void gnc_log_shutdown (void);
356 void gnc_log_set_handler (guint logdomain, gchar *logdomain, GLogFunc * func, gpointer data);
357 */
358 
359 #endif /*UNITTEST_SUPPORT_H*/
360