OSDN Git Service

86abe1fffdb6085e318ade573383fa5c2de27f36
[ccunit/ccunit.git] / src / ccunit / CCUnitTestFixture.c
1 /* Copyright (C) 2003, 2010 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 tests exception environment.
36  */
37 jmp_buf _ccunit_runTest_env;
38
39 /**
40  * run tests exception.
41  */
42 CCUnitTestFailure* _ccunit_testFailure;
43
44 extern void _ccunit_startTest (CCUnitTestResult* result,
45                                struct CCUnitTestCase* test);
46 extern void _ccunit_endTest (CCUnitTestResult* result,
47                              struct CCUnitTestCase* test);
48
49 inline void ccunit_addTestCase (CCUnitTestFixture* fixture,
50                                 CCUnitTestCase* testCase)
51 {
52   ccunit_addList (&fixture->testCases, testCase);
53 }
54
55 CCUnitTestCase* ccunit_addNewTestCase (CCUnitTestFixture* fixture,
56                                        const char* name,
57                                        const char* desc,
58                                        void (*runTest)())
59 {
60   CCUnitTestCase* c;
61   if (!fixture)
62     return NULL;
63   c = ccunit_newTestCase (name, desc, runTest);
64   if (!c)
65     return NULL;
66   ccunit_addTestCase (fixture, c);
67   return c;
68 }
69
70 /**
71  * Runs the bare test sequence.
72  *
73  * @return failure
74  */
75 static CCUnitTestFailure* runTest (CCUnitTestCase* testCase,
76                                    CCUnitTestFunc* setUp,
77                                    CCUnitTestFunc* tearDown,
78                                    CCUnitTestResult* result)
79 {
80   CCUnitTestFailure* runFailure = NULL;
81   if (setUp && setUp->runTest)
82     {
83       if (setjmp (_ccunit_runTest_env) == 0)
84         setUp->runTest ();
85       else
86         {
87           _ccunit_testFailure->testCase = setUp;
88           return _ccunit_testFailure;
89         }
90     }
91   if (setjmp (_ccunit_runTest_env) == 0)
92     {
93       result->runCount ++;
94       testCase->runTest ();
95     }
96   else
97     {
98       runFailure = _ccunit_testFailure;
99       runFailure->testCase = testCase;
100     }
101   if (tearDown && tearDown->runTest)
102     {
103       if (setjmp (_ccunit_runTest_env) == 0)
104         tearDown->runTest ();
105       else
106         {
107           _ccunit_testFailure->testCase = tearDown;
108           ccunit_addFailure (result, _ccunit_testFailure);
109         }
110     }
111   return runFailure;
112 }
113
114 /**
115  * Runs the test fixture and collects the results in CCUnitTestResult.
116  * @param test A test to run.
117  * @param result A result container.
118  */
119 static void run (CCUnitTest* test, CCUnitTestResult* result)
120 {
121   CCUnitTestFixture* fixture = (CCUnitTestFixture*)test;
122   CCUnitListIterator itor;
123   CCUnitTestCase* testCase;
124   assert (test->type == ccunitTypeFixture);
125   ccunit_initListIterator (&fixture->testCases, &itor);
126   while ((testCase = ccunit_nextListIterator (&itor)) != NULL)
127     {
128       CCUnitTestFailure* failure = NULL;
129       _ccunit_startTest (result, testCase);
130       failure = runTest (testCase, fixture->setUp, fixture->tearDown, result);
131       if (failure)
132         ccunit_addFailure (result, failure);
133       _ccunit_endTest (result, testCase);
134     }
135 }
136
137 /**
138  * Destruct test fixture.
139  * @param test destruct test.
140  */
141 static void destroy (CCUnitTest* test)
142 {
143   CCUnitTestFixture* fixture;
144   assert (test->type == ccunitTypeFixture);
145   fixture = (CCUnitTestFixture*)test;
146   safe_free (fixture->name);
147   ccunit_deleteTestFunc (fixture->setUp);
148   ccunit_deleteTestFunc (fixture->tearDown);
149   ccunit_deleteList (&fixture->testCases,
150                      (void (*)(void*))ccunit_deleteTestCase);
151 }
152
153 CCUnitTestFixture* ccunit_newTestFixture (const char* name,
154                                           CCUnitTestFunc* setUp,
155                                           CCUnitTestFunc* tearDown)
156 {
157   CCUnitTestFixture* fixture = calloc (1, sizeof (*fixture));
158   ccunit_initTest (&fixture->test, ccunitTypeFixture, run, destroy);
159   fixture->name = safe_strdup (name);
160   ccunit_initList (&fixture->testCases);
161   fixture->setUp = setUp;
162   fixture->tearDown = tearDown;
163   return fixture;
164 }
165
166 inline struct CCUnitTestResult* ccunit_runTestFixture (CCUnitTestFixture* f)
167 {
168   CCUnitTestResult* result;
169   if (!f)
170     return NULL;
171   result = ccunit_newTestResult ();
172   if (!result)
173     return NULL;
174   f->test.run (&f->test, result);
175   return result;
176 }