mirror of
https://github.com/unittest-cpp/unittest-cpp
synced 2026-09-27 00:28:49 +03:00
splitted class in .h/.cpp
This commit is contained in:
parent
f9f3523ce3
commit
17ec122775
2 changed files with 179 additions and 151 deletions
166
UnitTest++/ParameterizedSuite.cpp
Normal file
166
UnitTest++/ParameterizedSuite.cpp
Normal 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();
|
||||
}
|
||||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue