OSDN Git Service

catch ctor/dtor/setUp/tearDown longjmp
[ccunit/ccunit.git] / src / ccunit / CCUnitTestFixture.c
1 /* Copyright (C) 2003 TSUTSUMI Kikuo.
2    This file is part of the CCUnit Library.
3
4    The CCUnit Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public License
6    as published by the Free Software Foundation; either version 2.1 of
7    the License, or (at your option) any later version.
8
9    The CCUnit Library is distributed in the hope that it will be
10    useful, but WITHOUT ANY WARRANTY; without even the implied warranty
11    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU Lesser General Public License for more details.
13
14    You should have received a copy of the GNU Lesser General Public
15    License along with the CCUnit Library; see the file COPYING.LESSER.
16    If not, write to the Free Software Foundation, Inc., 59 Temple
17    Place - Suite 330, Boston, MA 02111-1307, USA.  
18 */
19
20 /*
21  * $Id$
22  */
23
24 /**
25  * @file
26  * TestFixture module implementation.
27  */
28
29 #include <ccunit/CCUnitTestFixture.h>
30 #include <ccunit/CCUnitTestResult.h>
31 #include <assert.h>
32 #include <setjmp.h>
33
34 /**
35  * run test fixtures exception.
36  */
37 jmp_buf _ccunit_run_env;
38
39 /**
40  * run tests exception.
41  */
42 jmp_buf _ccunit_runTest_env;
43
44 extern void _ccunit_runTestCase (CCUnitTestResult* result,
45                                  CCUnitTestFixture* fixture);
46
47 inline void ccunit_addTestCase (CCUnitTestFixture* fixture,
48                                 CCUnitTestCase* testCase)
49 {
50   ccunit_addList (&fixture->testCases, testCase);
51 }
52
53 CCUnitTestCase* ccunit_addNewTestCase (CCUnitTestFixture* fixture,
54                                        const char* name,
55                                        const char* desc,
56                                        void (*runTest)())
57 {
58   CCUnitTestCase* c = ccunit_newTestCase (name, desc, runTest);
59   if (!c)
60     return NULL;
61   ccunit_addTestCase (fixture, c);
62   return c;
63 }
64
65 /**
66  * Runs the test fixture and collects the results in CCUnitTestResult.
67  * @param test A test to run.
68  * @param result A result container.
69  */
70 static void run (CCUnitTest* test, CCUnitTestResult* result)
71 {
72   assert (test->type == ccunitTypeFixture);
73   _ccunit_runTestCase (result, (CCUnitTestFixture*)test);
74 }
75
76 /**
77  * Destruct test fixture.
78  * @param test destruct test.
79  */
80 static void destroy (CCUnitTest* test)
81 {
82   CCUnitTestFixture* fixture;
83   assert (test->type == ccunitTypeFixture);
84   fixture = (CCUnitTestFixture*)test;
85   safe_free ((char*)fixture->name);
86   ccunit_deleteList (&fixture->testCases,
87                      (void (*)(void*))ccunit_deleteTestCase);
88 }
89
90 CCUnitTestFixture* ccunit_newTestFixture (const char* name,
91                                           void (*setUp)(),
92                                           void (*tearDown)(),
93                                           void (*ctor)(),
94                                           void (*dtor)())
95 {
96   CCUnitTestFixture* fixture = calloc (1, sizeof (*fixture));
97   ccunit_initTest (&fixture->test, ccunitTypeFixture, run, destroy);
98   fixture->name = safe_strdup (name);
99   ccunit_initList (&fixture->testCases);
100   fixture->setUp = setUp;
101   fixture->tearDown = tearDown;
102   fixture->ctor = ctor;
103   fixture->dtor = dtor;
104   return fixture;
105 }
106
107 inline struct CCUnitTestResult* ccunit_runTestFixture (CCUnitTestFixture* f)
108 {
109   CCUnitTestResult* result;
110   result = ccunit_newTestResult ();
111   f->test.run (&f->test, result);
112   return result;
113 }
114
115 /*
116  * Runs the bare test sequence.
117  *
118  * @param testFixture test fixture to run.
119  * @param runTest test run function.
120  * @param result test result.
121  * @throws _ccunit_runResult_env by longjmp.
122  */
123 void _ccunit_runBare (CCUnitTestFixture* fixture,
124                       void (*runTest) (),
125                       CCUnitTestResult* result)
126 {
127   int failure = 0;
128   int runFailure = 0;
129   assert (fixture->test.type == ccunitTypeFixture);
130   if (fixture->setUp)
131     {
132       if ((failure = setjmp (_ccunit_runTest_env)) == 0)
133         fixture->setUp ();
134       else
135         ccunit_addFailure (result, (CCUnitTestFailure*)failure);
136     }
137   if (!failure)
138     {
139       if ((runFailure = setjmp (_ccunit_runTest_env)) == 0)
140         {
141           runTest ();
142         }
143     }
144   if (fixture->tearDown)
145     {
146       if ((failure = setjmp (_ccunit_runTest_env)) == 0)
147         fixture->tearDown ();
148       else
149         ccunit_addFailure (result, (CCUnitTestFailure*)failure);
150     }
151   if (runFailure)
152     longjmp (_ccunit_run_env, runFailure);
153 }