splitted class in .h/.cpp

This commit is contained in:
Gabriel Schlozer 2016-05-13 22:40:55 +02:00
parent f9f3523ce3
commit 17ec122775
2 changed files with 179 additions and 151 deletions

View file

@ -0,0 +1,166 @@
#include "ParameterizedSuite.h"
#include <string>
#include <iostream>
#include "TestList.h"
using namespace std;
using namespace UnitTest;
ParameterizedSuiteAbstract::ParameterizedSuiteAbstract(const string & suiteName)
: _iterationBranched(false),
_iteration(0),
_suiteName(suiteName),
_testName(suiteName + "ParameterizedSuite_anchor"),
_firstOuterTest(nullptr),
_lastOfSuite(nullptr),
_testAnchor(nullptr) // Important, even if defined just above (please read comment)
{
// WARNING: this is pointer because of memory problems with suiteName/testName.c_str(),
// the constructor does not initialize them in the right order
_testAnchor = new TestAnchor(*this);
}
ParameterizedSuiteAbstract::~ParameterizedSuiteAbstract()
{
if (_testAnchor != nullptr)
{
delete _testAnchor;
_testAnchor = nullptr;
}
}
size_t ParameterizedSuiteAbstract::getIteration() const
{
return _iteration;
}
void ParameterizedSuiteAbstract::ensureInitialized()
{
tryPeekFirstValue();
tryBranchUniqueTest();
}
bool ParameterizedSuiteAbstract::hasMoreValues(int advance) const
{
return (_iteration + advance < (int)valuesSize());
}
bool ParameterizedSuiteAbstract::tryPeekFirstValue()
{
if (_iterationBranched)
{
return false;
}
peekCurrentValue();
return false;
}
bool ParameterizedSuiteAbstract::tryBranchUniqueTest()
{
if (_iterationBranched)
{
return false;
}
//TODO find a way to allow single parameterized test execution
static bool messageDisplayed = false;
if (!messageDisplayed)
{
messageDisplayed = true;
cout << "WARNING: test of parameterized suite " << _suiteName
<< " can not be executed alone, test will be executed with first value only." << endl;
}
return true;
}
bool ParameterizedSuiteAbstract::branchTestsForIteration()
{
if (_iterationBranched)
{
return false;
}
for (Test* iTest = _testAnchor; iTest != nullptr; iTest = iTest->m_nextTest)
{
bool inSameSuite = (strcmp(iTest->m_details.suiteName, _suiteName.c_str()) == 0);
bool ownAnchor = (iTest == _testAnchor);
bool isOtherParameterizedSuite = (iTest != _testAnchor && dynamic_cast<TestAnchor*>(iTest) != nullptr);
if (!inSameSuite || isOtherParameterizedSuite)
{
_firstOuterTest = iTest;
break;
}
_lastOfSuite = iTest;
}
_lastOfSuite->m_nextTest = _testAnchor;
_iterationBranched = true;
return true;
}
bool ParameterizedSuiteAbstract::unbranchIterationIfLast()
{
if (!_iterationBranched)
{
return false;
}
if (hasMoreValues(1))
{
return false;
}
_lastOfSuite->m_nextTest = _firstOuterTest;
return true;
}
void ParameterizedSuiteAbstract::onNewIteration()
{
if (_iterationBranched)
{
_iteration++;
}
bool justBranched = branchTestsForIteration();
bool justUnbranched = unbranchIterationIfLast();
if (justBranched && justUnbranched)
{
// If no values to test, skip all tests
if (valuesSize() == 0)
{
_testAnchor->m_nextTest = _firstOuterTest;
return;
}
}
peekCurrentValue();
}
ParameterizedSuiteAbstract::TestAnchor::TestAnchor(ParameterizedSuiteAbstract & parameterized)
: Test(parameterized._testName.c_str(), parameterized._suiteName.c_str()),
_parameterized(parameterized)
{
Test::GetTestList().Add(this);
}
void ParameterizedSuiteAbstract::TestAnchor::RunImpl() const
{
_parameterized.onNewIteration();
}

View file

@ -2,8 +2,6 @@
#define UNITTEST_PARAMETERIZEDSUITE_H
#include <vector>
#include <iostream>
#include "Test.h"
namespace UnitTest
@ -13,164 +11,31 @@ namespace UnitTest
class ParameterizedSuiteAbstract
{
public:
ParameterizedSuiteAbstract(const string & suiteName)
: _iterationBranched(false),
_iteration(0),
_suiteName(suiteName),
_testName(suiteName + "ParameterizedSuite_anchor"),
_firstOuterTest(nullptr),
_lastOfSuite(nullptr),
_testAnchor(nullptr) // Important, even if defined just above (please read comment)
{
// WARNING: this is pointer because of memory problems with suiteName/testName.c_str(),
// the constructor does not initialize them in the right order
_testAnchor = new TestAnchor(*this);
}
virtual ~ParameterizedSuiteAbstract()
{
if (_testAnchor != nullptr)
{
delete _testAnchor;
_testAnchor = nullptr;
}
}
inline size_t getIteration() const
{
return _iteration;
}
ParameterizedSuiteAbstract(const string & suiteName);
virtual ~ParameterizedSuiteAbstract();
size_t getIteration() const;
protected:
virtual void peekCurrentValue() = 0;
virtual size_t valuesSize() const = 0;
void ensureInitialized()
{
tryPeekFirstValue();
tryBranchUniqueTest();
}
bool hasMoreValues(int advance = 0) const
{
return (_iteration + advance < (int)valuesSize());
}
void ensureInitialized();
bool hasMoreValues(int advance = 0) const;
private:
class TestAnchor : public Test
{
public:
TestAnchor(ParameterizedSuiteAbstract & parameterized)
: Test(parameterized._testName.c_str(), parameterized._suiteName.c_str()),
_parameterized(parameterized)
{
Test::GetTestList().Add(this);
}
virtual void RunImpl() const override
{
_parameterized.onNewIteration();
}
TestAnchor(ParameterizedSuiteAbstract & parameterized);
virtual void RunImpl() const override;
private:
ParameterizedSuiteAbstract & _parameterized;
};
bool tryPeekFirstValue()
{
if (_iterationBranched)
{
return false;
}
peekCurrentValue();
return false;
}
bool tryBranchUniqueTest()
{
if (_iterationBranched)
{
return false;
}
//TODO find a way to allow single parameterized test execution
static bool messageDisplayed = false;
if (!messageDisplayed)
{
messageDisplayed = true;
cout << "WARNING: test of parameterized suite " << _suiteName
<< " can not be executed alone, test will be executed with first value only." << endl;
}
return true;
}
bool branchTestsForIteration()
{
if (_iterationBranched)
{
return false;
}
for (Test* iTest = _testAnchor; iTest != nullptr; iTest = iTest->m_nextTest)
{
bool inSameSuite = (strcmp(iTest->m_details.suiteName, _suiteName.c_str()) == 0);
bool ownAnchor = (iTest == _testAnchor);
bool isOtherParameterizedSuite = (iTest != _testAnchor && dynamic_cast<TestAnchor*>(iTest) != nullptr);
if (!inSameSuite || isOtherParameterizedSuite)
{
_firstOuterTest = iTest;
break;
}
_lastOfSuite = iTest;
}
_lastOfSuite->m_nextTest = _testAnchor;
_iterationBranched = true;
return true;
}
bool unbranchIterationIfLast()
{
if (!_iterationBranched)
{
return false;
}
if (hasMoreValues(1))
{
return false;
}
_lastOfSuite->m_nextTest = _firstOuterTest;
return true;
}
void onNewIteration()
{
if (_iterationBranched)
{
_iteration++;
}
bool justBranched = branchTestsForIteration();
bool justUnbranched = unbranchIterationIfLast();
if (justBranched && justUnbranched)
{
// If no values to test, skip all tests
if (valuesSize() == 0)
{
_testAnchor->m_nextTest = _firstOuterTest;
return;
}
}
peekCurrentValue();
}
bool tryPeekFirstValue();
bool tryBranchUniqueTest();
bool branchTestsForIteration();
bool unbranchIterationIfLast();
void onNewIteration();
volatile bool _iterationBranched;
size_t _iteration;
@ -229,22 +94,19 @@ namespace UnitTest
virtual void peekCurrentValue() override
{
_currentValue = _values[getIteration()];
if (_suiteIterationListener != nullptr)
{
_suiteIterationListener->onNextIteration(_currentValue, getIteration());
}
}
virtual size_t valuesSize() override
virtual size_t valuesSize() const override
{
return _values.size();
}
private:
ISuiteIterationListener* const _suiteIterationListener;
vector<T_Value> _values;
T_Value _currentValue;
};