1 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  *  Copyright (C) 2007-2009  Kouhei Sutou <kou@cozmixng.org>
4  *
5  *  This library is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Lesser General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  *
18  */
19 
20 #ifdef HAVE_CONFIG_H
21 #  include <config.h>
22 #endif /* HAVE_CONFIG_H */
23 
24 #include <glib.h>
25 
26 #include "cut-test-runner.h"
27 #include "cut-runner.h"
28 #include "cut-repository.h"
29 #include "cut-test-case.h"
30 #include "cut-test-result.h"
31 
32 #include "cut-enum-types.h"
33 
34 static void runner_init (CutRunnerIface *iface);
35 
36 
37 static CutRunnerIface *parent_runner_iface;
38 
39 G_DEFINE_TYPE_WITH_CODE(CutTestRunner, cut_test_runner, CUT_TYPE_RUN_CONTEXT,
40                         G_IMPLEMENT_INTERFACE(CUT_TYPE_RUNNER, runner_init))
41 
42 static gboolean runner_run (CutRunner *runner);
43 
44 static void
cut_test_runner_class_init(CutTestRunnerClass * klass)45 cut_test_runner_class_init (CutTestRunnerClass *klass)
46 {
47 }
48 
49 static void
cut_test_runner_init(CutTestRunner * runner)50 cut_test_runner_init (CutTestRunner *runner)
51 {
52 }
53 
54 static void
runner_init(CutRunnerIface * iface)55 runner_init (CutRunnerIface *iface)
56 {
57     parent_runner_iface = g_type_interface_peek_parent(iface);
58     iface->run_async = NULL;
59     iface->run       = runner_run;
60 }
61 
62 CutRunContext *
cut_test_runner_new(void)63 cut_test_runner_new (void)
64 {
65     return g_object_new(CUT_TYPE_TEST_RUNNER, NULL);
66 }
67 
68 static void
cb_start_test(CutTest * test,CutTestContext * test_context,gpointer data)69 cb_start_test (CutTest *test, CutTestContext *test_context, gpointer data)
70 {
71     CutRunContext *context = data;
72 
73     g_signal_emit_by_name(context, "start-test", test, test_context);
74 }
75 
76 static void
cb_pass_assertion_test(CutTest * test,CutTestContext * test_context,gpointer data)77 cb_pass_assertion_test (CutTest *test, CutTestContext *test_context,
78                         gpointer data)
79 {
80     CutRunContext *context = data;
81 
82     g_signal_emit_by_name(context, "pass-assertion", test, test_context);
83 }
84 
85 static void
cb_success_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)86 cb_success_test (CutTest *test, CutTestContext *test_context,
87                  CutTestResult *result, gpointer data)
88 {
89     CutRunContext *context = data;
90 
91     g_signal_emit_by_name(context, "success-test", test, test_context, result);
92 }
93 
94 static void
cb_failure_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)95 cb_failure_test (CutTest *test, CutTestContext *test_context,
96                  CutTestResult *result, gpointer data)
97 {
98     CutRunContext *context = data;
99 
100     g_signal_emit_by_name(context, "failure-test", test, test_context, result);
101 }
102 
103 static void
cb_error_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)104 cb_error_test (CutTest *test, CutTestContext *test_context,
105                CutTestResult *result, gpointer data)
106 {
107     CutRunContext *context = data;
108 
109     g_signal_emit_by_name(context, "error-test", test, test_context, result);
110 }
111 
112 static void
cb_pending_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)113 cb_pending_test (CutTest *test, CutTestContext *test_context,
114                  CutTestResult *result, gpointer data)
115 {
116     CutRunContext *context = data;
117 
118     g_signal_emit_by_name(context, "pending-test", test, test_context, result);
119 }
120 
121 static void
cb_notification_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)122 cb_notification_test (CutTest *test, CutTestContext *test_context,
123                       CutTestResult *result, gpointer data)
124 {
125     CutRunContext *context = data;
126 
127     g_signal_emit_by_name(context, "notification-test",
128                           test, test_context, result);
129 }
130 
131 static void
cb_omission_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)132 cb_omission_test (CutTest *test, CutTestContext *test_context,
133                   CutTestResult *result, gpointer data)
134 {
135     CutRunContext *context = data;
136 
137     g_signal_emit_by_name(context, "omission-test", test, test_context, result);
138 }
139 
140 static void
cb_crash_test(CutTest * test,CutTestContext * test_context,CutTestResult * result,gpointer data)141 cb_crash_test (CutTest *test, CutTestContext *test_context,
142                CutTestResult *result, gpointer data)
143 {
144     CutRunContext *context = data;
145 
146     g_signal_emit_by_name(context, "crash-test", test, test_context, result);
147 }
148 
149 static void
cb_complete_test(CutTest * test,CutTestContext * test_context,gboolean success,gpointer data)150 cb_complete_test (CutTest *test, CutTestContext *test_context,
151                   gboolean success, gpointer data)
152 {
153     CutRunContext *context = data;
154 
155     g_signal_emit_by_name(context, "complete-test", test, test_context, success);
156 }
157 
158 static void
connect_to_test(CutRunContext * context,CutTest * test)159 connect_to_test (CutRunContext *context, CutTest *test)
160 {
161 #define CONNECT(name)                                                   \
162     g_signal_connect(test, #name,                                       \
163                      G_CALLBACK(cb_ ## name ## _test), context)
164 
165     CONNECT(start);
166     CONNECT(pass_assertion);
167     CONNECT(success);
168     CONNECT(failure);
169     CONNECT(error);
170     CONNECT(pending);
171     CONNECT(notification);
172     CONNECT(omission);
173     CONNECT(crash);
174     CONNECT(complete);
175 #undef CONNECT
176 }
177 
178 static void
cb_start_test_test_case(CutTestCase * test_case,CutTest * test,CutTestContext * test_context,gpointer data)179 cb_start_test_test_case (CutTestCase *test_case, CutTest *test,
180                          CutTestContext *test_context, gpointer data)
181 {
182     CutRunContext *context = data;
183 
184     connect_to_test(context, test);
185 }
186 
187 static void
cb_complete_test_test_case(CutTestCase * test_case,CutTest * test,CutTestContext * test_context,gboolean success,gpointer data)188 cb_complete_test_test_case (CutTestCase *test_case, CutTest *test,
189                             CutTestContext *test_context, gboolean success,
190                             gpointer data)
191 {
192 #define DISCONNECT(name)                                                \
193     g_signal_handlers_disconnect_by_func(test,                          \
194                                          G_CALLBACK(cb_ ##              \
195                                                     name ##             \
196                                                     _test),             \
197                                          data)
198 
199     DISCONNECT(start);
200     DISCONNECT(pass_assertion);
201     DISCONNECT(success);
202     DISCONNECT(failure);
203     DISCONNECT(error);
204     DISCONNECT(pending);
205     DISCONNECT(notification);
206     DISCONNECT(omission);
207     DISCONNECT(crash);
208     DISCONNECT(complete);
209 #undef DISCONNECT
210 }
211 
212 static void
cb_success_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)213 cb_success_test_case (CutTestCase *test_case, CutTestContext *test_context,
214                       CutTestResult *result, gpointer data)
215 {
216     CutRunContext *context = data;
217 
218     g_signal_emit_by_name(context, "success-test-case", test_case, result);
219 }
220 
221 static void
cb_failure_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)222 cb_failure_test_case (CutTestCase *test_case, CutTestContext *test_context,
223                       CutTestResult *result, gpointer data)
224 {
225     CutRunContext *context = data;
226 
227     g_signal_emit_by_name(context, "failure-test-case", test_case, result);
228 }
229 
230 static void
cb_error_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)231 cb_error_test_case (CutTestCase *test_case, CutTestContext *test_context,
232                     CutTestResult *result, gpointer data)
233 {
234     CutRunContext *context = data;
235 
236     g_signal_emit_by_name(context, "error-test-case", test_case, result);
237 }
238 
239 static void
cb_pending_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)240 cb_pending_test_case (CutTestCase *test_case, CutTestContext *test_context,
241                       CutTestResult *result, gpointer data)
242 {
243     CutRunContext *context = data;
244 
245     g_signal_emit_by_name(context, "pending-test-case", test_case, result);
246 }
247 
248 static void
cb_notification_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)249 cb_notification_test_case (CutTestCase *test_case, CutTestContext *test_context,
250                            CutTestResult *result, gpointer data)
251 {
252     CutRunContext *context = data;
253 
254     g_signal_emit_by_name(context, "notification-test-case", test_case, result);
255 }
256 
257 static void
cb_omission_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)258 cb_omission_test_case (CutTestCase *test_case, CutTestContext *test_context,
259                        CutTestResult *result, gpointer data)
260 {
261     CutRunContext *context = data;
262 
263     g_signal_emit_by_name(context, "omission-test-case", test_case, result);
264 }
265 
266 static void
cb_crash_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)267 cb_crash_test_case (CutTestCase *test_case, CutTestContext *test_context,
268                     CutTestResult *result, gpointer data)
269 {
270     CutRunContext *context = data;
271 
272     g_signal_emit_by_name(context, "crash-test-case", test_case, result);
273 }
274 
275 static void
cb_failure_in_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)276 cb_failure_in_test_case (CutTestCase *test_case, CutTestContext *test_context,
277                          CutTestResult *result, gpointer data)
278 {
279     CutRunContext *context = data;
280 
281     g_signal_emit_by_name(context, "failure-in-test-case", test_case, result);
282 }
283 
284 static void
cb_error_in_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)285 cb_error_in_test_case (CutTestCase *test_case, CutTestContext *test_context,
286                        CutTestResult *result, gpointer data)
287 {
288     CutRunContext *context = data;
289 
290     g_signal_emit_by_name(context, "error-in-test-case", test_case, result);
291 }
292 
293 static void
cb_pending_in_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)294 cb_pending_in_test_case (CutTestCase *test_case, CutTestContext *test_context,
295                          CutTestResult *result, gpointer data)
296 {
297     CutRunContext *context = data;
298 
299     g_signal_emit_by_name(context, "pending-in-test-case", test_case, result);
300 }
301 
302 static void
cb_notification_in_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)303 cb_notification_in_test_case (CutTestCase *test_case,
304                               CutTestContext *test_context,
305                               CutTestResult *result,
306                               gpointer data)
307 {
308     CutRunContext *context = data;
309 
310     g_signal_emit_by_name(context, "notification-in-test-case",
311                           test_case, result);
312 }
313 
314 static void
cb_omission_in_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)315 cb_omission_in_test_case (CutTestCase *test_case, CutTestContext *test_context,
316                           CutTestResult *result, gpointer data)
317 {
318     CutRunContext *context = data;
319 
320     g_signal_emit_by_name(context, "omission-in-test-case", test_case, result);
321 }
322 
323 static void
cb_crash_in_test_case(CutTestCase * test_case,CutTestContext * test_context,CutTestResult * result,gpointer data)324 cb_crash_in_test_case (CutTestCase *test_case, CutTestContext *test_context,
325                        CutTestResult *result, gpointer data)
326 {
327     CutRunContext *context = data;
328 
329     g_signal_emit_by_name(context, "crash-in-test-case", test_case, result);
330 }
331 
332 static void
cb_start_test_case(CutTestCase * test_case,CutTestContext * test_context,gpointer data)333 cb_start_test_case (CutTestCase *test_case, CutTestContext *test_context,
334                     gpointer data)
335 {
336     CutRunContext *context = data;
337 
338     g_signal_emit_by_name(context, "start-test-case", test_case);
339 }
340 
341 static void
cb_ready_test_case(CutTestCase * test_case,guint n_tests,gpointer data)342 cb_ready_test_case (CutTestCase *test_case, guint n_tests, gpointer data)
343 {
344     CutRunContext *context = data;
345 
346     g_signal_emit_by_name(context, "ready-test-case", test_case, n_tests);
347 }
348 
349 static void
cb_complete_test_case(CutTestCase * test_case,CutTestContext * test_context,gboolean success,gpointer data)350 cb_complete_test_case (CutTestCase *test_case, CutTestContext *test_context,
351                        gboolean success, gpointer data)
352 {
353     CutRunContext *context = data;
354 
355     g_signal_emit_by_name(context, "complete-test-case", test_case, success);
356 }
357 
358 static void
cb_ready_test_suite(CutTestSuite * test_suite,guint n_test_cases,guint n_tests,gpointer data)359 cb_ready_test_suite (CutTestSuite *test_suite, guint n_test_cases,
360                      guint n_tests, gpointer data)
361 {
362     CutRunContext *context = data;
363 
364     g_signal_emit_by_name(context, "ready-test-suite", test_suite,
365                           n_test_cases, n_tests);
366 }
367 
368 static void
cb_start_test_suite(CutTestSuite * test_suite,CutTestContext * test_context,gpointer data)369 cb_start_test_suite (CutTestSuite *test_suite, CutTestContext *test_context,
370                      gpointer data)
371 {
372     CutRunContext *context = data;
373 
374     g_signal_emit_by_name(context, "start-test-suite", test_suite);
375 }
376 
377 static void
cb_crash_test_suite(CutTestSuite * test_suite,CutTestContext * test_context,CutTestResult * result,gpointer data)378 cb_crash_test_suite (CutTestSuite *test_suite, CutTestContext *test_context,
379                      CutTestResult *result, gpointer data)
380 {
381     CutRunContext *context = data;
382 
383     g_signal_emit_by_name(context, "crash-test-suite", test_suite, result);
384 }
385 
386 static void
cb_start_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,gpointer data)387 cb_start_iterated_test (CutIteratedTest *iterated_test,
388                         CutTestContext *test_context, gpointer data)
389 {
390     CutRunContext *context = data;
391 
392     g_signal_emit_by_name(context, "start-iterated-test",
393                           iterated_test, test_context);
394 }
395 
396 static void
cb_pass_assertion_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,gpointer data)397 cb_pass_assertion_iterated_test (CutIteratedTest *iterated_test,
398                                  CutTestContext *test_context, gpointer data)
399 {
400     cb_pass_assertion_test(CUT_TEST(iterated_test), test_context, data);
401 }
402 
403 static void
cb_success_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)404 cb_success_iterated_test (CutIteratedTest *iterated_test,
405                           CutTestContext *test_context,
406                           CutTestResult *result, gpointer data)
407 {
408     cb_success_test(CUT_TEST(iterated_test), test_context, result, data);
409 }
410 
411 static void
cb_failure_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)412 cb_failure_iterated_test (CutIteratedTest *iterated_test,
413                           CutTestContext *test_context,
414                           CutTestResult *result, gpointer data)
415 {
416     cb_failure_test(CUT_TEST(iterated_test), test_context, result, data);
417 }
418 
419 static void
cb_error_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)420 cb_error_iterated_test (CutIteratedTest *iterated_test,
421                         CutTestContext *test_context,
422                         CutTestResult *result, gpointer data)
423 {
424     cb_error_test(CUT_TEST(iterated_test), test_context, result, data);
425 }
426 
427 static void
cb_pending_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)428 cb_pending_iterated_test (CutIteratedTest *iterated_test,
429                           CutTestContext *test_context,
430                           CutTestResult *result, gpointer data)
431 {
432     cb_pending_test(CUT_TEST(iterated_test), test_context, result, data);
433 }
434 
435 static void
cb_notification_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)436 cb_notification_iterated_test (CutIteratedTest *iterated_test,
437                                CutTestContext *test_context,
438                                CutTestResult *result, gpointer data)
439 {
440     cb_notification_test(CUT_TEST(iterated_test), test_context, result, data);
441 }
442 
443 static void
cb_omission_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)444 cb_omission_iterated_test (CutIteratedTest *iterated_test,
445                            CutTestContext *test_context,
446                            CutTestResult *result, gpointer data)
447 {
448     cb_omission_test(CUT_TEST(iterated_test), test_context, result, data);
449 }
450 
451 static void
cb_crash_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,CutTestResult * result,gpointer data)452 cb_crash_iterated_test (CutIteratedTest *iterated_test,
453                         CutTestContext *test_context,
454                         CutTestResult *result, gpointer data)
455 {
456     cb_crash_test(CUT_TEST(iterated_test), test_context, result, data);
457 }
458 
459 static void
cb_complete_iterated_test(CutIteratedTest * iterated_test,CutTestContext * test_context,gboolean success,gpointer data)460 cb_complete_iterated_test (CutIteratedTest *iterated_test,
461                            CutTestContext *test_context, gboolean success,
462                            gpointer data)
463 {
464     CutRunContext *context = data;
465 
466     g_signal_emit_by_name(context, "complete-iterated-test",
467                           iterated_test, test_context, success);
468 }
469 
470 static void
cb_start_iterated_test_test_iterator(CutTestIterator * test_iterator,CutIteratedTest * iterated_test,CutTestContext * test_context,gpointer data)471 cb_start_iterated_test_test_iterator (CutTestIterator *test_iterator,
472                                       CutIteratedTest *iterated_test,
473                                       CutTestContext *test_context,
474                                       gpointer data)
475 {
476     CutRunContext *context = data;
477 
478 #define CONNECT(name)                                                   \
479     g_signal_connect(iterated_test, #name,                              \
480                      G_CALLBACK(cb_ ## name ## _iterated_test),         \
481                      context)
482 
483     CONNECT(start);
484     CONNECT(complete);
485 
486     CONNECT(pass_assertion);
487     CONNECT(success);
488     CONNECT(failure);
489     CONNECT(error);
490     CONNECT(pending);
491     CONNECT(notification);
492     CONNECT(omission);
493     CONNECT(crash);
494 #undef CONNECT
495 }
496 
497 static void
cb_complete_iterated_test_test_iterator(CutTestIterator * test_iterator,CutIteratedTest * iterated_test,CutTestContext * test_context,gboolean success,gpointer data)498 cb_complete_iterated_test_test_iterator (CutTestIterator *test_iterator,
499                                          CutIteratedTest *iterated_test,
500                                          CutTestContext *test_context,
501                                          gboolean success,
502                                          gpointer data)
503 {
504 #define DISCONNECT(name)                                                \
505     g_signal_handlers_disconnect_by_func(iterated_test,                 \
506                                          G_CALLBACK(cb_ ##              \
507                                                     name ##             \
508                                                     _iterated_test),    \
509                                          data)
510 
511     DISCONNECT(start);
512     DISCONNECT(complete);
513 
514     DISCONNECT(pass_assertion);
515     DISCONNECT(success);
516     DISCONNECT(failure);
517     DISCONNECT(error);
518     DISCONNECT(pending);
519     DISCONNECT(notification);
520     DISCONNECT(omission);
521     DISCONNECT(crash);
522 #undef DISCONNECT
523 }
524 
525 static void
cb_success_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)526 cb_success_test_iterator (CutTestIterator *test_iterator,
527                           CutTestContext *test_context,
528                           CutTestResult *result, gpointer data)
529 {
530     CutRunContext *context = data;
531 
532     g_signal_emit_by_name(context, "success-test-iterator",
533                           test_iterator, result);
534 }
535 
536 static void
cb_failure_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)537 cb_failure_test_iterator (CutTestIterator *test_iterator,
538                           CutTestContext *test_context,
539                           CutTestResult *result, gpointer data)
540 {
541     CutRunContext *context = data;
542 
543     g_signal_emit_by_name(context, "failure-test-iterator",
544                           test_iterator, result);
545 }
546 
547 static void
cb_error_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)548 cb_error_test_iterator (CutTestIterator *test_iterator,
549                         CutTestContext *test_context,
550                         CutTestResult *result, gpointer data)
551 {
552     CutRunContext *context = data;
553 
554     g_signal_emit_by_name(context, "error-test-iterator",
555                           test_iterator, result);
556 }
557 
558 static void
cb_pending_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)559 cb_pending_test_iterator (CutTestIterator *test_iterator,
560                           CutTestContext *test_context,
561                           CutTestResult *result, gpointer data)
562 {
563     CutRunContext *context = data;
564 
565     g_signal_emit_by_name(context, "pending-test-iterator",
566                           test_iterator, result);
567 }
568 
569 static void
cb_notification_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)570 cb_notification_test_iterator (CutTestIterator *test_iterator,
571                                CutTestContext *test_context,
572                                CutTestResult *result, gpointer data)
573 {
574     CutRunContext *context = data;
575 
576     g_signal_emit_by_name(context, "notification-test-iterator",
577                           test_iterator, result);
578 }
579 
580 static void
cb_omission_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)581 cb_omission_test_iterator (CutTestIterator *test_iterator,
582                            CutTestContext *test_context,
583                            CutTestResult *result, gpointer data)
584 {
585     CutRunContext *context = data;
586 
587     g_signal_emit_by_name(context, "omission-test-iterator",
588                           test_iterator, result);
589 }
590 
591 static void
cb_crash_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,CutTestResult * result,gpointer data)592 cb_crash_test_iterator (CutTestIterator *test_iterator,
593                         CutTestContext *test_context,
594                         CutTestResult *result, gpointer data)
595 {
596     CutRunContext *context = data;
597 
598     g_signal_emit_by_name(context, "crash-test-iterator",
599                           test_iterator, result);
600 }
601 
602 static void
cb_start_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,gpointer data)603 cb_start_test_iterator (CutTestIterator *test_iterator,
604                         CutTestContext *test_context, gpointer data)
605 {
606     CutRunContext *context = data;
607 
608     g_signal_emit_by_name(context, "start-test-iterator", test_iterator);
609 }
610 
611 static void
cb_ready_test_iterator(CutTestIterator * test_iterator,guint n_tests,gpointer data)612 cb_ready_test_iterator (CutTestIterator *test_iterator, guint n_tests,
613                         gpointer data)
614 {
615     CutRunContext *context = data;
616 
617     g_signal_emit_by_name(context, "ready-test-iterator",
618                           test_iterator, n_tests);
619 }
620 
621 static void
cb_complete_test_iterator(CutTestIterator * test_iterator,CutTestContext * test_context,gboolean success,gpointer data)622 cb_complete_test_iterator (CutTestIterator *test_iterator,
623                            CutTestContext *test_context,
624                            gboolean success, gpointer data)
625 {
626     CutRunContext *context = data;
627 
628     g_signal_emit_by_name(context, "complete-test-iterator",
629                           test_iterator, success);
630 }
631 
632 static void
connect_to_test_iterator(CutRunContext * context,CutTestIterator * test_iterator)633 connect_to_test_iterator (CutRunContext *context, CutTestIterator *test_iterator)
634 {
635 
636 #define CONNECT(name)                                                   \
637     g_signal_connect(test_iterator, #name,                              \
638                      G_CALLBACK(cb_ ## name ## _test_iterator), context)
639 
640     CONNECT(start_iterated_test);
641     CONNECT(complete_iterated_test);
642 
643     CONNECT(success);
644     CONNECT(failure);
645     CONNECT(error);
646     CONNECT(pending);
647     CONNECT(notification);
648     CONNECT(omission);
649     CONNECT(crash);
650 
651     CONNECT(ready);
652     CONNECT(start);
653     CONNECT(complete);
654 #undef CONNECT
655 }
656 
657 static void
cb_start_test_iterator_test_case(CutTestCase * test_case,CutTestIterator * test_iterator,CutTestContext * test_context,gpointer data)658 cb_start_test_iterator_test_case (CutTestCase *test_case,
659                                   CutTestIterator *test_iterator,
660                                   CutTestContext *test_context,
661                                   gpointer data)
662 {
663     CutRunContext *context = data;
664 
665     connect_to_test_iterator(context, test_iterator);
666 }
667 
668 static void
cb_complete_test_iterator_test_case(CutTestCase * test_case,CutTestIterator * test_iterator,CutTestContext * test_context,gboolean success,gpointer data)669 cb_complete_test_iterator_test_case (CutTestCase *test_case,
670                                      CutTestIterator *test_iterator,
671                                      CutTestContext *test_context,
672                                      gboolean success,
673                                      gpointer data)
674 {
675     CutRunContext *context = data;
676 
677 #define DISCONNECT(name)                                                \
678     g_signal_handlers_disconnect_by_func(test_iterator,                 \
679                                          G_CALLBACK(cb_ ##              \
680                                                     name ##             \
681                                                     _test_iterator),    \
682                                          context)
683 
684     DISCONNECT(start_iterated_test);
685     DISCONNECT(complete_iterated_test);
686 
687     DISCONNECT(success);
688     DISCONNECT(failure);
689     DISCONNECT(error);
690     DISCONNECT(pending);
691     DISCONNECT(notification);
692     DISCONNECT(omission);
693     DISCONNECT(crash);
694 
695     DISCONNECT(ready);
696     DISCONNECT(start);
697     DISCONNECT(complete);
698 #undef DISCONNECT
699 }
700 
701 static void
connect_to_test_case(CutRunContext * context,CutTestCase * test_case)702 connect_to_test_case (CutRunContext *context, CutTestCase *test_case)
703 {
704 #define CONNECT(name)                                                   \
705     g_signal_connect(test_case, #name,                                  \
706                      G_CALLBACK(cb_ ## name ## _test_case), context)
707 
708     CONNECT(start_test);
709     CONNECT(complete_test);
710     CONNECT(start_test_iterator);
711     CONNECT(complete_test_iterator);
712 
713     CONNECT(success);
714     CONNECT(failure);
715     CONNECT(error);
716     CONNECT(pending);
717     CONNECT(notification);
718     CONNECT(omission);
719     CONNECT(crash);
720 
721     CONNECT(failure_in);
722     CONNECT(error_in);
723     CONNECT(pending_in);
724     CONNECT(notification_in);
725     CONNECT(omission_in);
726     CONNECT(crash_in);
727 
728     CONNECT(ready);
729     CONNECT(start);
730     CONNECT(complete);
731 #undef CONNECT
732 }
733 
734 static void
cb_start_test_case_test_suite(CutTestSuite * test_suite,CutTestCase * test_case,gpointer data)735 cb_start_test_case_test_suite (CutTestSuite *test_suite, CutTestCase *test_case,
736                                gpointer data)
737 {
738     CutRunContext *context = data;
739 
740     connect_to_test_case(context, test_case);
741 }
742 
743 static void
cb_complete_test_case_test_suite(CutTestSuite * test_suite,CutTestCase * test_case,gboolean success,gpointer data)744 cb_complete_test_case_test_suite (CutTestSuite *test_suite,
745                                   CutTestCase *test_case,
746                                   gboolean success,
747                                   gpointer data)
748 {
749     CutRunContext *context = data;
750 
751 #define DISCONNECT(name)                                                \
752     g_signal_handlers_disconnect_by_func(test_case,                     \
753                                          G_CALLBACK(cb_ ##              \
754                                                     name ##             \
755                                                     _test_case),        \
756                                          context)
757 
758     DISCONNECT(start_test);
759     DISCONNECT(complete_test);
760     DISCONNECT(start_test_iterator);
761     DISCONNECT(complete_test_iterator);
762 
763     DISCONNECT(success);
764     DISCONNECT(failure);
765     DISCONNECT(error);
766     DISCONNECT(pending);
767     DISCONNECT(notification);
768     DISCONNECT(omission);
769     DISCONNECT(crash);
770 
771     DISCONNECT(ready);
772     DISCONNECT(start);
773     DISCONNECT(complete);
774 #undef DISCONNECT
775 }
776 
777 static void
cb_complete_test_suite(CutTestSuite * test_suite,CutTestContext * test_context,gboolean success,gpointer data)778 cb_complete_test_suite (CutTestSuite *test_suite, CutTestContext *test_context,
779                         gboolean success, gpointer data)
780 {
781     CutRunContext *context = data;
782 
783 #define DISCONNECT(name)                                                \
784     g_signal_handlers_disconnect_by_func(test_suite,                    \
785                                          G_CALLBACK(cb_ ##              \
786                                                     name ##             \
787                                                     _test_suite),       \
788                                          data)
789 
790     DISCONNECT(ready);
791     DISCONNECT(start);
792     DISCONNECT(crash);
793     DISCONNECT(complete);
794 
795     DISCONNECT(start_test_case);
796     DISCONNECT(complete_test_case);
797 #undef DISCONNECT
798 
799     g_signal_emit_by_name(context, "complete-test-suite", test_suite, success);
800 }
801 
802 static void
connect_to_test_suite(CutRunContext * context,CutTestSuite * test_suite)803 connect_to_test_suite (CutRunContext *context, CutTestSuite *test_suite)
804 {
805 #define CONNECT(name)                                                \
806     g_signal_connect(test_suite, #name,                              \
807                      G_CALLBACK(cb_ ## name ## _test_suite),         \
808                      context)
809 
810     CONNECT(ready);
811     CONNECT(start);
812     CONNECT(crash);
813     CONNECT(complete);
814 
815     CONNECT(start_test_case);
816     CONNECT(complete_test_case);
817 #undef CONNECT
818 }
819 
820 static gboolean
runner_run(CutRunner * runner)821 runner_run (CutRunner *runner)
822 {
823     CutRunContext *context;
824     CutTestSuite *suite;
825     gboolean success;
826 
827     context = CUT_RUN_CONTEXT(runner);
828     suite = cut_run_context_get_test_suite(context);
829     g_signal_emit_by_name(context, "start-run");
830     success = cut_test_runner_run_test_suite(CUT_TEST_RUNNER(runner), suite);
831     success = cut_run_context_emit_complete_run(context, success);
832     return success;
833 }
834 
835 gboolean
cut_test_runner_run_test(CutTestRunner * runner,CutTest * test,CutTestContext * test_context)836 cut_test_runner_run_test (CutTestRunner *runner, CutTest *test,
837                           CutTestContext *test_context)
838 {
839     CutRunContext *context;
840 
841     context = CUT_RUN_CONTEXT(runner);
842     connect_to_test(context, test);
843     return cut_test_run(test, test_context, context);
844 }
845 
846 gboolean
cut_test_runner_run_test_case(CutTestRunner * runner,CutTestCase * test_case)847 cut_test_runner_run_test_case (CutTestRunner *runner, CutTestCase *test_case)
848 {
849     CutRunContext *context;
850 
851     context = CUT_RUN_CONTEXT(runner);
852     connect_to_test_case(context, test_case);
853     return cut_test_case_run(test_case, context);
854 }
855 
856 gboolean
cut_test_runner_run_test_iterator(CutTestRunner * runner,CutTestIterator * test_iterator,CutTestContext * test_context)857 cut_test_runner_run_test_iterator (CutTestRunner *runner,
858                                    CutTestIterator *test_iterator,
859                                    CutTestContext *test_context)
860 {
861     CutRunContext *context;
862 
863     context = CUT_RUN_CONTEXT(runner);
864     connect_to_test_iterator(context, test_iterator);
865     return cut_test_run(CUT_TEST(test_iterator), test_context, context);
866 }
867 
868 gboolean
cut_test_runner_run_test_suite(CutTestRunner * runner,CutTestSuite * test_suite)869 cut_test_runner_run_test_suite (CutTestRunner *runner, CutTestSuite *test_suite)
870 {
871     CutRunContext *context;
872 
873     context = CUT_RUN_CONTEXT(runner);
874     connect_to_test_suite(context, test_suite);
875     return cut_test_suite_run(test_suite, context);
876 }
877 
878 /*
879 vi:ts=4:nowrap:ai:expandtab:sw=4
880 */
881