1 /*
2 -------------------------------------------------------------------------
3  CxxTest: A lightweight C++ unit testing library.
4  Copyright (c) 2008 Sandia Corporation.
5  This software is distributed under the LGPL License v3
6  For more information, see the COPYING file in the top CxxTest directory.
7  Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
8  the U.S. Government retains certain rights in this software.
9 -------------------------------------------------------------------------
10 */
11 
12 #ifndef __cxxtest__RealDescriptions_cpp__
13 #define __cxxtest__RealDescriptions_cpp__
14 
15 //
16 // NOTE: If an error occur during world construction/deletion, CxxTest cannot
17 //       know where the error originated.
18 //
19 
20 #include <cxxtest/RealDescriptions.h>
21 
22 namespace CxxTest
23 {
RealTestDescription()24 RealTestDescription::RealTestDescription()
25 {
26 }
27 
RealTestDescription(List & argList,SuiteDescription & argSuite,unsigned argLine,const char * argTestName)28 RealTestDescription::RealTestDescription(List &argList,
29         SuiteDescription &argSuite,
30         unsigned argLine,
31         const char *argTestName)
32 {
33     initialize(argList, argSuite, argLine, argTestName);
34 }
35 
initialize(List & argList,SuiteDescription & argSuite,unsigned argLine,const char * argTestName)36 void RealTestDescription::initialize(List &argList,
37                                      SuiteDescription &argSuite,
38                                      unsigned argLine,
39                                      const char *argTestName)
40 {
41     _suite = &argSuite;
42     _line = argLine;
43     _testName = argTestName;
44     attach(argList);
45 }
46 
setUp()47 bool RealTestDescription::setUp()
48 {
49     if (!suite())
50     {
51         return false;
52     }
53 
54     for (GlobalFixture *gf = GlobalFixture::firstGlobalFixture(); gf != 0; gf = gf->nextGlobalFixture())
55     {
56         bool ok;
57         _TS_TRY { ok = gf->setUp(); }
58         _TS_LAST_CATCH( { ok = false; });
59 
60         if (!ok)
61         {
62             doFailTest(file(), line(), "Error in GlobalFixture::setUp()");
63             return false;
64         }
65     }
66 
67     _TS_TRY
68     {
69         bool ok = false;
70         _TSM_ASSERT_THROWS_NOTHING(file(), line(), "Exception thrown from setUp()", suite()->setUp(); ok = true);
71         if (ok == false) { return ok; }
72     }
73     _TS_CATCH_ABORT( { return false; })
74     _TS_CATCH_SKIPPED( { return false; });
75 
76     return true;
77 }
78 
tearDown()79 bool RealTestDescription::tearDown()
80 {
81     if (!suite())
82     {
83         return false;
84     }
85 
86     _TS_TRY
87     {
88         _TSM_ASSERT_THROWS_NOTHING(file(), line(), "Exception thrown from tearDown()", suite()->tearDown());
89     }
90     _TS_CATCH_ABORT( { return false; })
91     _TS_CATCH_SKIPPED( { return false; });
92 
93     for (GlobalFixture *gf = GlobalFixture::lastGlobalFixture(); gf != 0; gf = gf->prevGlobalFixture())
94     {
95         bool ok;
96         _TS_TRY { ok = gf->tearDown(); }
97         _TS_LAST_CATCH( { ok = false; });
98 
99         if (!ok)
100         {
101             doFailTest(file(), line(), "Error in GlobalFixture::tearDown()");
102             return false;
103         }
104     }
105 
106     return true;
107 }
108 
file() const109 const char *RealTestDescription::file() const { return _suite->file(); }
line() const110 int RealTestDescription::line() const { return _line; }
testName() const111 const char *RealTestDescription::testName() const { return _testName; }
suiteName() const112 const char *RealTestDescription::suiteName() const { return _suite->suiteName(); }
113 
next()114 TestDescription *RealTestDescription::next() { return (RealTestDescription *)Link::next(); }
next() const115 const TestDescription *RealTestDescription::next() const { return (const RealTestDescription *)Link::next(); }
116 
suite() const117 TestSuite *RealTestDescription::suite() const { return _suite->suite(); }
118 
run()119 void RealTestDescription::run()
120 {
121     _TS_TRY { runTest(); }
122     _TS_CATCH_ABORT( {})
123     _TS_CATCH_SKIPPED( {})
124     ___TSM_CATCH(file(), line(), "Exception thrown from test");
125 }
126 
RealSuiteDescription()127 RealSuiteDescription::RealSuiteDescription() {}
RealSuiteDescription(const char * argFile,unsigned argLine,const char * argSuiteName,List & argTests)128 RealSuiteDescription::RealSuiteDescription(const char *argFile,
129         unsigned argLine,
130         const char *argSuiteName,
131         List &argTests)
132 {
133     initialize(argFile, argLine, argSuiteName, argTests);
134 }
135 
initialize(const char * argFile,unsigned argLine,const char * argSuiteName,List & argTests)136 void RealSuiteDescription::initialize(const char *argFile,
137                                       unsigned argLine,
138                                       const char *argSuiteName,
139                                       List &argTests)
140 {
141     _file = argFile;
142     _line = argLine;
143     _suiteName = argSuiteName;
144     _tests = &argTests;
145 
146     attach(_suites);
147 }
148 
file() const149 const char *RealSuiteDescription::file() const { return _file; }
line() const150 int RealSuiteDescription::line() const { return _line; }
suiteName() const151 const char *RealSuiteDescription::suiteName() const { return _suiteName; }
152 
firstTest()153 TestDescription *RealSuiteDescription::firstTest() { return (RealTestDescription *)_tests->head(); }
firstTest() const154 const TestDescription *RealSuiteDescription::firstTest() const { return (const RealTestDescription *)_tests->head(); }
next()155 SuiteDescription *RealSuiteDescription::next() { return (RealSuiteDescription *)Link::next(); }
next() const156 const SuiteDescription *RealSuiteDescription::next() const { return (const RealSuiteDescription *)Link::next(); }
157 
numTests() const158 unsigned RealSuiteDescription::numTests() const { return _tests->size(); }
159 
testDescription(unsigned i) const160 const TestDescription &RealSuiteDescription::testDescription(unsigned i) const
161 {
162     return *(RealTestDescription *)_tests->nth(i);
163 }
164 
activateAllTests()165 void RealSuiteDescription::activateAllTests()
166 {
167     _tests->activateAll();
168 }
169 
leaveOnly(const char * testName)170 bool RealSuiteDescription::leaveOnly(const char *testName)
171 {
172     for (TestDescription *td = firstTest(); td != 0; td = td->next())
173     {
174         if (stringsEqual(td->testName(), testName))
175         {
176             _tests->leaveOnly(*td);
177             return true;
178         }
179     }
180     return false;
181 }
182 
StaticSuiteDescription()183 StaticSuiteDescription::StaticSuiteDescription() {}
StaticSuiteDescription(const char * argFile,unsigned argLine,const char * argSuiteName,TestSuite & argSuite,List & argTests)184 StaticSuiteDescription::StaticSuiteDescription(const char *argFile, unsigned argLine,
185         const char *argSuiteName, TestSuite &argSuite,
186         List &argTests) :
187     RealSuiteDescription(argFile, argLine, argSuiteName, argTests)
188 {
189     doInitialize(argSuite);
190 }
191 
initialize(const char * argFile,unsigned argLine,const char * argSuiteName,TestSuite & argSuite,List & argTests)192 void StaticSuiteDescription::initialize(const char *argFile, unsigned argLine,
193                                         const char *argSuiteName, TestSuite &argSuite,
194                                         List &argTests)
195 {
196     RealSuiteDescription::initialize(argFile, argLine, argSuiteName, argTests);
197     doInitialize(argSuite);
198 }
199 
doInitialize(TestSuite & argSuite)200 void StaticSuiteDescription::doInitialize(TestSuite &argSuite)
201 {
202     _suite = &argSuite;
203 }
204 
suite() const205 TestSuite *StaticSuiteDescription::suite() const
206 {
207     return _suite;
208 }
209 
setUp()210 bool StaticSuiteDescription::setUp() { return true; }
tearDown()211 bool StaticSuiteDescription::tearDown() { return true; }
212 
CommonDynamicSuiteDescription()213 CommonDynamicSuiteDescription::CommonDynamicSuiteDescription() {}
CommonDynamicSuiteDescription(const char * argFile,unsigned argLine,const char * argSuiteName,List & argTests,unsigned argCreateLine,unsigned argDestroyLine)214 CommonDynamicSuiteDescription::CommonDynamicSuiteDescription(const char *argFile, unsigned argLine,
215         const char *argSuiteName, List &argTests,
216         unsigned argCreateLine, unsigned argDestroyLine) :
217     RealSuiteDescription(argFile, argLine, argSuiteName, argTests)
218 {
219     doInitialize(argCreateLine, argDestroyLine);
220 }
221 
initialize(const char * argFile,unsigned argLine,const char * argSuiteName,List & argTests,unsigned argCreateLine,unsigned argDestroyLine)222 void CommonDynamicSuiteDescription::initialize(const char *argFile, unsigned argLine,
223         const char *argSuiteName, List &argTests,
224         unsigned argCreateLine, unsigned argDestroyLine)
225 {
226     RealSuiteDescription::initialize(argFile, argLine, argSuiteName, argTests);
227     doInitialize(argCreateLine, argDestroyLine);
228 }
229 
doInitialize(unsigned argCreateLine,unsigned argDestroyLine)230 void CommonDynamicSuiteDescription::doInitialize(unsigned argCreateLine, unsigned argDestroyLine)
231 {
232     _createLine = argCreateLine;
233     _destroyLine = argDestroyLine;
234 }
235 
suites()236 List &RealWorldDescription::suites()
237 {
238     return RealSuiteDescription::_suites;
239 }
240 
numSuites(void) const241 unsigned RealWorldDescription::numSuites(void) const
242 {
243     return suites().size();
244 }
245 
numTotalTests(void) const246 unsigned RealWorldDescription::numTotalTests(void) const
247 {
248     unsigned count = 0;
249     for (const SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next())
250     {
251         count += sd->numTests();
252     }
253     return count;
254 }
255 
firstSuite()256 SuiteDescription *RealWorldDescription::firstSuite()
257 {
258     return (RealSuiteDescription *)suites().head();
259 }
260 
firstSuite() const261 const SuiteDescription *RealWorldDescription::firstSuite() const
262 {
263     return (const RealSuiteDescription *)suites().head();
264 }
265 
suiteDescription(unsigned i) const266 const SuiteDescription &RealWorldDescription::suiteDescription(unsigned i) const
267 {
268     return *(const RealSuiteDescription *)suites().nth(i);
269 }
270 
activateAllTests()271 void RealWorldDescription::activateAllTests()
272 {
273     suites().activateAll();
274     for (SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next())
275     {
276         sd->activateAllTests();
277     }
278 }
279 
leaveOnly(const char * suiteName,const char * testName)280 bool RealWorldDescription::leaveOnly(const char *suiteName, const char *testName)
281 {
282     for (SuiteDescription *sd = firstSuite(); sd != 0; sd = sd->next())
283     {
284         if (stringsEqual(sd->suiteName(), suiteName))
285         {
286             if (testName)
287             {
288                 if (!sd->leaveOnly(testName))
289                 {
290                     return false;
291                 }
292             }
293             suites().leaveOnly(*sd);
294             return true;
295         }
296     }
297     return false;
298 }
299 
setUp()300 bool RealWorldDescription::setUp()
301 {
302     for (GlobalFixture *gf = GlobalFixture::firstGlobalFixture(); gf != 0; gf = gf->nextGlobalFixture())
303     {
304         bool ok;
305         _TS_TRY
306         {
307             ok = gf->setUpWorld();
308             if (tracker().testFailed())
309             {
310                 tracker().initialize();
311                 ok = false;
312             }
313         }
314         _TS_LAST_CATCH( { ok = false; });
315 
316         if (!ok)
317         {
318             reportError("Error setting up world");
319             return false;
320         }
321     }
322 
323     return true;
324 }
325 
tearDown()326 bool RealWorldDescription::tearDown()
327 {
328     for (GlobalFixture *gf = GlobalFixture::lastGlobalFixture(); gf != 0; gf = gf->prevGlobalFixture())
329     {
330         bool ok;
331         _TS_TRY { ok = gf->tearDownWorld(); }
332         _TS_LAST_CATCH( { ok = false; });
333 
334         if (!ok)
335         {
336             reportError("Error tearing down world");
337             return false;
338         }
339     }
340 
341     return true;
342 }
343 
reportError(const char * message)344 void RealWorldDescription::reportError(const char *message)
345 {
346     doWarn(__FILE__, 5, message);
347 }
348 
activateAllTests()349 void activateAllTests()
350 {
351     RealWorldDescription().activateAllTests();
352 }
353 
leaveOnly(const char * suiteName,const char * testName)354 bool leaveOnly(const char *suiteName, const char *testName)
355 {
356     return RealWorldDescription().leaveOnly(suiteName, testName);
357 }
358 }
359 
360 #endif // __cxxtest__RealDescriptions_cpp__
361 
362