diff --git a/src/AssertException.cpp b/src/AssertException.cpp index 0ac4484..cc2c7e1 100644 --- a/src/AssertException.cpp +++ b/src/AssertException.cpp @@ -2,38 +2,16 @@ #ifdef UNITTEST_USE_EXCEPTIONS -#include - namespace UnitTest { -AssertException::AssertException(char const* description, char const* filename, int lineNumber) - : m_lineNumber(lineNumber) +AssertException::AssertException() { - using namespace std; - - strcpy(m_description, description); - strcpy(m_filename, filename); } AssertException::~AssertException() { } -char const* AssertException::what() const -{ - return m_description; -} - -char const* AssertException::Filename() const -{ - return m_filename; -} - -int AssertException::LineNumber() const -{ - return m_lineNumber; -} - } #endif diff --git a/src/AssertException.h b/src/AssertException.h index 72200c8..4603827 100644 --- a/src/AssertException.h +++ b/src/AssertException.h @@ -12,18 +12,8 @@ namespace UnitTest { class AssertException : public std::exception { public: - AssertException(char const* description, char const* filename, int lineNumber); + AssertException(); virtual ~AssertException(); - - virtual char const* what() const; - - char const* Filename() const; - int LineNumber() const; - -private: - char m_description[512]; - char m_filename[256]; - int m_lineNumber; }; } diff --git a/src/CheckMacros.h b/src/CheckMacros.h index 89384c3..5523b3c 100644 --- a/src/CheckMacros.h +++ b/src/CheckMacros.h @@ -130,10 +130,15 @@ if (!caught_) \ UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(*UnitTest::CurrentTest::Details(), __LINE__), "Expected exception: \"" #ExpectedExceptionType "\" not thrown"); \ } while(0) -#endif #define CHECK_ASSERT(expression) \ - CHECK_THROW(expression, UnitTest::AssertException); + do \ + { \ + UnitTest::ExpectAssert(true); \ + CHECK_THROW(expression, UnitTest::AssertException); \ + UnitTest::ExpectAssert(false); \ + } while(0) #endif +#endif diff --git a/src/ExecuteTest.h b/src/ExecuteTest.h index c09eca2..0c37eb3 100644 --- a/src/ExecuteTest.h +++ b/src/ExecuteTest.h @@ -14,9 +14,10 @@ namespace UnitTest { template< typename T > -void ExecuteTest(T& testObject, TestDetails const& details) +void ExecuteTest(T& testObject, TestDetails const& details, bool isMockTest) { - CurrentTest::Details() = &details; + if (isMockTest == false) + CurrentTest::Details() = &details; #ifndef UNITTEST_POSIX UT_TRY @@ -33,8 +34,7 @@ void ExecuteTest(T& testObject, TestDetails const& details) UT_CATCH(AssertException, e, { - CurrentTest::Results()->OnTestFailure( - TestDetails(details.testName, details.suiteName, e.Filename(), e.LineNumber()), e.what()); + (void)e; }) UT_CATCH(std::exception, e, { @@ -44,7 +44,7 @@ void ExecuteTest(T& testObject, TestDetails const& details) }) UT_CATCH_ALL ({ - CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: Crash!"); + CurrentTest::Results()->OnTestFailure(details, "Unhandled exception: test crashed"); }) } diff --git a/src/ReportAssert.cpp b/src/ReportAssert.cpp index 0386b62..fb4d043 100644 --- a/src/ReportAssert.cpp +++ b/src/ReportAssert.cpp @@ -1,17 +1,52 @@ #include "ReportAssert.h" #include "AssertException.h" +#include "CurrentTest.h" +#include "TestResults.h" +#include "TestDetails.h" namespace UnitTest { +namespace +{ + bool& AssertExpectedFlag() + { + static bool s_assertExpected = false; + return s_assertExpected; + } +} + void ReportAssert(char const* description, char const* filename, int lineNumber) { - (void)description; - (void)filename; - (void)lineNumber; + ReportAssertEx(CurrentTest::Results(), CurrentTest::Details(), description, filename, lineNumber); +} + +void ReportAssertEx(TestResults* testResults, + const TestDetails* testDetails, + char const* description, + char const* filename, + int lineNumber) +{ + if (AssertExpectedFlag() == false) + { + TestDetails assertDetails(testDetails->testName, testDetails->suiteName, filename, lineNumber); + testResults->OnTestFailure(assertDetails, description); + } + + ExpectAssert(false); #ifdef UNITTEST_USE_EXCEPTIONS - throw AssertException(description, filename, lineNumber); + throw AssertException(); #endif } +void ExpectAssert(bool expected) +{ + AssertExpectedFlag() = expected; +} + +bool AssertExpected() +{ + return AssertExpectedFlag(); +} + } diff --git a/src/ReportAssert.h b/src/ReportAssert.h index a000e15..253229a 100644 --- a/src/ReportAssert.h +++ b/src/ReportAssert.h @@ -3,8 +3,20 @@ namespace UnitTest { +class TestResults; +class TestDetails; + void ReportAssert(char const* description, char const* filename, int lineNumber); - + +void ReportAssertEx(TestResults* testResults, + const TestDetails* testDetails, + char const* description, + char const* filename, + int lineNumber); + +void ExpectAssert(bool expected); +bool AssertExpected(); + } #endif diff --git a/src/Test.cpp b/src/Test.cpp index 6b63041..d00749c 100644 --- a/src/Test.cpp +++ b/src/Test.cpp @@ -20,8 +20,9 @@ TestList& Test::GetTestList() Test::Test(char const* testName, char const* suiteName, char const* filename, int lineNumber) : m_details(testName, suiteName, filename, lineNumber) - , next(0) + , m_nextTest(0) , m_timeConstraintExempt(false) + , m_isMockTest(false) { } @@ -31,7 +32,7 @@ Test::~Test() void Test::Run() { - ExecuteTest(*this, m_details); + ExecuteTest(*this, m_details, m_isMockTest); } void Test::RunImpl() const diff --git a/src/Test.h b/src/Test.h index 436dbc1..7c2f175 100644 --- a/src/Test.h +++ b/src/Test.h @@ -16,8 +16,9 @@ public: void Run(); TestDetails const m_details; - Test* next; + Test* m_nextTest; mutable bool m_timeConstraintExempt; + mutable bool m_isMockTest; static TestList& GetTestList(); diff --git a/src/TestList.cpp b/src/TestList.cpp index 4f58034..38fbfec 100644 --- a/src/TestList.cpp +++ b/src/TestList.cpp @@ -21,7 +21,7 @@ void TestList::Add(Test* test) } else { - m_tail->next = test; + m_tail->m_nextTest = test; m_tail = test; } } diff --git a/src/TestMacros.h b/src/TestMacros.h index 8aad30e..912f8ca 100644 --- a/src/TestMacros.h +++ b/src/TestMacros.h @@ -83,11 +83,11 @@ ({ \ Fixture##Name##Helper fixtureHelper(m_details); \ ctorOk = true; \ - UnitTest::ExecuteTest(fixtureHelper, m_details); \ + UnitTest::ExecuteTest(fixtureHelper, m_details, false); \ }) \ UT_CATCH (UnitTest::AssertException, e, \ { \ - UnitTest::CurrentTest::Results()->OnTestFailure(UnitTest::TestDetails(m_details.testName, m_details.suiteName, e.Filename(), e.LineNumber()), e.what()); \ + (void)e; \ }) \ UT_CATCH (std::exception, e, \ { \ diff --git a/src/TestRunner.cpp b/src/TestRunner.cpp index b7fcb62..108348e 100644 --- a/src/TestRunner.cpp +++ b/src/TestRunner.cpp @@ -32,6 +32,11 @@ TestRunner::~TestRunner() delete m_timer; } +TestResults* TestRunner::GetTestResults() +{ + return m_result; +} + int TestRunner::Finish() const { float const secondsElapsed = static_cast(m_timer->GetTimeInMs() / 1000.0); @@ -51,7 +56,8 @@ bool TestRunner::IsTestInSuite(const Test* const curTest, char const* suiteName) void TestRunner::RunTest(TestResults* const result, Test* const curTest, int const maxTestTimeInMs) const { - CurrentTest::Results() = result; + if (curTest->m_isMockTest == false) + CurrentTest::Results() = result; Timer testTimer; testTimer.Start(); @@ -70,7 +76,7 @@ void TestRunner::RunTest(TestResults* const result, Test* const curTest, int con result->OnTestFailure(curTest->m_details, stream.GetText()); } - result->OnTestFinish(curTest->m_details, static_cast(testTimeInMs/1000.0)); + result->OnTestFinish(curTest->m_details, static_cast< float >(testTimeInMs / 1000.0)); } } diff --git a/src/TestRunner.h b/src/TestRunner.h index 2ad6e5c..27ec9c6 100644 --- a/src/TestRunner.h +++ b/src/TestRunner.h @@ -27,7 +27,7 @@ public: explicit TestRunner(TestReporter& reporter); ~TestRunner(); - template + template< class Predicate > int RunTestsIf(TestList const& list, char const* suiteName, const Predicate& predicate, int maxTestTimeInMs) const { @@ -38,12 +38,14 @@ public: if (IsTestInSuite(curTest, suiteName) && predicate(curTest)) RunTest(m_result, curTest, maxTestTimeInMs); - curTest = curTest->next; + curTest = curTest->m_nextTest; } return Finish(); } + TestResults* GetTestResults(); + private: TestReporter* m_reporter; TestResults* m_result; diff --git a/src/tests/TestAssertHandler.cpp b/src/tests/TestAssertHandler.cpp index 664a670..6116b19 100644 --- a/src/tests/TestAssertHandler.cpp +++ b/src/tests/TestAssertHandler.cpp @@ -1,49 +1,111 @@ #include "../Config.h" -#ifdef UNITTEST_USE_EXCEPTIONS - #include "../unittestpp.h" -#include "../AssertException.h" #include "../ReportAssert.h" +#include "../AssertException.h" + +#include "RecordingReporter.h" using namespace UnitTest; namespace { +TEST(CanSetAssertExpected) +{ + ExpectAssert(true); + CHECK(AssertExpected()); + + ExpectAssert(false); + CHECK(!AssertExpected()); +} + +#ifdef UNITTEST_USE_EXCEPTIONS + TEST(ReportAssertThrowsAssertException) { bool caught = false; try { - ReportAssert("", "", 0); + TestResults testResults; + TestDetails testDetails("", "", "", 0); + ReportAssertEx(&testResults, &testDetails, "", "", 0); } catch(AssertException const&) { caught = true; } - CHECK (true == caught); + CHECK(true == caught); } -TEST(ReportAssertSetsCorrectInfoInException) +TEST(ReportAssertClearsExpectAssertFlag) +{ + RecordingReporter reporter; + TestResults testResults(&reporter); + TestDetails testDetails("", "", "", 0); + + try + { + ExpectAssert(true); + ReportAssertEx(&testResults, &testDetails, "", "", 0); + } + catch(AssertException const&) + { + } + + CHECK(AssertExpected() == false); + CHECK_EQUAL(0, reporter.testFailedCount); +} + +TEST(ReportAssertWritesFailureToResultsAndDetailsWhenAssertIsNotExpected) { const int lineNumber = 12345; const char* description = "description"; const char* filename = "filename"; + RecordingReporter reporter; + TestResults testResults(&reporter); + TestDetails testDetails("", "", "", 0); + try { - ReportAssert(description, filename, lineNumber); + ReportAssertEx(&testResults, &testDetails, description, filename, lineNumber); } - catch(AssertException const& e) + catch(AssertException const&) { - CHECK_EQUAL(description, e.what()); - CHECK_EQUAL(filename, e.Filename()); - CHECK_EQUAL(lineNumber, e.LineNumber()); } + + CHECK_EQUAL(description, reporter.lastFailedMessage); + CHECK_EQUAL(filename, reporter.lastFailedFile); + CHECK_EQUAL(lineNumber, reporter.lastFailedLine); } +TEST(ReportAssertReportsNoErrorsWhenAssertIsExpected) +{ + ExpectAssert(true); + + RecordingReporter reporter; + TestResults testResults(&reporter); + TestDetails testDetails("", "", "", 0); + + try + { + ReportAssertEx(&testResults, &testDetails, "", "", 0); + } + catch(AssertException const&) + { + } + + CHECK_EQUAL(0, reporter.testFailedCount); } #endif + +TEST(CheckAssertMacroSetsAssertExpectationToFalseAfterRunning) +{ + CHECK_ASSERT(ReportAssert("", "", 0)); + CHECK(!AssertExpected()); +} + +} diff --git a/src/tests/TestTestList.cpp b/src/tests/TestTestList.cpp index b37bff2..6b88ed4 100644 --- a/src/tests/TestTestList.cpp +++ b/src/tests/TestTestList.cpp @@ -6,23 +6,23 @@ using namespace UnitTest; namespace { -TEST (TestListIsEmptyByDefault) +TEST(TestListIsEmptyByDefault) { TestList list; - CHECK (list.GetHead() == 0); + CHECK(list.GetHead() == 0); } -TEST (AddingTestSetsHeadToTest) +TEST(AddingTestSetsHeadToTest) { Test test("test"); TestList list; list.Add(&test); - CHECK (list.GetHead() == &test); - CHECK (test.next == 0); + CHECK(list.GetHead() == &test); + CHECK(test.m_nextTest == 0); } -TEST (AddingSecondTestAddsItToEndOfList) +TEST(AddingSecondTestAddsItToEndOfList) { Test test1("test1"); Test test2("test2"); @@ -31,20 +31,20 @@ TEST (AddingSecondTestAddsItToEndOfList) list.Add(&test1); list.Add(&test2); - CHECK (list.GetHead() == &test1); - CHECK (test1.next == &test2); - CHECK (test2.next == 0); + CHECK(list.GetHead() == &test1); + CHECK(test1.m_nextTest == &test2); + CHECK(test2.m_nextTest == 0); } -TEST (ListAdderAddsTestToList) +TEST(ListAdderAddsTestToList) { TestList list; Test test(""); ListAdder adder(list, &test); - CHECK (list.GetHead() == &test); - CHECK (test.next == 0); + CHECK(list.GetHead() == &test); + CHECK(test.m_nextTest == 0); } } diff --git a/src/tests/TestTestMacros.cpp b/src/tests/TestTestMacros.cpp index a1506e5..d613580 100644 --- a/src/tests/TestTestMacros.cpp +++ b/src/tests/TestTestMacros.cpp @@ -19,7 +19,7 @@ TEST_EX(DummyTest, list1) TEST (TestsAreAddedToTheListThroughMacro) { CHECK(list1.GetHead() != 0); - CHECK(list1.GetHead()->next == 0); + CHECK(list1.GetHead()->m_nextTest == 0); } #ifdef UNITTEST_USE_EXCEPTIONS diff --git a/src/tests/TestTestRunner.cpp b/src/tests/TestTestRunner.cpp index 9acdaa5..bda88ae 100644 --- a/src/tests/TestTestRunner.cpp +++ b/src/tests/TestTestRunner.cpp @@ -10,6 +10,23 @@ using namespace UnitTest; namespace { +struct TestRunnerFixture +{ + TestRunnerFixture() + : runner(reporter) + { + s_testRunnerFixtureTestResults = runner.GetTestResults(); + } + + static TestResults* s_testRunnerFixtureTestResults; + + RecordingReporter reporter; + TestList list; + TestRunner runner; +}; + +TestResults* TestRunnerFixture::s_testRunnerFixtureTestResults = NULL; + struct MockTest : public Test { MockTest(char const* testName, bool const success_, bool const assert_, int const count_ = 1) @@ -18,16 +35,19 @@ struct MockTest : public Test , asserted(assert_) , count(count_) { + m_isMockTest = true; } - virtual void RunImpl(TestResults& testResults_) const + virtual void RunImpl() const { + TestResults* testResults = TestRunnerFixture::s_testRunnerFixtureTestResults; + for (int i=0; i < count; ++i) { if (asserted) - ReportAssert("desc", "file", 0); + ReportAssertEx(testResults, &m_details, "desc", "file", 0); else if (!success) - testResults_.OnTestFailure(m_details, "message"); + testResults->OnTestFailure(m_details, "message"); } } @@ -36,19 +56,6 @@ struct MockTest : public Test int const count; }; - -struct TestRunnerFixture -{ - TestRunnerFixture() - : runner(reporter) - { - } - - RecordingReporter reporter; - TestList list; - TestRunner runner; -}; - TEST_FIXTURE(TestRunnerFixture, TestStartIsReportedCorrectly) { MockTest test("goodtest", true, false); @@ -104,7 +111,7 @@ TEST_FIXTURE(TestRunnerFixture, CallsReportFailureOncePerFailingTest) MockTest test3("test", false, false); list.Add(&test3); - CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0)); + CHECK_EQUAL(2, runner.RunTestsIf(list, NULL, True(), 0)); CHECK_EQUAL(2, reporter.testFailedCount); } @@ -117,7 +124,6 @@ TEST_FIXTURE(TestRunnerFixture, TestsThatAssertAreReportedAsFailing) CHECK_EQUAL(1, reporter.testFailedCount); } - TEST_FIXTURE(TestRunnerFixture, ReporterNotifiedOfTestCount) { MockTest test1("test", true, false);