1 /*
2 * Copyright (c) 2007, Michael Feathers, James Grenning and Bas Vodde
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the <organization> nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE EARLIER MENTIONED AUTHORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL <copyright holder> BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "CppUTest/TestHarness.h"
29 #include "CppUTest/TestRegistry.h"
30 #include "CppUTest/PlatformSpecificFunctions.h"
31 #include "CppUTest/TestOutput.h"
32
doubles_equal(double d1,double d2,double threshold)33 bool doubles_equal(double d1, double d2, double threshold)
34 {
35 if (PlatformSpecificIsNan(d1) || PlatformSpecificIsNan(d2) || PlatformSpecificIsNan(threshold))
36 return false;
37
38 if (PlatformSpecificIsInf(d1) && PlatformSpecificIsInf(d2))
39 {
40 return true;
41 }
42
43 return PlatformSpecificFabs(d1 - d2) <= threshold;
44 }
45
46 /* Sometimes stubs use the CppUTest assertions.
47 * Its not correct to do so, but this small helper class will prevent a segmentation fault and instead
48 * will give an error message and also the file/line of the check that was executed outside the tests.
49 */
50 class OutsideTestRunnerUTest: public UtestShell
51 {
52 public:
53 static OutsideTestRunnerUTest& instance();
getTestResult()54 virtual TestResult& getTestResult()
55 {
56 return defaultTestResult;
57 }
~OutsideTestRunnerUTest()58 virtual ~OutsideTestRunnerUTest() _destructor_override
59 {
60 }
61 private:
OutsideTestRunnerUTest()62 OutsideTestRunnerUTest() :
63 UtestShell("\n\t NOTE: Assertion happened without being in a test run (perhaps in main?)", "\n\t Something is very wrong. Check this assertion and fix", "unknown file", 0),
64 defaultTestResult(defaultOutput)
65 {
66 }
67 ConsoleTestOutput defaultOutput;
68 TestResult defaultTestResult;
69 };
70
instance()71 OutsideTestRunnerUTest& OutsideTestRunnerUTest::instance()
72 {
73 static OutsideTestRunnerUTest instance_;
74 return instance_;
75 }
76
77 /*
78 * Below helpers are used for the PlatformSpecificSetJmp and LongJmp. They pass a method for what needs to happen after
79 * the jump, so that the stack stays right.
80 *
81 */
82
83 extern "C" {
84
helperDoTestSetup(void * data)85 static void helperDoTestSetup(void* data)
86 {
87 ((Utest*)data)->setup();
88 }
89
helperDoTestBody(void * data)90 static void helperDoTestBody(void* data)
91 {
92 ((Utest*)data)->testBody();
93 }
94
helperDoTestTeardown(void * data)95 static void helperDoTestTeardown(void* data)
96 {
97 ((Utest*)data)->teardown();
98 }
99
100 struct HelperTestRunInfo
101 {
HelperTestRunInfoHelperTestRunInfo102 HelperTestRunInfo(UtestShell* shell, TestPlugin* plugin, TestResult* result) : shell_(shell), plugin_(plugin), result_(result){}
103
104 UtestShell* shell_;
105 TestPlugin* plugin_;
106 TestResult* result_;
107 };
108
helperDoRunOneTestInCurrentProcess(void * data)109 static void helperDoRunOneTestInCurrentProcess(void* data)
110 {
111 HelperTestRunInfo* runInfo = (HelperTestRunInfo*) data;
112
113 UtestShell* shell = runInfo->shell_;
114 TestPlugin* plugin = runInfo->plugin_;
115 TestResult* result = runInfo->result_;
116
117 shell->runOneTestInCurrentProcess(plugin, *result);
118 }
119
helperDoRunOneTestSeperateProcess(void * data)120 static void helperDoRunOneTestSeperateProcess(void* data)
121 {
122 HelperTestRunInfo* runInfo = (HelperTestRunInfo*) data;
123
124 UtestShell* shell = runInfo->shell_;
125 TestPlugin* plugin = runInfo->plugin_;
126 TestResult* result = runInfo->result_;
127 PlatformSpecificRunTestInASeperateProcess(shell, plugin, result);
128 }
129
130 }
131
132 /******************************** */
133
UtestShell()134 UtestShell::UtestShell() :
135 group_("UndefinedTestGroup"), name_("UndefinedTest"), file_("UndefinedFile"), lineNumber_(0), next_(NULLPTR), isRunAsSeperateProcess_(false), hasFailed_(false)
136 {
137 }
138
UtestShell(const char * groupName,const char * testName,const char * fileName,size_t lineNumber)139 UtestShell::UtestShell(const char* groupName, const char* testName, const char* fileName, size_t lineNumber) :
140 group_(groupName), name_(testName), file_(fileName), lineNumber_(lineNumber), next_(NULLPTR), isRunAsSeperateProcess_(false), hasFailed_(false)
141 {
142 }
143
UtestShell(const char * groupName,const char * testName,const char * fileName,size_t lineNumber,UtestShell * nextTest)144 UtestShell::UtestShell(const char* groupName, const char* testName, const char* fileName, size_t lineNumber, UtestShell* nextTest) :
145 group_(groupName), name_(testName), file_(fileName), lineNumber_(lineNumber), next_(nextTest), isRunAsSeperateProcess_(false), hasFailed_(false)
146 {
147 }
148
~UtestShell()149 UtestShell::~UtestShell()
150 {
151 }
152
153 // LCOV_EXCL_START - actually covered but not in .gcno due to race condition
defaultCrashMethod()154 static void defaultCrashMethod()
155 {
156 UtestShell* ptr = (UtestShell*) NULLPTR; ptr->countTests();
157 }
158 // LCOV_EXCL_STOP
159
160 static void (*pleaseCrashMeRightNow) () = defaultCrashMethod;
161
setCrashMethod(void (* crashme)())162 void UtestShell::setCrashMethod(void (*crashme)())
163 {
164 pleaseCrashMeRightNow = crashme;
165 }
166
resetCrashMethod()167 void UtestShell::resetCrashMethod()
168 {
169 pleaseCrashMeRightNow = defaultCrashMethod;
170 }
171
crash()172 void UtestShell::crash()
173 {
174 pleaseCrashMeRightNow();
175 }
176
runOneTest(TestPlugin * plugin,TestResult & result)177 void UtestShell::runOneTest(TestPlugin* plugin, TestResult& result)
178 {
179 hasFailed_ = false;
180 result.countRun();
181 HelperTestRunInfo runInfo(this, plugin, &result);
182 if (isRunInSeperateProcess())
183 PlatformSpecificSetJmp(helperDoRunOneTestSeperateProcess, &runInfo);
184 else
185 PlatformSpecificSetJmp(helperDoRunOneTestInCurrentProcess, &runInfo);
186 }
187
createTest()188 Utest* UtestShell::createTest()
189 {
190 return new Utest();
191 }
192
destroyTest(Utest * test)193 void UtestShell::destroyTest(Utest* test)
194 {
195 delete test;
196 }
197
runOneTestInCurrentProcess(TestPlugin * plugin,TestResult & result)198 void UtestShell::runOneTestInCurrentProcess(TestPlugin* plugin, TestResult& result)
199 {
200 result.printVeryVerbose("\n-- before runAllPreTestAction: ");
201 plugin->runAllPreTestAction(*this, result);
202 result.printVeryVerbose("\n-- after runAllPreTestAction: ");
203
204 //save test context, so that test class can be tested
205 UtestShell* savedTest = UtestShell::getCurrent();
206 TestResult* savedResult = UtestShell::getTestResult();
207
208 UtestShell::setTestResult(&result);
209 UtestShell::setCurrentTest(this);
210
211 result.printVeryVerbose("\n---- before createTest: ");
212 Utest* testToRun = createTest();
213 result.printVeryVerbose("\n---- after createTest: ");
214
215 result.printVeryVerbose("\n------ before runTest: ");
216 testToRun->run();
217 result.printVeryVerbose("\n------ after runTest: ");
218
219 UtestShell::setCurrentTest(savedTest);
220 UtestShell::setTestResult(savedResult);
221
222 result.printVeryVerbose("\n---- before destroyTest: ");
223 destroyTest(testToRun);
224 result.printVeryVerbose("\n---- after destroyTest: ");
225
226 result.printVeryVerbose("\n-- before runAllPostTestAction: ");
227 plugin->runAllPostTestAction(*this, result);
228 result.printVeryVerbose("\n-- after runAllPostTestAction: ");
229 }
230
getNext() const231 UtestShell *UtestShell::getNext() const
232 {
233 return next_;
234 }
235
addTest(UtestShell * test)236 UtestShell* UtestShell::addTest(UtestShell *test)
237 {
238 next_ = test;
239 return this;
240 }
241
countTests()242 size_t UtestShell::countTests()
243 {
244 return next_ ? next_->countTests() + 1 : 1;
245 }
246
getMacroName() const247 SimpleString UtestShell::getMacroName() const
248 {
249 return "TEST";
250 }
251
getName() const252 const SimpleString UtestShell::getName() const
253 {
254 return SimpleString(name_);
255 }
256
getGroup() const257 const SimpleString UtestShell::getGroup() const
258 {
259 return SimpleString(group_);
260 }
261
getFormattedName() const262 SimpleString UtestShell::getFormattedName() const
263 {
264 SimpleString formattedName(getMacroName());
265 formattedName += "(";
266 formattedName += group_;
267 formattedName += ", ";
268 formattedName += name_;
269 formattedName += ")";
270
271 return formattedName;
272 }
273
hasFailed() const274 bool UtestShell::hasFailed() const
275 {
276 return hasFailed_;
277 }
278
countCheck()279 void UtestShell::countCheck()
280 {
281 getTestResult()->countCheck();
282 }
283
willRun() const284 bool UtestShell::willRun() const
285 {
286 return true;
287 }
288
isRunInSeperateProcess() const289 bool UtestShell::isRunInSeperateProcess() const
290 {
291 return isRunAsSeperateProcess_;
292 }
293
setRunInSeperateProcess()294 void UtestShell::setRunInSeperateProcess()
295 {
296 isRunAsSeperateProcess_ = true;
297 }
298
299
setRunIgnored()300 void UtestShell::setRunIgnored()
301 {
302
303 }
304
setFileName(const char * fileName)305 void UtestShell::setFileName(const char* fileName)
306 {
307 file_ = fileName;
308 }
309
setLineNumber(size_t lineNumber)310 void UtestShell::setLineNumber(size_t lineNumber)
311 {
312 lineNumber_ = lineNumber;
313 }
314
setGroupName(const char * groupName)315 void UtestShell::setGroupName(const char* groupName)
316 {
317 group_ = groupName;
318 }
319
setTestName(const char * testName)320 void UtestShell::setTestName(const char* testName)
321 {
322 name_ = testName;
323 }
324
getFile() const325 const SimpleString UtestShell::getFile() const
326 {
327 return SimpleString(file_);
328 }
329
getLineNumber() const330 size_t UtestShell::getLineNumber() const
331 {
332 return lineNumber_;
333 }
334
match(const char * target,const TestFilter * filters) const335 bool UtestShell::match(const char* target, const TestFilter* filters) const
336 {
337 if(filters == NULLPTR) return true;
338
339 for(; filters != NULLPTR; filters = filters->getNext())
340 if(filters->match(target)) return true;
341
342 return false;
343 }
344
shouldRun(const TestFilter * groupFilters,const TestFilter * nameFilters) const345 bool UtestShell::shouldRun(const TestFilter* groupFilters, const TestFilter* nameFilters) const
346 {
347 return match(group_, groupFilters) && match(name_, nameFilters);
348 }
349
failWith(const TestFailure & failure)350 void UtestShell::failWith(const TestFailure& failure)
351 {
352 failWith(failure, NormalTestTerminator());
353 } // LCOV_EXCL_LINE
354
failWith(const TestFailure & failure,const TestTerminator & terminator)355 void UtestShell::failWith(const TestFailure& failure, const TestTerminator& terminator)
356 {
357 hasFailed_ = true;
358 getTestResult()->addFailure(failure);
359 terminator.exitCurrentTest();
360 } // LCOV_EXCL_LINE
361
exitTest(const TestTerminator & terminator)362 void UtestShell::exitTest(const TestTerminator& terminator)
363 {
364 terminator.exitCurrentTest();
365 } // LCOV_EXCL_LINE
366
assertTrue(bool condition,const char * checkString,const char * conditionString,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)367 void UtestShell::assertTrue(bool condition, const char *checkString, const char *conditionString, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator)
368 {
369 getTestResult()->countCheck();
370 if (!condition)
371 failWith(CheckFailure(this, fileName, lineNumber, checkString, conditionString, text), testTerminator);
372 }
373
fail(const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)374 void UtestShell::fail(const char *text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
375 {
376 getTestResult()->countCheck();
377 failWith(FailFailure(this, fileName, lineNumber, text), testTerminator);
378 } // LCOV_EXCL_LINE
379
assertCstrEqual(const char * expected,const char * actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)380 void UtestShell::assertCstrEqual(const char* expected, const char* actual, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
381 {
382 getTestResult()->countCheck();
383 if (actual == NULLPTR && expected == NULLPTR) return;
384 if (actual == NULLPTR || expected == NULLPTR)
385 failWith(StringEqualFailure(this, fileName, lineNumber, expected, actual, text), testTerminator);
386 if (SimpleString::StrCmp(expected, actual) != 0)
387 failWith(StringEqualFailure(this, fileName, lineNumber, expected, actual, text), testTerminator);
388 }
389
assertCstrNEqual(const char * expected,const char * actual,size_t length,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)390 void UtestShell::assertCstrNEqual(const char* expected, const char* actual, size_t length, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
391 {
392 getTestResult()->countCheck();
393 if (actual == NULLPTR && expected == NULLPTR) return;
394 if (actual == NULLPTR || expected == NULLPTR)
395 failWith(StringEqualFailure(this, fileName, lineNumber, expected, actual, text), testTerminator);
396 if (SimpleString::StrNCmp(expected, actual, length) != 0)
397 failWith(StringEqualFailure(this, fileName, lineNumber, expected, actual, text), testTerminator);
398 }
399
assertCstrNoCaseEqual(const char * expected,const char * actual,const char * text,const char * fileName,size_t lineNumber)400 void UtestShell::assertCstrNoCaseEqual(const char* expected, const char* actual, const char* text, const char* fileName, size_t lineNumber)
401 {
402 getTestResult()->countCheck();
403 if (actual == NULLPTR && expected == NULLPTR) return;
404 if (actual == NULLPTR || expected == NULLPTR)
405 failWith(StringEqualNoCaseFailure(this, fileName, lineNumber, expected, actual, text));
406 if (!SimpleString(expected).equalsNoCase(actual))
407 failWith(StringEqualNoCaseFailure(this, fileName, lineNumber, expected, actual, text));
408 }
409
assertCstrContains(const char * expected,const char * actual,const char * text,const char * fileName,size_t lineNumber)410 void UtestShell::assertCstrContains(const char* expected, const char* actual, const char* text, const char* fileName, size_t lineNumber)
411 {
412 getTestResult()->countCheck();
413 if (actual == NULLPTR && expected == NULLPTR) return;
414 if (actual == NULLPTR || expected == NULLPTR)
415 failWith(ContainsFailure(this, fileName, lineNumber, expected, actual, text));
416 if (!SimpleString(actual).contains(expected))
417 failWith(ContainsFailure(this, fileName, lineNumber, expected, actual, text));
418 }
419
assertCstrNoCaseContains(const char * expected,const char * actual,const char * text,const char * fileName,size_t lineNumber)420 void UtestShell::assertCstrNoCaseContains(const char* expected, const char* actual, const char* text, const char* fileName, size_t lineNumber)
421 {
422 getTestResult()->countCheck();
423 if (actual == NULLPTR && expected == NULLPTR) return;
424 if (actual == NULLPTR || expected == NULLPTR)
425 failWith(ContainsFailure(this, fileName, lineNumber, expected, actual, text));
426 if (!SimpleString(actual).containsNoCase(expected))
427 failWith(ContainsFailure(this, fileName, lineNumber, expected, actual, text));
428 }
429
assertLongsEqual(long expected,long actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)430 void UtestShell::assertLongsEqual(long expected, long actual, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
431 {
432 getTestResult()->countCheck();
433 if (expected != actual)
434 failWith(LongsEqualFailure (this, fileName, lineNumber, expected, actual, text), testTerminator);
435 }
436
assertUnsignedLongsEqual(unsigned long expected,unsigned long actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)437 void UtestShell::assertUnsignedLongsEqual(unsigned long expected, unsigned long actual, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
438 {
439 getTestResult()->countCheck();
440 if (expected != actual)
441 failWith(UnsignedLongsEqualFailure (this, fileName, lineNumber, expected, actual, text), testTerminator);
442 }
443
assertLongLongsEqual(cpputest_longlong expected,cpputest_longlong actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)444 void UtestShell::assertLongLongsEqual(cpputest_longlong expected, cpputest_longlong actual, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
445 {
446 getTestResult()->countCheck();
447 #ifdef CPPUTEST_USE_LONG_LONG
448 if (expected != actual)
449 failWith(LongLongsEqualFailure(this, fileName, lineNumber, expected, actual, text), testTerminator);
450 #else
451 (void)expected;
452 (void)actual;
453 failWith(FeatureUnsupportedFailure(this, fileName, lineNumber, "CPPUTEST_USE_LONG_LONG", text), testTerminator);
454 #endif
455 }
456
assertUnsignedLongLongsEqual(cpputest_ulonglong expected,cpputest_ulonglong actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)457 void UtestShell::assertUnsignedLongLongsEqual(cpputest_ulonglong expected, cpputest_ulonglong actual, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
458 {
459 getTestResult()->countCheck();
460 #ifdef CPPUTEST_USE_LONG_LONG
461 if (expected != actual)
462 failWith(UnsignedLongLongsEqualFailure(this, fileName, lineNumber, expected, actual, text), testTerminator);
463 #else
464 (void)expected;
465 (void)actual;
466 failWith(FeatureUnsupportedFailure(this, fileName, lineNumber, "CPPUTEST_USE_LONG_LONG", text), testTerminator);
467 #endif
468 }
469
assertSignedBytesEqual(signed char expected,signed char actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)470 void UtestShell::assertSignedBytesEqual(signed char expected, signed char actual, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator)
471 {
472 getTestResult()->countCheck();
473 if (expected != actual)
474 failWith(SignedBytesEqualFailure (this, fileName, lineNumber, expected, actual, text), testTerminator);
475 }
476
assertPointersEqual(const void * expected,const void * actual,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)477 void UtestShell::assertPointersEqual(const void* expected, const void* actual, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
478 {
479 getTestResult()->countCheck();
480 if (expected != actual)
481 failWith(EqualsFailure(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual), text), testTerminator);
482 }
483
assertFunctionPointersEqual(void (* expected)(),void (* actual)(),const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)484 void UtestShell::assertFunctionPointersEqual(void (*expected)(), void (*actual)(), const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
485 {
486 getTestResult()->countCheck();
487 if (expected != actual)
488 failWith(EqualsFailure(this, fileName, lineNumber, StringFrom(expected), StringFrom(actual), text), testTerminator);
489 }
490
assertDoublesEqual(double expected,double actual,double threshold,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)491 void UtestShell::assertDoublesEqual(double expected, double actual, double threshold, const char* text, const char* fileName, size_t lineNumber, const TestTerminator& testTerminator)
492 {
493 getTestResult()->countCheck();
494 if (!doubles_equal(expected, actual, threshold))
495 failWith(DoublesEqualFailure(this, fileName, lineNumber, expected, actual, threshold, text), testTerminator);
496 }
497
assertBinaryEqual(const void * expected,const void * actual,size_t length,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)498 void UtestShell::assertBinaryEqual(const void *expected, const void *actual, size_t length, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator)
499 {
500 getTestResult()->countCheck();
501 if (length == 0) return;
502 if (actual == NULLPTR && expected == NULLPTR) return;
503 if (actual == NULLPTR || expected == NULLPTR)
504 failWith(BinaryEqualFailure(this, fileName, lineNumber, (const unsigned char *) expected, (const unsigned char *) actual, length, text), testTerminator);
505 if (SimpleString::MemCmp(expected, actual, length) != 0)
506 failWith(BinaryEqualFailure(this, fileName, lineNumber, (const unsigned char *) expected, (const unsigned char *) actual, length, text), testTerminator);
507 }
508
assertBitsEqual(unsigned long expected,unsigned long actual,unsigned long mask,size_t byteCount,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)509 void UtestShell::assertBitsEqual(unsigned long expected, unsigned long actual, unsigned long mask, size_t byteCount, const char* text, const char *fileName, size_t lineNumber, const TestTerminator& testTerminator)
510 {
511 getTestResult()->countCheck();
512 if ((expected & mask) != (actual & mask))
513 failWith(BitsEqualFailure(this, fileName, lineNumber, expected, actual, mask, byteCount, text), testTerminator);
514 }
515
assertEquals(bool failed,const char * expected,const char * actual,const char * text,const char * file,size_t line,const TestTerminator & testTerminator)516 void UtestShell::assertEquals(bool failed, const char* expected, const char* actual, const char* text, const char* file, size_t line, const TestTerminator& testTerminator)
517 {
518 getTestResult()->countCheck();
519 if (failed)
520 failWith(CheckEqualFailure(this, file, line, expected, actual, text), testTerminator);
521 }
522
assertCompare(bool comparison,const char * checkString,const char * comparisonString,const char * text,const char * fileName,size_t lineNumber,const TestTerminator & testTerminator)523 void UtestShell::assertCompare(bool comparison, const char *checkString, const char *comparisonString, const char *text, const char *fileName, size_t lineNumber, const TestTerminator &testTerminator)
524 {
525 getTestResult()->countCheck();
526 if (!comparison)
527 failWith(ComparisonFailure(this, fileName, lineNumber, checkString, comparisonString, text), testTerminator);
528 }
529
print(const char * text,const char * fileName,size_t lineNumber)530 void UtestShell::print(const char *text, const char* fileName, size_t lineNumber)
531 {
532 SimpleString stringToPrint = "\n";
533 stringToPrint += fileName;
534 stringToPrint += ":";
535 stringToPrint += StringFrom(lineNumber);
536 stringToPrint += " ";
537 stringToPrint += text;
538 getTestResult()->print(stringToPrint.asCharString());
539 }
540
print(const SimpleString & text,const char * fileName,size_t lineNumber)541 void UtestShell::print(const SimpleString& text, const char* fileName, size_t lineNumber)
542 {
543 print(text.asCharString(), fileName, lineNumber);
544 }
545
printVeryVerbose(const char * text)546 void UtestShell::printVeryVerbose(const char* text)
547 {
548 getTestResult()->printVeryVerbose(text);
549 }
550
551 TestResult* UtestShell::testResult_ = NULLPTR;
552 UtestShell* UtestShell::currentTest_ = NULLPTR;
553
setTestResult(TestResult * result)554 void UtestShell::setTestResult(TestResult* result)
555 {
556 testResult_ = result;
557 }
558
setCurrentTest(UtestShell * test)559 void UtestShell::setCurrentTest(UtestShell* test)
560 {
561 currentTest_ = test;
562 }
563
getTestResult()564 TestResult* UtestShell::getTestResult()
565 {
566 if (testResult_ == NULLPTR)
567 return &OutsideTestRunnerUTest::instance().getTestResult();
568 return testResult_;
569 }
570
getCurrent()571 UtestShell* UtestShell::getCurrent()
572 {
573 if (currentTest_ == NULLPTR)
574 return &OutsideTestRunnerUTest::instance();
575 return currentTest_;
576 }
577
578
~ExecFunctionTestShell()579 ExecFunctionTestShell::~ExecFunctionTestShell()
580 {
581 }
582
583 ////////////// Utest ////////////
584
Utest()585 Utest::Utest()
586 {
587 }
588
~Utest()589 Utest::~Utest()
590 {
591 }
592
593 #if CPPUTEST_USE_STD_CPP_LIB
594
run()595 void Utest::run()
596 {
597 UtestShell* current = UtestShell::getCurrent();
598 int jumpResult = 0;
599 try {
600 current->printVeryVerbose("\n-------- before setup: ");
601 jumpResult = PlatformSpecificSetJmp(helperDoTestSetup, this);
602 current->printVeryVerbose("\n-------- after setup: ");
603
604 if (jumpResult) {
605 current->printVeryVerbose("\n---------- before body: ");
606 PlatformSpecificSetJmp(helperDoTestBody, this);
607 current->printVeryVerbose("\n---------- after body: ");
608 }
609 }
610 catch (CppUTestFailedException&)
611 {
612 PlatformSpecificRestoreJumpBuffer();
613 }
614
615 try {
616 current->printVeryVerbose("\n-------- before teardown: ");
617 PlatformSpecificSetJmp(helperDoTestTeardown, this);
618 current->printVeryVerbose("\n-------- after teardown: ");
619 }
620 catch (CppUTestFailedException&)
621 {
622 PlatformSpecificRestoreJumpBuffer();
623 }
624
625 }
626 #else
627
run()628 void Utest::run()
629 {
630 if (PlatformSpecificSetJmp(helperDoTestSetup, this)) {
631 PlatformSpecificSetJmp(helperDoTestBody, this);
632 }
633 PlatformSpecificSetJmp(helperDoTestTeardown, this);
634 }
635
636 #endif
637
setup()638 void Utest::setup()
639 {
640 }
641
testBody()642 void Utest::testBody()
643 {
644 }
645
teardown()646 void Utest::teardown()
647 {
648 }
649
650
651 /////////////////// Terminators
652
~TestTerminator()653 TestTerminator::~TestTerminator()
654 {
655 }
656
exitCurrentTest() const657 void NormalTestTerminator::exitCurrentTest() const
658 {
659 #if CPPUTEST_USE_STD_CPP_LIB
660 throw CppUTestFailedException();
661 #else
662 TestTerminatorWithoutExceptions().exitCurrentTest();
663 #endif
664 }
665
~NormalTestTerminator()666 NormalTestTerminator::~NormalTestTerminator()
667 {
668 }
669
exitCurrentTest() const670 void TestTerminatorWithoutExceptions::exitCurrentTest() const
671 {
672 PlatformSpecificLongJmp();
673 } // LCOV_EXCL_LINE
674
~TestTerminatorWithoutExceptions()675 TestTerminatorWithoutExceptions::~TestTerminatorWithoutExceptions()
676 {
677 }
678
679 //////////////////// ExecFunction
680 //
ExecFunction()681 ExecFunction::ExecFunction()
682 {
683 }
684
~ExecFunction()685 ExecFunction::~ExecFunction()
686 {
687 }
688
ExecFunctionWithoutParameters(void (* testFunction)())689 ExecFunctionWithoutParameters::ExecFunctionWithoutParameters(void(*testFunction)())
690 : testFunction_(testFunction)
691 {
692 }
693
~ExecFunctionWithoutParameters()694 ExecFunctionWithoutParameters::~ExecFunctionWithoutParameters()
695 {
696 }
697
exec()698 void ExecFunctionWithoutParameters::exec()
699 {
700 if (testFunction_)
701 testFunction_();
702 }
703
704 //////////////////// ExecFunctionTest
705
ExecFunctionTest(ExecFunctionTestShell * shell)706 ExecFunctionTest::ExecFunctionTest(ExecFunctionTestShell* shell)
707 : shell_(shell)
708 {
709 }
710
testBody()711 void ExecFunctionTest::testBody()
712 {
713 if (shell_->testFunction_) shell_->testFunction_->exec();
714 }
715
setup()716 void ExecFunctionTest::setup()
717 {
718 if (shell_->setup_) shell_->setup_();
719 }
720
teardown()721 void ExecFunctionTest::teardown()
722 {
723 if (shell_->teardown_) shell_->teardown_();
724 }
725
726 /////////////// IgnoredUtestShell /////////////
IgnoredUtestShell()727 IgnoredUtestShell::IgnoredUtestShell(): runIgnored_(false)
728 {
729 }
730
IgnoredUtestShell(const char * groupName,const char * testName,const char * fileName,size_t lineNumber)731 IgnoredUtestShell::IgnoredUtestShell(const char* groupName, const char* testName, const char* fileName, size_t lineNumber) :
732 UtestShell(groupName, testName, fileName, lineNumber), runIgnored_(false)
733 {
734 }
735
~IgnoredUtestShell()736 IgnoredUtestShell::~IgnoredUtestShell()
737 {
738 }
739
willRun() const740 bool IgnoredUtestShell::willRun() const
741 {
742 if (runIgnored_) return UtestShell::willRun();
743
744 return false;
745 }
746
getMacroName() const747 SimpleString IgnoredUtestShell::getMacroName() const
748 {
749 if (runIgnored_) return "TEST";
750
751 return "IGNORE_TEST";
752 }
753
runOneTest(TestPlugin * plugin,TestResult & result)754 void IgnoredUtestShell::runOneTest(TestPlugin* plugin, TestResult& result)
755 {
756 if (runIgnored_)
757 {
758 UtestShell::runOneTest(plugin, result);
759 return;
760 }
761
762 result.countIgnored();
763 }
764
setRunIgnored()765 void IgnoredUtestShell::setRunIgnored()
766 {
767 runIgnored_ = true;
768 }
769
770 //////////////////// UtestShellPointerArray
771
UtestShellPointerArray(UtestShell * firstTest)772 UtestShellPointerArray::UtestShellPointerArray(UtestShell* firstTest)
773 : arrayOfTests_(NULLPTR), count_(0)
774 {
775 count_ = (firstTest) ? firstTest->countTests() : 0;
776 if (count_ == 0) return;
777
778 arrayOfTests_ = new UtestShell*[count_];
779
780 UtestShell*currentTest = firstTest;
781 for (size_t i = 0; i < count_; i++)
782 {
783 arrayOfTests_[i] = currentTest;
784 currentTest = currentTest->getNext();
785 }
786 }
787
~UtestShellPointerArray()788 UtestShellPointerArray::~UtestShellPointerArray()
789 {
790 delete [] arrayOfTests_;
791 }
792
swap(size_t index1,size_t index2)793 void UtestShellPointerArray::swap(size_t index1, size_t index2)
794 {
795 UtestShell* e2 = arrayOfTests_[index2];
796 UtestShell* e1 = arrayOfTests_[index1];
797 arrayOfTests_[index1] = e2;
798 arrayOfTests_[index2] = e1;
799 }
800
shuffle(size_t seed)801 void UtestShellPointerArray::shuffle(size_t seed)
802 {
803 if (count_ == 0) return;
804
805 PlatformSpecificSrand((unsigned int) seed);
806
807 for (size_t i = count_ - 1; i >= 1; --i)
808 {
809 if (count_ == 0) return;
810
811 const size_t j = ((size_t)PlatformSpecificRand()) % (i + 1); // distribution biased by modulo, but good enough for shuffling
812 swap(i, j);
813 }
814 relinkTestsInOrder();
815 }
816
reverse()817 void UtestShellPointerArray::reverse()
818 {
819 if (count_ == 0) return;
820
821 size_t halfCount = count_ / 2;
822 for (size_t i = 0; i < halfCount; i++)
823 {
824 size_t j = count_ - i - 1;
825 swap(i, j);
826 }
827 relinkTestsInOrder();
828 }
829
relinkTestsInOrder()830 void UtestShellPointerArray::relinkTestsInOrder()
831 {
832 UtestShell *tests = NULLPTR;
833 for (size_t i = 0; i < count_; i++)
834 tests = arrayOfTests_[count_ - i - 1]->addTest(tests);
835 }
836
getFirstTest() const837 UtestShell* UtestShellPointerArray::getFirstTest() const
838 {
839 return get(0);
840 }
841
get(size_t index) const842 UtestShell* UtestShellPointerArray::get(size_t index) const
843 {
844 if (index >= count_) return NULLPTR;
845 return arrayOfTests_[index];
846 }
847
848
849
850 ////////////// TestInstaller ////////////
851
TestInstaller(UtestShell & shell,const char * groupName,const char * testName,const char * fileName,size_t lineNumber)852 TestInstaller::TestInstaller(UtestShell& shell, const char* groupName, const char* testName, const char* fileName, size_t lineNumber)
853 {
854 shell.setGroupName(groupName);
855 shell.setTestName(testName);
856 shell.setFileName(fileName);
857 shell.setLineNumber(lineNumber);
858 TestRegistry::getCurrentRegistry()->addTest(&shell);
859 }
860
~TestInstaller()861 TestInstaller::~TestInstaller()
862 {
863 }
864
unDo()865 void TestInstaller::unDo()
866 {
867 TestRegistry::getCurrentRegistry()->unDoLastAddTest();
868 }
869