Skip to content

Commit c8f551a

Browse files
committed
r9 | charles.nicholson | 2010-03-17 17:13:51 -0500 (Wed, 17 Mar 2010) | 1 line
setjmp/longjmp in place for assert handling when UNITTEST_USE_EXCEPTIONS is not defined
1 parent 3a40aa8 commit c8f551a

10 files changed

+150
-60
lines changed

src/CheckMacros.h

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "MemoryOutStream.h"
88
#include "TestDetails.h"
99
#include "CurrentTest.h"
10+
#include "ReportAssertImpl.h"
1011

1112
#ifdef CHECK
1213
#error UnitTest++ redefines CHECK
@@ -118,7 +119,7 @@
118119
} while (0)
119120

120121

121-
// CHECK_THROW only exists when UNITTEST_USE_EXCEPTIONS is defined (see Config.h)
122+
// CHECK_THROW and CHECK_ASSERT only exist when UNITTEST_USE_EXCEPTIONS is defined (see Config.h)
122123
#ifdef UNITTEST_USE_EXCEPTIONS
123124
#define CHECK_THROW(expression, ExpectedExceptionType) \
124125
do \
@@ -135,10 +136,9 @@
135136
#define CHECK_ASSERT(expression) \
136137
do \
137138
{ \
138-
UnitTest::ExpectAssert(true); \
139+
UnitTest::Detail::ExpectAssert(true); \
139140
CHECK_THROW(expression, UnitTest::AssertException); \
140-
UnitTest::ExpectAssert(false); \
141+
UnitTest::Detail::ExpectAssert(false); \
141142
} while(0)
142-
143-
#endif
144143
#endif
144+
#endif

src/ExecuteTest.h

Lines changed: 29 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
#ifndef UNITTEST_EXECUTE_TEST_H
22
#define UNITTEST_EXECUTE_TEST_H
33

4+
#include "Config.h"
45
#include "ExceptionMacros.h"
56
#include "TestDetails.h"
67
#include "MemoryOutStream.h"
78
#include "AssertException.h"
89
#include "CurrentTest.h"
910

11+
#ifndef UNITTEST_USE_EXCEPTIONS
12+
#include "ReportAssertImpl.h"
13+
#endif
14+
1015
#ifdef UNITTEST_POSIX
1116
#include "Posix/SignalTranslator.h"
1217
#endif
@@ -19,33 +24,33 @@ void ExecuteTest(T& testObject, TestDetails const& details, bool isMockTest)
1924
if (isMockTest == false)
2025
CurrentTest::Details() = &details;
2126

27+
#ifndef UNITTEST_USE_EXCEPTIONS
28+
if (UNITTEST_SET_ASSERT_JUMP_TARGET() == 0)
29+
{
30+
#endif
2231
#ifndef UNITTEST_POSIX
23-
UT_TRY
24-
({
25-
testObject.RunImpl();
26-
})
32+
UT_TRY({ testObject.RunImpl(); })
2733
#else
28-
UT_TRY
29-
({
30-
UNITTEST_THROW_SIGNALS_POSIX_ONLY
31-
testObject.RunImpl();
32-
})
34+
UT_TRY
35+
({
36+
UNITTEST_THROW_SIGNALS_POSIX_ONLY
37+
testObject.RunImpl();
38+
})
39+
#endif
40+
UT_CATCH(AssertException, e, { (void)e; })
41+
UT_CATCH(std::exception, e,
42+
{
43+
MemoryOutStream stream;
44+
stream << "Unhandled exception: " << e.what();
45+
CurrentTest::Results()->OnTestFailure(details, stream.GetText());
46+
})
47+
UT_CATCH_ALL
48+
({
49+
CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed");
50+
})
51+
#ifndef UNITTEST_USE_EXCEPTIONS
52+
}
3353
#endif
34-
35-
UT_CATCH(AssertException, e,
36-
{
37-
(void)e;
38-
})
39-
UT_CATCH(std::exception, e,
40-
{
41-
MemoryOutStream stream;
42-
stream << "Unhandled exception: " << e.what();
43-
CurrentTest::Results()->OnTestFailure(details, stream.GetText());
44-
})
45-
UT_CATCH_ALL
46-
({
47-
CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed");
48-
})
4954
}
5055

5156
}

src/ReportAssert.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#include "ReportAssert.h"
2+
#include "ReportAssertImpl.h"
23
#include "AssertException.h"
34
#include "CurrentTest.h"
45
#include "TestResults.h"
56
#include "TestDetails.h"
67

8+
#ifndef UNITTEST_USE_EXCEPTIONS
9+
#include "ReportAssertImpl.h"
10+
#endif
11+
712
namespace UnitTest {
813

914
namespace
@@ -17,9 +22,20 @@ namespace
1722

1823
void ReportAssert(char const* description, char const* filename, int lineNumber)
1924
{
20-
ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(), description, filename, lineNumber);
25+
Detail::ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(),
26+
description, filename, lineNumber);
2127
}
2228

29+
namespace Detail {
30+
31+
#ifndef UNITTEST_USE_EXCEPTIONS
32+
jmp_buf* GetAssertJmpBuf()
33+
{
34+
static jmp_buf s_jmpBuf;
35+
return &s_jmpBuf;
36+
}
37+
#endif
38+
2339
void ReportAssertEx(TestResults* testResults,
2440
const TestDetails* testDetails,
2541
char const* description,
@@ -36,6 +52,8 @@ void ReportAssertEx(TestResults* testResults,
3652

3753
#ifdef UNITTEST_USE_EXCEPTIONS
3854
throw AssertException();
55+
#else
56+
UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET();
3957
#endif
4058
}
4159

@@ -49,4 +67,4 @@ bool AssertExpected()
4967
return AssertExpectedFlag();
5068
}
5169

52-
}
70+
}}

src/ReportAssert.h

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,8 @@
33

44
namespace UnitTest {
55

6-
class TestResults;
7-
class TestDetails;
8-
96
void ReportAssert(char const* description, char const* filename, int lineNumber);
107

11-
void ReportAssertEx(TestResults* testResults,
12-
const TestDetails* testDetails,
13-
char const* description,
14-
char const* filename,
15-
int lineNumber);
16-
17-
void ExpectAssert(bool expected);
18-
bool AssertExpected();
19-
208
}
219

2210
#endif

src/ReportAssertImpl.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#ifndef UNITTEST_REPORTASSERTIMPL_H
2+
#define UNITTEST_REPORTASSERTIMPL_H
3+
4+
#include "Config.h"
5+
6+
#ifndef UNITTEST_USE_EXCEPTIONS
7+
#include <csetjmp>
8+
#endif
9+
10+
namespace UnitTest {
11+
12+
class TestResults;
13+
class TestDetails;
14+
15+
namespace Detail {
16+
17+
void ExpectAssert(bool expected);
18+
19+
void ReportAssertEx(TestResults* testResults,
20+
const TestDetails* testDetails,
21+
char const* description,
22+
char const* filename,
23+
int lineNumber);
24+
25+
bool AssertExpected();
26+
27+
#ifndef UNITTEST_USE_EXCEPTIONS
28+
jmp_buf* GetAssertJmpBuf();
29+
30+
#ifdef _MSC_VER
31+
#define UNITTEST_SET_ASSERT_JUMP_TARGET() \
32+
__pragma(warning(push)) __pragma(warning(disable:4611)) \
33+
setjmp(*UnitTest::Detail::GetAssertJmpBuf()) \
34+
__pragma(warning(pop))
35+
#else
36+
#define UNITTEST_SET_ASSERT_JUMP_TARGET() setjmp(*UnitTest::Detail::GetAssertJmpBuf())
37+
#endif
38+
39+
#define UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET() longjmp(*UnitTest::Detail::GetAssertJmpBuf(), 1)
40+
#endif
41+
42+
}
43+
}
44+
45+
#endif

src/TimeConstraint.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ TimeConstraint::~TimeConstraint()
2222
stream << "Time constraint failed. Expected to run test under " << m_maxMs <<
2323
"ms but took " << totalTimeInMs << "ms.";
2424

25-
UnitTest::CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());
25+
CurrentTest::Results()->OnTestFailure(m_details, stream.GetText());
2626
}
2727
}
2828

src/tests/TestAssertHandler.cpp

Lines changed: 39 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,23 @@
22

33
#include "../unittestpp.h"
44
#include "../ReportAssert.h"
5+
#include "../ReportAssertImpl.h"
56
#include "../AssertException.h"
67

78
#include "RecordingReporter.h"
9+
#include <csetjmp>
810

911
using namespace UnitTest;
1012

1113
namespace {
1214

1315
TEST(CanSetAssertExpected)
1416
{
15-
ExpectAssert(true);
16-
CHECK(AssertExpected());
17+
Detail::ExpectAssert(true);
18+
CHECK(Detail::AssertExpected());
1719

18-
ExpectAssert(false);
19-
CHECK(!AssertExpected());
20+
Detail::ExpectAssert(false);
21+
CHECK(!Detail::AssertExpected());
2022
}
2123

2224
#ifdef UNITTEST_USE_EXCEPTIONS
@@ -29,7 +31,7 @@ TEST(ReportAssertThrowsAssertException)
2931
{
3032
TestResults testResults;
3133
TestDetails testDetails("", "", "", 0);
32-
ReportAssertEx(&testResults, &testDetails, "", "", 0);
34+
Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
3335
}
3436
catch(AssertException const&)
3537
{
@@ -47,14 +49,14 @@ TEST(ReportAssertClearsExpectAssertFlag)
4749

4850
try
4951
{
50-
ExpectAssert(true);
51-
ReportAssertEx(&testResults, &testDetails, "", "", 0);
52+
Detail::ExpectAssert(true);
53+
Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
5254
}
5355
catch(AssertException const&)
5456
{
5557
}
5658

57-
CHECK(AssertExpected() == false);
59+
CHECK(Detail::AssertExpected() == false);
5860
CHECK_EQUAL(0, reporter.testFailedCount);
5961
}
6062

@@ -70,7 +72,7 @@ TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected)
7072

7173
try
7274
{
73-
ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber);
75+
Detail::ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber);
7476
}
7577
catch(AssertException const&)
7678
{
@@ -83,15 +85,15 @@ TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected)
8385

8486
TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected)
8587
{
86-
ExpectAssert(true);
88+
Detail::ExpectAssert(true);
8789

8890
RecordingReporter reporter;
8991
TestResults testResults(&reporter);
9092
TestDetails testDetails("", "", "", 0);
9193

9294
try
9395
{
94-
ReportAssertEx(&testResults, &testDetails, "", "", 0);
96+
Detail::ReportAssertEx(&testResults, &testDetails, "", "", 0);
9597
}
9698
catch(AssertException const&)
9799
{
@@ -100,12 +102,35 @@ TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected)
100102
CHECK_EQUAL(0, reporter.testFailedCount);
101103
}
102104

103-
#endif
104-
105105
TEST(CheckAssertMacroSetsAssertExpectationToFalseAfterRunning)
106106
{
107+
Detail::ExpectAssert(true);
107108
CHECK_ASSERT(ReportAssert("", "", 0));
108-
CHECK(!AssertExpected());
109+
CHECK(!Detail::AssertExpected());
110+
Detail::ExpectAssert(false);
111+
}
112+
113+
#else
114+
115+
TEST(SetAssertJumpTargetReturnsFalseWhenSettingJumpTarget)
116+
{
117+
CHECK(UNITTEST_SET_ASSERT_JUMP_TARGET() == false);
109118
}
110119

120+
TEST(JumpToAssertJumpTarget_JumpsToSetPoint_ReturnsTrue)
121+
{
122+
const volatile bool taken = !!UNITTEST_SET_ASSERT_JUMP_TARGET();
123+
124+
volatile bool set = false;
125+
if (taken == false)
126+
{
127+
UNITTEST_JUMP_TO_ASSERT_JUMP_TARGET();
128+
set = true;
129+
}
130+
131+
CHECK(set == false);
132+
}
133+
134+
#endif
135+
111136
}

src/tests/TestTestRunner.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../TestList.h"
55
#include "../TimeHelpers.h"
66
#include "../TimeConstraint.h"
7+
#include "../ReportAssertImpl.h"
78

89
using namespace UnitTest;
910

@@ -45,7 +46,7 @@ struct MockTest : public Test
4546
for (int i=0; i < count; ++i)
4647
{
4748
if (asserted)
48-
ReportAssertEx(testResults, &m_details, "desc", "file", 0);
49+
Detail::ReportAssertEx(testResults, &m_details, "desc", "file", 0);
4950
else if (!success)
5051
testResults->OnTestFailure(m_details, "message");
5152
}
@@ -124,6 +125,14 @@ TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing)
124125
CHECK_EQUAL(1, reporter.testFailedCount);
125126
}
126127

128+
TEST_FIXTURE(TestRunnerFixture, AssertingTestAbortsAsSoonAsAssertIsHit)
129+
{
130+
MockTest test("test", false, true, 3);
131+
list.Add(&test);
132+
runner.RunTestsIf(list, NULL, True(), 0);
133+
CHECK_EQUAL(1, reporter.summaryFailureCount);
134+
}
135+
127136
TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount)
128137
{
129138
MockTest test1("test", true, false);

src/tests/TestUnitTestPP.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
#include "../unittestpp.h"
2-
#include "../ReportAssert.h"
32
#include "ScopedCurrentTest.h"
43

54
// These are sample tests that show the different features of the framework

0 commit comments

Comments
 (0)