From 183209faf8c756dc53390f35eb97d90a1f91d7fe Mon Sep 17 00:00:00 2001 From: Gabriel Schlozer Date: Sun, 15 May 2016 01:01:29 +0200 Subject: [PATCH] coded feature --- UnitTest++/ParameterizedTest.cpp | 87 ++++++++++++++++++++++++++++++-- UnitTest++/ParameterizedTest.h | 63 +++++++++++++++++++++-- 2 files changed, 143 insertions(+), 7 deletions(-) diff --git a/UnitTest++/ParameterizedTest.cpp b/UnitTest++/ParameterizedTest.cpp index 0fc3e7e..df65de9 100644 --- a/UnitTest++/ParameterizedTest.cpp +++ b/UnitTest++/ParameterizedTest.cpp @@ -7,23 +7,57 @@ using namespace std; using namespace UnitTest; -ParameterizedTest::ParameterizedTest() +ParameterizedTestAbstract::ParameterizedTestAbstract() + : _iteration(0), + _testAnchor(nullptr), + _lastTest(nullptr), + _nextTestBackup(nullptr) { } -ParameterizedTest::~ParameterizedTest() +ParameterizedTestAbstract::~ParameterizedTestAbstract() { + if (_testAnchor != nullptr) + { + delete _testAnchor; + _testAnchor = nullptr; + } } -Test* const ParameterizedTest::retrieveCurrentTest() +size_t ParameterizedTestAbstract::getIteration() +{ + ensureInitialized(); + return _iteration; +} + + +void ParameterizedTestAbstract::ensureInitialized() +{ + Test* currentTest = retrieveCurrentTest(); + + if (_testAnchor == nullptr) + { + _testAnchor = new TestAnchor("ParameterizedTestAnchor", currentTest->m_details.suiteName, *this); + } + + if (_lastTest != currentTest) + { + _lastTest = currentTest; + _nextTestBackup = currentTest->m_nextTest; + onNewIteration(true); + } +} + + +Test* const ParameterizedTestAbstract::retrieveCurrentTest() { return retrieveTest(CurrentTest::Details()); } -Test* const ParameterizedTest::retrieveTest(TestDetails const * const details) +Test* const ParameterizedTestAbstract::retrieveTest(TestDetails const * const details) { //TODO This workaround is too far complicated, why not simply add pointer to current test in class CurrentTest ? Details2Test::iterator it = _tests.find(details); @@ -44,3 +78,48 @@ Test* const ParameterizedTest::retrieveTest(TestDetails const * const details) throw runtime_error(string("Impossible to retrieve test ") + details->testName); } + + +bool ParameterizedTestAbstract::hasMoreValues(int advance) const +{ + return (_iteration + advance < (int)valuesSize()); +} + + +void ParameterizedTestAbstract::onNewIteration(bool first) +{ + if (first) + { + _iteration = 0; + } + else + { + _iteration++; + } + + if (hasMoreValues(1)) + { + _lastTest->m_nextTest = _testAnchor; + _testAnchor->m_nextTest = _lastTest; + } + else + { + _lastTest->m_nextTest = _nextTestBackup; + _testAnchor->m_nextTest = nullptr; + } + + peekCurrentValue(_iteration); +} + + +ParameterizedTestAbstract::TestAnchor::TestAnchor(char const* testName, char const* suiteName, ParameterizedTestAbstract & pt) + : Test(testName, suiteName), + _pt(pt) +{ +} + + +void ParameterizedTestAbstract::TestAnchor::RunImpl() const +{ + _pt.onNewIteration(false); +} diff --git a/UnitTest++/ParameterizedTest.h b/UnitTest++/ParameterizedTest.h index 05ff9cd..79582a9 100644 --- a/UnitTest++/ParameterizedTest.h +++ b/UnitTest++/ParameterizedTest.h @@ -3,6 +3,8 @@ #include #include +#include + #include "Test.h" namespace UnitTest @@ -11,17 +13,72 @@ namespace UnitTest typedef map Details2Test; - class ParameterizedTest + class ParameterizedTestAbstract { public: - ParameterizedTest(); - virtual ~ParameterizedTest(); + ParameterizedTestAbstract(); + virtual ~ParameterizedTestAbstract(); + size_t getIteration(); + + protected: + virtual void peekCurrentValue(size_t iteration) = 0; + virtual size_t valuesSize() const = 0; + void ensureInitialized(); private: + class TestAnchor : public Test + { + public: + TestAnchor(char const* testName, char const* suiteName, ParameterizedTestAbstract & pt); + virtual void RunImpl() const override; + private: + ParameterizedTestAbstract & _pt; + }; + Test* const retrieveCurrentTest(); Test* const retrieveTest(TestDetails const * const details); + + bool hasMoreValues(int advance = 0) const; + void onNewIteration(bool first); + + size_t _iteration; + Test* _lastTest; + Test* _nextTestBackup; + TestAnchor* _testAnchor; Details2Test _tests; }; + + + template + class ParameterizedTest : public ParameterizedTestAbstract + { + public: + ParameterizedTest(vector values) + : _values(values) + { + } + + T_Value operator()() + { + ensureInitialized(); + return _currentValue; + } + + protected: + virtual void peekCurrentValue(size_t iteration) override + { + _currentValue = _values[iteration]; + } + + virtual size_t valuesSize() const override + { + return _values.size(); + } + + private: + vector _values; + T_Value _currentValue; + }; } #endif \ No newline at end of file