Skip to content

Commit c8522b0

Browse files
committed
Bug Fix: ensure we stop unit test execution when an unexpected exception is raised in REQUIRE_* macros.
1 parent 856d881 commit c8522b0

File tree

2 files changed

+193
-0
lines changed

2 files changed

+193
-0
lines changed

UnitTest++/RequireMacros.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,13 @@
6262
message << "Unhandled exception (" << e.what() << ") in REQUIRE_CHECK(" #value ")"; \
6363
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
6464
message.GetText()); \
65+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
6566
}) \
6667
UT_CATCH_ALL \
6768
({ \
6869
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
6970
"Unhandled exception in REQUIRE_CHECK(" #value ")"); \
71+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
7072
}) \
7173
UNITTEST_MULTILINE_MACRO_END
7274

@@ -86,11 +88,13 @@
8688
message << "Unhandled exception (" << e.what() << ") in REQUIRE_EQUAL(" #expected ", " #actual ")"; \
8789
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
8890
message.GetText()); \
91+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
8992
}) \
9093
UT_CATCH_ALL \
9194
({ \
9295
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
9396
"Unhandled exception in REQUIRE_EQUAL(" #expected ", " #actual ")"); \
97+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
9498
}) \
9599
UNITTEST_MULTILINE_MACRO_END
96100

@@ -110,11 +114,13 @@
110114
message << "Unhandled exception (" << e.what() << ") in REQUIRE_CLOSE(" #expected ", " #actual ")"; \
111115
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
112116
message.GetText()); \
117+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
113118
}) \
114119
UT_CATCH_ALL \
115120
({ \
116121
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
117122
"Unhandled exception in REQUIRE_CLOSE(" #expected ", " #actual ")"); \
123+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
118124
}) \
119125
UNITTEST_MULTILINE_MACRO_END
120126

@@ -134,11 +140,13 @@
134140
message << "Unhandled exception (" << e.what() << ") in REQUIRE_ARRAY_EQUAL(" #expected ", " #actual ")"; \
135141
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
136142
message.GetText()); \
143+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
137144
}) \
138145
UT_CATCH_ALL \
139146
({ \
140147
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
141148
"Unhandled exception in REQUIRE_ARRAY_EQUAL(" #expected ", " #actual ")"); \
149+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
142150
}) \
143151
UNITTEST_MULTILINE_MACRO_END
144152

@@ -158,11 +166,13 @@
158166
message << "Unhandled exception (" << e.what() << ") in REQUIRE_ARRAY_CLOSE(" #expected ", " #actual ")"; \
159167
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
160168
message.GetText()); \
169+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
161170
}) \
162171
UT_CATCH_ALL \
163172
({ \
164173
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
165174
"Unhandled exception in REQUIRE_ARRAY_CLOSE(" #expected ", " #actual ")"); \
175+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
166176
}) \
167177
UNITTEST_MULTILINE_MACRO_END
168178

@@ -182,11 +192,13 @@
182192
message << "Unhandled exception (" << e.what() << ") in REQUIRE_ARRAY2D_CLOSE(" #expected ", " #actual ")"; \
183193
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
184194
message.GetText()); \
195+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
185196
}) \
186197
UT_CATCH_ALL \
187198
({ \
188199
UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), \
189200
"Unhandled exception in REQUIRE_ARRAY2D_CLOSE(" #expected ", " #actual ")"); \
201+
UT_THROW(UnitTest::RequiredCheckFailedException()); \
190202
}) \
191203
UNITTEST_MULTILINE_MACRO_END
192204

tests/TestRequireMacros.cpp

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,40 @@ TEST(RequiredCheckFailsOnFalse)
6060
CHECK(exception);
6161
}
6262

63+
bool ThrowsOnCall()
64+
{
65+
throw std::exception();
66+
return false;
67+
}
68+
69+
TEST(RequireCheckStopsTestOnException)
70+
{
71+
bool failure = false;
72+
bool continued = false;
73+
bool exception = false;
74+
75+
{
76+
UnitTest::TestResults testResults;
77+
ScopedCurrentTest scopedResults(testResults);
78+
79+
try
80+
{
81+
REQUIRE_CHECK(ThrowsOnCall());
82+
continued = true;
83+
}
84+
catch (const UnitTest::RequiredCheckFailedException&)
85+
{
86+
exception = true;
87+
}
88+
89+
failure = (testResults.GetFailureCount() > 0);
90+
}
91+
92+
CHECK(failure);
93+
CHECK(!continued);
94+
CHECK(exception);
95+
}
96+
6397
TEST(FailureReportsCorrectTestName)
6498
{
6599
RecordingReporter reporter;
@@ -149,6 +183,34 @@ TEST(RequiredCheckEqualFailsOnNotEqual)
149183
CHECK(exception);
150184
}
151185

186+
TEST(RequireEqualStopsTestOnException)
187+
{
188+
bool failure = false;
189+
bool continued = false;
190+
bool exception = false;
191+
192+
{
193+
UnitTest::TestResults testResults;
194+
ScopedCurrentTest scopedResults(testResults);
195+
196+
try
197+
{
198+
REQUIRE_EQUAL(false, ThrowsOnCall());
199+
continued = true;
200+
}
201+
catch (const UnitTest::RequiredCheckFailedException&)
202+
{
203+
exception = true;
204+
}
205+
206+
failure = (testResults.GetFailureCount() > 0);
207+
}
208+
209+
CHECK(failure);
210+
CHECK(!continued);
211+
CHECK(exception);
212+
}
213+
152214
TEST(RequiredCheckEqualFailureContainsCorrectDetails)
153215
{
154216
int line = 0;
@@ -267,6 +329,40 @@ TEST(RequiredCheckCloseFailsOnNotEqual)
267329
CHECK(exception);
268330
}
269331

332+
float ThrowsOnCallReturnsFloat()
333+
{
334+
throw std::exception();
335+
return 0.0f;
336+
}
337+
338+
TEST(RequireCloseStopsTestOnException)
339+
{
340+
bool failure = false;
341+
bool continued = false;
342+
bool exception = false;
343+
344+
{
345+
UnitTest::TestResults testResults;
346+
ScopedCurrentTest scopedResults(testResults);
347+
348+
try
349+
{
350+
REQUIRE_CLOSE(1.0f, ThrowsOnCallReturnsFloat(), 0.1f);
351+
continued = true;
352+
}
353+
catch (const UnitTest::RequiredCheckFailedException&)
354+
{
355+
exception = true;
356+
}
357+
358+
failure = (testResults.GetFailureCount() > 0);
359+
}
360+
361+
CHECK(failure);
362+
CHECK(!continued);
363+
CHECK(exception);
364+
}
365+
270366
TEST(RequiredCheckCloseFailureContainsCorrectDetails)
271367
{
272368
int line = 0;
@@ -382,6 +478,54 @@ TEST(RequiredCheckArrayCloseFailsOnNotEqual)
382478
CHECK(exception);
383479
}
384480

481+
// more convenient to use std::array<> here... not every compiler has it.
482+
template<typename Type, std::size_t Count>
483+
struct array_wrapper
484+
{
485+
Type operator[](std::size_t index) const
486+
{
487+
return values_[index];
488+
}
489+
490+
Type values_[Count];
491+
};
492+
493+
array_wrapper<int, 4> ThrowsOnCallReturnsArray()
494+
{
495+
throw std::exception();
496+
return array_wrapper<int, 4>();
497+
}
498+
499+
TEST(RequireCheckArrayStopsTestOnException)
500+
{
501+
bool failure = false;
502+
bool continued = false;
503+
bool exception = false;
504+
505+
{
506+
UnitTest::TestResults testResults;
507+
ScopedCurrentTest scopedResults(testResults);
508+
509+
int const data1[4] = { 0, 1, 2, 3 };
510+
511+
try
512+
{
513+
REQUIRE_ARRAY_CLOSE (data1, ThrowsOnCallReturnsArray(), 4, 0.01f);
514+
continued = true;
515+
}
516+
catch (const UnitTest::RequiredCheckFailedException&)
517+
{
518+
exception = true;
519+
}
520+
521+
failure = (testResults.GetFailureCount() > 0);
522+
}
523+
524+
CHECK(failure);
525+
CHECK(!continued);
526+
CHECK(exception);
527+
}
528+
385529
TEST(RequiredCheckArrayCloseFailureIncludesCheckExpectedAndActual)
386530
{
387531
RecordingReporter reporter;
@@ -660,6 +804,43 @@ TEST(RequiredCheckArray2DCloseFailsOnNotEqual)
660804
CHECK(exception);
661805
}
662806

807+
array_wrapper<array_wrapper<int, 2>, 2> ThrowsOnCallMultidimensionalArray()
808+
{
809+
throw std::exception();
810+
return array_wrapper<array_wrapper<int, 2>, 2>();
811+
}
812+
813+
TEST(RequiredCheckArray2DCloseStopsOnException)
814+
{
815+
bool failure = false;
816+
bool continued = false;
817+
bool exception = false;
818+
{
819+
RecordingReporter reporter;
820+
UnitTest::TestResults testResults(&reporter);
821+
ScopedCurrentTest scopedResults(testResults);
822+
823+
const float data[2][2] = { {0, 1}, {2, 3} };
824+
825+
try
826+
{
827+
REQUIRE_ARRAY2D_CLOSE(data, ThrowsOnCallMultidimensionalArray(), 2, 2, 0.01f);
828+
continued = true;
829+
}
830+
catch (const UnitTest::RequiredCheckFailedException&)
831+
{
832+
exception = true;
833+
}
834+
835+
failure = (testResults.GetFailureCount() > 0);
836+
}
837+
838+
CHECK(failure);
839+
CHECK(!continued);
840+
CHECK(exception);
841+
}
842+
843+
663844
TEST(RequiredCheckArray2DCloseFailureIncludesCheckExpectedAndActual)
664845
{
665846
RecordingReporter reporter;

0 commit comments

Comments
 (0)