aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
authorRenaud Guezennec <renaud@rolisteam.org>2024-12-28 15:00:29 +0100
committerRenaud Guezennec <renaud@rolisteam.org>2024-12-29 14:46:30 +0100
commit5c508b351a95f416e4a599f76902b888369de1b4 (patch)
treee3f6363fd7458fb0a46eabde6bd3a65b4746d798 /src
parent5515cd5a22ab97843f6ca1c234333ec110a9bab1 (diff)
downloadOneRoll-5c508b351a95f416e4a599f76902b888369de1b4.tar.gz
OneRoll-5c508b351a95f416e4a599f76902b888369de1b4.zip
Several fix from fuzzer test.
Diffstat (limited to 'src')
-rw-r--r--src/bin/cli/CMakeLists.txt2
-rw-r--r--src/libparser/booleancondition.cpp4
-rw-r--r--src/libparser/diceparser.cpp4
-rw-r--r--src/libparser/die.cpp12
-rw-r--r--src/libparser/die.h1
-rw-r--r--src/libparser/node/bind.cpp37
-rw-r--r--src/libparser/node/executionnode.cpp19
-rw-r--r--src/libparser/node/executionnode.h5
-rw-r--r--src/libparser/node/jumpbackwardnode.cpp9
-rw-r--r--src/libparser/node/jumpbackwardnode.h1
-rw-r--r--src/libparser/node/mergenode.cpp98
-rw-r--r--src/libparser/node/mergenode.h6
-rw-r--r--src/libparser/node/rerolldicenode.cpp61
-rw-r--r--src/libparser/parsingtoolbox.cpp35
-rw-r--r--src/libparser/result/diceresult.cpp2
-rw-r--r--src/tests/dice/tst_dice.cpp57
16 files changed, 225 insertions, 128 deletions
diff --git a/src/bin/cli/CMakeLists.txt b/src/bin/cli/CMakeLists.txt
index 6e17c1e..606bb90 100644
--- a/src/bin/cli/CMakeLists.txt
+++ b/src/bin/cli/CMakeLists.txt
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.16)
-#project(dice)
+project(dice)
option(UPDATE_TRANSLATIONS "update Translation" OFF)
option(NO_PAINTER_OPERATOR "No PAINTING" OFF)
diff --git a/src/libparser/booleancondition.cpp b/src/libparser/booleancondition.cpp
index ab5b15d..12fb54b 100644
--- a/src/libparser/booleancondition.cpp
+++ b/src/libparser/booleancondition.cpp
@@ -93,6 +93,8 @@ BooleanCondition::~BooleanCondition()
}
qint64 BooleanCondition::hasValid(Die* b, bool recursive, bool unhighlight) const
{
+ if(!b)
+ return 0;
QList<qint64> listValues;
if(m_conditionType == Dice::OnEachValue)
{
@@ -185,7 +187,7 @@ Dice::CONDITION_STATE BooleanCondition::isValidRangeSize(const std::pair<qint64,
{
Dice::CONDITION_STATE state;
auto valueScalar= valueToScalar();
- qint64 boundValue= qBound(range.first, valueScalar, range.second);
+ qint64 boundValue= qBound(std::min(range.first, range.second), valueScalar, std::max(range.first, range.second));
bool isInsideRange= (boundValue == valueScalar);
switch(m_operator)
{
diff --git a/src/libparser/diceparser.cpp b/src/libparser/diceparser.cpp
index 43ee9ff..9f6a3dc 100644
--- a/src/libparser/diceparser.cpp
+++ b/src/libparser/diceparser.cpp
@@ -175,7 +175,7 @@ QMap<Dice::ERROR_CODE, QString> DiceParser::errorMap() const
}
QString DiceParser::humanReadableError() const
{
- auto parsingError= m_parsingToolbox->getErrorList();
+ auto const& parsingError= m_parsingToolbox->getErrorList();
QString str;
std::for_each(parsingError.begin(), parsingError.end(),
[&str](const QString& text)
@@ -185,7 +185,7 @@ QString DiceParser::humanReadableError() const
});
/// list
- auto errMap= errorMap();
+ auto const& errMap= errorMap();
std::for_each(errMap.begin(), errMap.end(),
[&str](const QString& text)
{
diff --git a/src/libparser/die.cpp b/src/libparser/die.cpp
index f752bbc..021ba5e 100644
--- a/src/libparser/die.cpp
+++ b/src/libparser/die.cpp
@@ -58,6 +58,7 @@ Die::Die()
Die::Die(const Die& die)
{
+ // qDebug() << "dice copy" << m_rollResult.size() << die.m_rollResult.size();
m_value= die.m_value;
m_rollResult= die.m_rollResult;
m_selected= die.m_selected;
@@ -69,8 +70,11 @@ Die::Die(const Die& die)
m_base= die.m_base;
m_color= die.getColor();
m_op= die.getOp();
- // auto seed= std::chrono::high_resolution_clock::now().time_since_epoch().count();
- // m_rng= std::mt19937(quintptr(this) + static_cast<unsigned long long>(seed));
+}
+
+Die::~Die()
+{
+ // qDebug() << "die destruction" << m_uuid << this;
}
void Die::setValue(qint64 r)
@@ -153,6 +157,7 @@ bool Die::hasChildrenValue()
}
void Die::replaceLastValue(qint64 value)
{
+ // qDebug() << "replace value" << value;
if(!m_rollResult.isEmpty())
m_rollResult.removeLast();
insertRollValue(value);
@@ -160,9 +165,6 @@ void Die::replaceLastValue(qint64 value)
void Die::roll(bool adding)
{
- if(std::abs(m_base) >= std::abs(m_maxValue))
- return;
-
std::uniform_int_distribution<qint64> dist(m_base, m_maxValue);
qint64 value= dist(s_rng);
if((adding) || (m_rollResult.isEmpty()))
diff --git a/src/libparser/die.h b/src/libparser/die.h
index 2da2006..48da214 100644
--- a/src/libparser/die.h
+++ b/src/libparser/die.h
@@ -42,6 +42,7 @@ public:
* @brief Die
*/
Die(const Die&);
+ ~Die();
/**
* @brief setValue
* @param r
diff --git a/src/libparser/node/bind.cpp b/src/libparser/node/bind.cpp
index 41449d8..9c502df 100644
--- a/src/libparser/node/bind.cpp
+++ b/src/libparser/node/bind.cpp
@@ -38,27 +38,36 @@ void BindNode::run(ExecutionNode* previous)
for(auto start : *m_startList)
{
ExecutionNode* last= getLatestNode(start);
- if(nullptr != last)
+ if(!last)
+ continue;
+
+ auto tmpResult= last->getResult();
+ QSet<Result*> alreadyVisited;
+ while(nullptr != tmpResult && !alreadyVisited.contains(tmpResult))
{
- auto tmpResult= last->getResult();
- while(nullptr != tmpResult)
+ alreadyVisited.insert(tmpResult);
+ DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
+
+ if(nullptr != dice)
{
- DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
- if(nullptr != dice)
+ m_diceResult->setHomogeneous(false);
+ auto list= dice->getResultList();
+ for(int i= 0; i < list.size(); ++i)
{
- m_diceResult->setHomogeneous(false);
- for(auto& die : dice->getResultList())
+ auto die= list[i];
+
+ if(!die)
+ continue;
+
+ if(!die->hasBeenDisplayed())
{
- if(!die->hasBeenDisplayed())
- {
- Die* tmpdie= new Die(*die);
- die->displayed();
- m_diceResult->getResultList().append(tmpdie);
- }
+ Die* tmpdie= new Die(*die);
+ die->displayed();
+ m_diceResult->getResultList().append(tmpdie);
}
}
- tmpResult= tmpResult->getPrevious();
}
+ tmpResult= tmpResult->getPrevious();
}
}
}
diff --git a/src/libparser/node/executionnode.cpp b/src/libparser/node/executionnode.cpp
index 096c8fe..b231416 100644
--- a/src/libparser/node/executionnode.cpp
+++ b/src/libparser/node/executionnode.cpp
@@ -2,6 +2,16 @@
#include <QUuid>
+namespace
+{
+#ifdef QT_DEBUG
+constexpr int WaitingTime{2 * 1000 * 60};
+#else
+constexpr int WaitingTime{30 * 60 * 1000};
+#endif
+
+} // namespace
+
ExecutionNode::ExecutionNode()
: m_previousNode(nullptr)
, m_result(nullptr)
@@ -43,12 +53,19 @@ ExecutionNode* ExecutionNode::getNextNode()
void ExecutionNode::execute(ExecutionNode* previous)
{
+ QElapsedTimer timer;
+ timer.start();
+
auto errorCount= m_errors.count();
run(previous);
- if(m_nextNode && errorCount == m_errors.count())
+ auto timeLimit= timer.hasExpired(WaitingTime);
+
+ if(m_nextNode && errorCount == m_errors.count() && !timeLimit)
m_nextNode->execute(this);
+ else if(timeLimit)
+ qDebug() << "Error too long" << WaitingTime << timeLimit << timer.elapsed();
}
QMap<Dice::ERROR_CODE, QString> ExecutionNode::getExecutionErrorMap()
diff --git a/src/libparser/node/executionnode.h b/src/libparser/node/executionnode.h
index 342ae36..a2912e3 100644
--- a/src/libparser/node/executionnode.h
+++ b/src/libparser/node/executionnode.h
@@ -6,6 +6,7 @@
#include <diceparser/diceparserhelper.h>
#include <QCoreApplication>
+#include <QElapsedTimer>
/**
* @brief The ExecutionNode class
*/
@@ -87,7 +88,7 @@ public:
protected:
/**
- * @brief m_nextNode
+ * @brief previous
*/
ExecutionNode* m_previousNode= nullptr;
/**
@@ -102,9 +103,7 @@ protected:
* @brief m_errors
*/
QMap<Dice::ERROR_CODE, QString> m_errors;
-
QMap<Dice::ERROR_CODE, QString> m_warnings;
-
QString m_id;
};
diff --git a/src/libparser/node/jumpbackwardnode.cpp b/src/libparser/node/jumpbackwardnode.cpp
index e4ae59a..3e2f4c1 100644
--- a/src/libparser/node/jumpbackwardnode.cpp
+++ b/src/libparser/node/jumpbackwardnode.cpp
@@ -29,6 +29,11 @@ JumpBackwardNode::JumpBackwardNode()
m_result= m_diceResult;
}
+JumpBackwardNode::~JumpBackwardNode()
+{
+ delete m_diceResult;
+}
+
qint64 JumpBackwardNode::getPriority() const
{
return 4;
@@ -126,13 +131,13 @@ void JumpBackwardNode::run(ExecutionNode* previous)
for(auto& die : diceResult->getResultList())
{
Die* tmpdie= new Die(*die);
- //*tmpdie= *die;
m_diceResult->insertResult(tmpdie);
die->displayed();
}
}
- m_result->setPrevious(previous->getResult());
+ if(m_result && previous)
+ m_result->setPrevious(previous->getResult());
if(m_nextNode)
m_nextNode->execute(this);
diff --git a/src/libparser/node/jumpbackwardnode.h b/src/libparser/node/jumpbackwardnode.h
index 5f20291..2e14a00 100644
--- a/src/libparser/node/jumpbackwardnode.h
+++ b/src/libparser/node/jumpbackwardnode.h
@@ -33,6 +33,7 @@ public:
* @brief JumpBackwardNode allows to get result from remote node in the execution tree.
*/
JumpBackwardNode();
+ virtual ~JumpBackwardNode();
/**
* @brief run - performs the actions
* @param previous
diff --git a/src/libparser/node/mergenode.cpp b/src/libparser/node/mergenode.cpp
index 4c19bd7..8f30289 100644
--- a/src/libparser/node/mergenode.cpp
+++ b/src/libparser/node/mergenode.cpp
@@ -23,75 +23,82 @@
#include <diceparser/parsingtoolbox.h>
-MergeNode::MergeNode() : m_diceResult(new DiceResult())
+MergeNode::MergeNode(std::vector<ExecutionNode*>& startList) : m_startList(startList), m_diceResult(new DiceResult())
{
m_result= m_diceResult;
}
+
+int findDistance(const std::vector<ExecutionNode*>& startList, MergeNode* node)
+{
+ int i= 0;
+ for(auto start : startList)
+ {
+ auto temp= start;
+ while(temp != nullptr)
+ {
+ if(temp == node)
+ return i;
+ temp= temp->getNextNode();
+ }
+ ++i;
+ }
+ return i;
+}
void MergeNode::run(ExecutionNode* previous)
{
if(isValid(!previous, Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No previous node before Merge operator")))
return;
- m_previousNode= previous;
- m_result->setPrevious(previous->getResult());
- ExecutionNode* previousLast= nullptr;
- std::vector<Result*> pastResult;
- if(!m_startList)
+ // m_previousNode= previous;
+ // m_result->setPrevious(previous->getResult());
+ // std::vector<Result*> pastResult;
+ if(isValid(m_startList.empty(), Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No several instruction")))
return;
- for(auto start : *m_startList)
- {
- ExecutionNode* last= getLatestNode(start);
- if(nullptr == last || nullptr == previousLast)
- {
- previousLast= last;
- continue;
- }
-
- auto startResult= start->getResult();
- if(nullptr == startResult)
- continue;
+ auto instId= findDistance(m_startList, this);
- startResult->setPrevious(previousLast->getResult());
- previousLast->setNextNode(start);
+ ExecutionNode* previousLast= nullptr;
+ std::for_each(std::begin(m_startList), std::end(m_startList),
+ [&previousLast, this](ExecutionNode* node)
+ {
+ ExecutionNode* last= getLatestNode(node);
+ if(previousLast)
+ {
+ previousLast->setNextNode(node);
+ auto resultNode= node->getResult();
+ if(resultNode)
+ resultNode->setPrevious(previousLast->getResult());
+ }
+ previousLast= last;
+ });
- previousLast= last;
- Result* tmpResult= last->getResult();
+ if(instId != 0)
+ {
+ Result* tmpResult= previous->getResult();
while(nullptr != tmpResult)
{
DiceResult* dice= dynamic_cast<DiceResult*>(tmpResult);
- if(nullptr != dice)
+ if(nullptr != dice && dice != m_diceResult)
{
- ///@todo TODO improve here to set homogeneous while is really
m_diceResult->setHomogeneous(false);
+
for(auto& die : dice->getResultList())
{
if(!m_diceResult->getResultList().contains(die) && (!die->hasBeenDisplayed()))
{
Die* tmpdie= new Die(*die);
die->displayed();
- m_diceResult->getResultList().append(tmpdie);
+ m_diceResult->insertResult(tmpdie);
}
}
}
- auto it= std::find_if(pastResult.begin(), pastResult.end(),
- [tmpResult](const Result* a) { return (a == tmpResult->getPrevious()); });
- if(it == pastResult.end())
- {
- pastResult.push_back(previousLast->getResult());
- tmpResult= tmpResult->getPrevious();
- }
- else
- {
- tmpResult->setPrevious(nullptr);
- tmpResult= nullptr;
- }
+ tmpResult= tmpResult->getPrevious();
}
}
- auto first= m_startList->front();
- m_startList->clear();
- m_startList->push_back(first);
+ auto first= m_startList.front();
+ m_startList.clear();
+ m_startList.push_back(first);
}
#include <QDebug>
ExecutionNode* MergeNode::getLatestNode(ExecutionNode* node)
@@ -126,7 +133,7 @@ qint64 MergeNode::getPriority() const
}
ExecutionNode* MergeNode::getCopy() const
{
- MergeNode* node= new MergeNode();
+ MergeNode* node= new MergeNode(m_startList);
if(nullptr != m_nextNode)
{
node->setNextNode(m_nextNode->getCopy());
@@ -134,12 +141,7 @@ ExecutionNode* MergeNode::getCopy() const
return node;
}
-std::vector<ExecutionNode*>* MergeNode::getStartList() const
-{
- return m_startList;
-}
-
-void MergeNode::setStartList(std::vector<ExecutionNode*>* startList)
+/*void MergeNode::setStartList(const std::vector<ExecutionNode*>& startList)
{
m_startList= startList;
-}
+}*/
diff --git a/src/libparser/node/mergenode.h b/src/libparser/node/mergenode.h
index 515a2e9..1b32352 100644
--- a/src/libparser/node/mergenode.h
+++ b/src/libparser/node/mergenode.h
@@ -31,20 +31,18 @@
class MergeNode : public ExecutionNode
{
public:
- MergeNode();
+ MergeNode(std::vector<ExecutionNode*>& startList);
void run(ExecutionNode* previous);
virtual QString toString(bool withLabel) const;
virtual qint64 getPriority() const;
virtual ExecutionNode* getCopy() const;
- std::vector<ExecutionNode*>* getStartList() const;
- void setStartList(std::vector<ExecutionNode*>* startList);
private:
ExecutionNode* getLatestNode(ExecutionNode* node);
private:
+ std::vector<ExecutionNode*>& m_startList;
DiceResult* m_diceResult= nullptr;
- std::vector<ExecutionNode*>* m_startList= nullptr;
};
#endif // NUMBERNODE_H
diff --git a/src/libparser/node/rerolldicenode.cpp b/src/libparser/node/rerolldicenode.cpp
index af075ce..25143ac 100644
--- a/src/libparser/node/rerolldicenode.cpp
+++ b/src/libparser/node/rerolldicenode.cpp
@@ -19,74 +19,81 @@ RerollDiceNode::~RerollDiceNode()
}
void RerollDiceNode::run(ExecutionNode* previous)
{
- if(isValid(!previous, Dice::ERROR_CODE::NO_PREVIOUS_ERROR, tr("No Previous node")))
+ using DE= Dice::ERROR_CODE;
+ using DC= Dice::CONDITION_STATE;
+ if(isValid(!previous, DE::NO_PREVIOUS_ERROR, tr("No Previous node")))
return;
m_previousNode= previous;
auto previousDiceResult= previous->getResult();
- if(isValid(!previousDiceResult, Dice::ERROR_CODE::NO_VALID_RESULT, tr("No Valid result")))
+ if(isValid(!previousDiceResult, DE::NO_VALID_RESULT, tr("No Valid result")))
return;
DiceResult* previous_result= dynamic_cast<DiceResult*>(previousDiceResult);
- if(isValid(!previous_result, Dice::ERROR_CODE::DIE_RESULT_EXPECTED,
+ if(isValid(!previous_result, DE::DIE_RESULT_EXPECTED,
tr(" The a operator expects dice result. Please check the documentation and fix your command.")))
return;
m_result->setPrevious(previous_result);
- for(auto& die : previous_result->getResultList())
+ for(auto const& die : previous_result->getResultList())
{
+ if(!die)
+ return;
+
Die* tmpdie= new Die(*die);
m_diceResult->insertResult(tmpdie);
die->displayed();
}
- // m_diceResult->setResultList(list);
QList<Die*>& list= m_diceResult->getResultList();
QList<Die*> toRemove;
- for(auto& die : list)
+ for(int i= 0; i < list.size(); ++i)
{
+ auto die= list[i];
+ if(!die)
+ continue;
+
bool finished= false;
auto state
= m_validatorList->isValidRangeSize(std::make_pair<qint64, qint64>(die->getBase(), die->getMaxValue()));
- if((Dice::CONDITION_STATE::ALWAYSTRUE == state && m_adding)
- || (!m_reroll && !m_adding && state == Dice::CONDITION_STATE::UNREACHABLE))
+
+ if(isValid((DC::ALWAYSTRUE == state && m_adding) || (!m_reroll && !m_adding && state == DC::UNREACHABLE),
+ DE::ENDLESS_LOOP_ERROR,
+ QStringLiteral("Condition cause an endless loop with this dice: %1")
+ .arg(QStringLiteral("d[%1,%2]")
+ .arg(static_cast<int>(die->getBase()))
+ .arg(static_cast<int>(die->getMaxValue())))))
{
- m_errors.insert(Dice::ERROR_CODE::ENDLESS_LOOP_ERROR,
- QObject::tr("Condition (%1) cause an endless loop with this dice: %2")
- .arg(toString(true))
- .arg(QStringLiteral("d[%1,%2]")
- .arg(static_cast<int>(die->getBase()))
- .arg(static_cast<int>(die->getMaxValue()))));
continue;
}
+
while(m_validatorList->hasValid(die, false) && !finished)
{
- if(m_instruction != nullptr)
+ if(m_instruction)
{
m_instruction->execute(this);
auto lastNode= ParsingToolBox::getLeafNode(m_instruction);
- if(lastNode != nullptr)
+ if(lastNode == nullptr)
+ continue;
+ auto lastResult= dynamic_cast<DiceResult*>(lastNode->getResult());
+ if(lastResult != nullptr)
{
- auto lastResult= dynamic_cast<DiceResult*>(lastNode->getResult());
- if(lastResult != nullptr)
- {
- toRemove.append(die);
- list.append(lastResult->getResultList());
- lastResult->clear();
- }
+ toRemove.append(die);
+ if(list.size() < lastResult->getResultList().size())
+ break;
+ list.append(lastResult->getResultList());
+ die= list[i];
+ lastResult->clear();
}
}
else
{
die->roll(m_adding);
}
- if(m_reroll)
- {
- finished= true;
- }
+ finished= m_reroll;
}
}
diff --git a/src/libparser/parsingtoolbox.cpp b/src/libparser/parsingtoolbox.cpp
index 4d75ede..a7b089d 100644
--- a/src/libparser/parsingtoolbox.cpp
+++ b/src/libparser/parsingtoolbox.cpp
@@ -306,6 +306,8 @@ Validator* ParsingToolBox::readValidator(QString& str, bool hasSquare)
qint64 start= operandNode->getScalarResult();
Range* range= new Range();
range->setConditionType(opCompare);
+ if(start > end)
+ qDebug() << "ERRORRR";
range->setValue(start, end);
returnVal= range;
isRange= true;
@@ -361,12 +363,13 @@ ValidatorList* ParsingToolBox::readValidatorList(QString& str)
str= str.remove(0, 1);
expectSquareBrasket= true;
}
+ ValidatorList* result{nullptr};
Validator* tmp= readValidator(str, expectSquareBrasket);
Dice::LogicOperation opLogic;
QVector<Dice::LogicOperation> operators;
QList<Validator*> validatorList;
-
+ bool isOK{true};
while(nullptr != tmp)
{
bool hasOperator= readLogicOperation(str, opLogic);
@@ -381,23 +384,26 @@ ValidatorList* ParsingToolBox::readValidatorList(QString& str)
if((expectSquareBrasket) && (str.startsWith("]")))
{
str= str.remove(0, 1);
- // isOk=true;
+ isOK= true;
+ }
+ else
+ {
+ // addError(Dice::ERROR_CODE::BAD_SYNTAXE,
+ // QStringLiteral("Syntax Error: no closing square bracket: %1").arg(str));
}
validatorList.append(tmp);
tmp= nullptr;
}
}
- if(!validatorList.isEmpty())
- {
- ValidatorList* validator= new ValidatorList();
- validator->setOperationList(operators);
- validator->setValidators(validatorList);
- return validator;
- }
- else
+
+ if(!validatorList.isEmpty() && isOK)
{
- return nullptr;
+ result= new ValidatorList();
+ result->setOperationList(operators);
+ result->setValidators(validatorList);
}
+
+ return result;
}
bool ParsingToolBox::readLogicOperation(QString& str, Dice::LogicOperation& op)
{
@@ -1820,8 +1826,8 @@ bool ParsingToolBox::readOption(QString& str, ExecutionNode* previous) //,
break;
case Merge:
{
- MergeNode* mergeNode= new MergeNode();
- mergeNode->setStartList(&m_startNodes);
+ MergeNode* mergeNode= new MergeNode(m_startNodes);
+ // mergeNode->setStartList(m_startNodes);
previous->setNextNode(mergeNode);
found= true;
}
@@ -1844,7 +1850,8 @@ bool ParsingToolBox::readOption(QString& str, ExecutionNode* previous) //,
{
auto scNode= new ReplaceValueNode();
found= readReplaceValueNode(str, scNode);
- previous->setNextNode(scNode);
+ if(found)
+ previous->setNextNode(scNode);
}
break;
case Bind:
diff --git a/src/libparser/result/diceresult.cpp b/src/libparser/result/diceresult.cpp
index b7e79f9..6f87536 100644
--- a/src/libparser/result/diceresult.cpp
+++ b/src/libparser/result/diceresult.cpp
@@ -62,7 +62,7 @@ DiceResult::~DiceResult()
{
if(!m_diceValues.isEmpty())
{
- qDeleteAll(m_diceValues.begin(), m_diceValues.end());
+ qDeleteAll(m_diceValues);
m_diceValues.clear();
}
}
diff --git a/src/tests/dice/tst_dice.cpp b/src/tests/dice/tst_dice.cpp
index f6541d2..2de3bcc 100644
--- a/src/tests/dice/tst_dice.cpp
+++ b/src/tests/dice/tst_dice.cpp
@@ -496,7 +496,10 @@ void TestDice::scopeDF()
auto results= m_diceParser->scalarResultsFromEachInstruction();
for(auto const& result : std::as_const(results))
+ {
+ qDebug() << result;
QVERIFY(result >= min && result <= max);
+ }
}
void TestDice::scopeDF_data()
@@ -1043,7 +1046,7 @@ void TestDice::filterTest_data()
QTest::addRow("cmd3") << "[1, 2, 3]f[.>2&:>5]" << 6;
QTest::addRow("cmd4") << "[1, 2, 6]f[.<2&>5]" << 6;
QTest::addRow("cmd5") << "[2, 2, 6]f[.<2&>5]" << 0;
- QTest::addRow("cmd5") << "[1, 5, 1]f[.<2&>5]" << 0;
+ QTest::addRow("cmd6") << "[1, 5, 1]f[.<2&>5]" << 0;
}
void TestDice::uniqueTest()
@@ -1106,11 +1109,55 @@ void TestDice::spreadTest_data()
QTest::addRow("cmd1") << QVector<int>({8, 4, 2});
}
-void TestDice::groupTest() {}
-void TestDice::groupTest_data() {}
+void TestDice::groupTest()
+{
+ QFETCH(QString, cmd);
+ QFETCH(int, scalar);
+
+ bool test= m_diceParser->parseLine(cmd);
+ QVERIFY2(test, cmd.toStdString().c_str());
+
+ m_diceParser->start();
+
+ auto results= m_diceParser->scalarResultsFromEachInstruction();
+ auto strResult= m_diceParser->finalStringResult([](const QString& result, const QString&, bool) { return result; });
+
+ QCOMPARE(strResult, QString::number(scalar));
+}
+void TestDice::groupTest_data()
+{
+ QTest::addColumn<QString>("cmd");
+ QTest::addColumn<int>("scalar");
+
+ QTest::addRow("group1") << "[12,7]g5" << 2;
+ QTest::addRow("group2") << "[12,7,4,3,2,1]g5" << 4;
+ QTest::addRow("group3") << "[1,1,1,1]g5" << 0;
+ // QTest::addRow("group4") << "[-18,-2,-1,2]g-3" << 2;
+}
+
+void TestDice::bindTest()
+{
+ QFETCH(QString, cmd);
+ QFETCH(int, scalar);
+
+ bool test= m_diceParser->parseLine(cmd);
+ QVERIFY2(test, cmd.toStdString().c_str());
+
+ m_diceParser->start();
-void TestDice::bindTest() {}
-void TestDice::bindTest_data() {}
+ auto results= m_diceParser->scalarResultsFromEachInstruction();
+ auto strResult= m_diceParser->finalStringResult([](const QString& result, const QString&, bool) { return result; });
+
+ QCOMPARE(strResult, QString::number(scalar));
+}
+void TestDice::bindTest_data()
+{
+ QTest::addColumn<QString>("cmd");
+ QTest::addColumn<int>("scalar");
+
+ QTest::addRow("bind1") << "[12,7];[18,2]b;$2k2;\"$3\"" << 30;
+ QTest::addRow("bind2") << "[12,7];[18,2]b;$2k2kl1;\"$3\"" << 12;
+}
void TestDice::occurenceTest()
{