From 6f499de159eeac37fe473f945042e13359dc2d40 Mon Sep 17 00:00:00 2001 From: Renaud G Date: Thu, 25 Jul 2019 09:59:03 +0200 Subject: move files --- dicealias.h | 119 ----- diceparser.h | 362 --------------- highlightdice.h | 55 --- include/dicealias.h | 119 +++++ include/diceparser.h | 362 +++++++++++++++ include/diceparserhelper.h | 4 + include/highlightdice.h | 55 +++ include/parsingtoolbox.h | 247 ++++++++++ parsingtoolbox.h | 247 ---------- tests/CMakeLists.txt | 9 - tests/dice/CMakeLists.txt | 18 +- tests/dice/Dice.pro | 25 -- tests/dice/testnode.cpp | 49 ++ tests/dice/testnode.h | 44 ++ tests/dice/tst_dice.cpp | 1069 ++++++++++++++++++++++++++++++++++++++++++++ tests/testnode.cpp | 49 -- tests/testnode.h | 44 -- tests/tst_dice.cpp | 1069 -------------------------------------------- 18 files changed, 1954 insertions(+), 1992 deletions(-) delete mode 100644 dicealias.h delete mode 100644 diceparser.h delete mode 100644 highlightdice.h create mode 100644 include/dicealias.h create mode 100644 include/diceparser.h create mode 100644 include/diceparserhelper.h create mode 100644 include/highlightdice.h create mode 100644 include/parsingtoolbox.h delete mode 100644 parsingtoolbox.h delete mode 100644 tests/CMakeLists.txt delete mode 100644 tests/dice/Dice.pro create mode 100644 tests/dice/testnode.cpp create mode 100644 tests/dice/testnode.h create mode 100644 tests/dice/tst_dice.cpp delete mode 100644 tests/testnode.cpp delete mode 100644 tests/testnode.h delete mode 100644 tests/tst_dice.cpp diff --git a/dicealias.h b/dicealias.h deleted file mode 100644 index 463a654..0000000 --- a/dicealias.h +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Renaud Guezennec * - * http://www.rolisteam.org/contact * - * * - * This file is part of DiceParser * - * * - * DiceParser is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef DICEALIAS_H -#define DICEALIAS_H - -#include -/** - * @brief The DiceAlias class is dedicated to store aliases, alias is mainly two QString. The Alias and its replacement. - * The replacement can be a simple QString or a RegExp. - */ -class DiceAlias -{ -public: - enum RESOLUTION_TYPE - { - REPLACE, - REGEXP - }; - /** - * @brief DiceAlias - * @param cmd - * @param key - * @param isReplace - */ - DiceAlias(QString pattern, QString remplacement, bool isReplace= true, bool isEnable= true); - /** - * @brief ~DiceAlias - */ - virtual ~DiceAlias(); - /** - * @brief resolved - * @param str - * @return - */ - bool resolved(QString& str); - /** - * @brief setCommand - * @param key - */ - void setCommand(QString key); - /** - * @brief setValue - * @param value - */ - void setValue(QString value); - /** - * @brief setType - */ - void setType(RESOLUTION_TYPE); - - /** - * @brief getCommand - * @return - */ - QString getCommand() const; - /** - * @brief getValue - * @return - */ - QString getValue() const; - /** - * @brief isReplace - * @return - */ - bool isReplace() const; - /** - * @brief setReplace - */ - void setReplace(bool); - - /** - * @brief isEnable - * @return - */ - bool isEnable() const; - /** - * @brief setEnable - * @param b - */ - void setEnable(bool b); - /** - * @brief getComment - * @return - */ - QString getComment() const; - /** - * @brief setComment - * @param comment - */ - void setComment(const QString& comment); - -private: - QString m_command; - QString m_value; - QString m_comment; - RESOLUTION_TYPE m_type; - bool m_isEnable; -}; - -#endif // DICEALIAS_H diff --git a/diceparser.h b/diceparser.h deleted file mode 100644 index 8ecfb50..0000000 --- a/diceparser.h +++ /dev/null @@ -1,362 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Renaud Guezennec * - * http://www.rolisteam.org/contact * - * * - * This file is part of DiceParser * - * * - * DiceParser is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef DICEPARSER_H -#define DICEPARSER_H - -#include -#include - -#include "dicealias.h" -#include "highlightdice.h" -#include "node/executionnode.h" - -typedef QList ListDiceResult; -typedef QMap ExportedDiceResult; - -class ExplodeDiceNode; -class ParsingToolBox; -class DiceRollerNode; -/** - * @page DiceParser Dice Parser - * - * @section Intro Introduction - * Diceparser is the software component dedicated to compute dice command in rolisteam.
- * - * @section grammar The Grammar - * - * The grammar is described in Readme.md - */ - -/** - * @brief The DiceParser class facade class, it receives a command and return a DiceResult class (not yet implemented). - */ -class DiceParser -{ -public: - /** - * @brief The DiceOperator enum gathering all dice operators - */ - enum DiceOperator - { - D, - L - }; - /** - * @brief The DiceSymbol enum - */ - enum NodeAction - { - JumpBackward - }; - /** - * @brief The OptionOperator enum gathering all options availables for result. - */ - enum OptionOperator - { - KeepAndExplode, - Keep, - Reroll, - RerollUntil, - Explode, - Sort, - Count, - RerollAndAdd, - Merge, - ifOperator, - Painter, - Filter, - Split, - Group, - Occurences, - Unique, - Bind - }; - /** - * @brief The CommandOperator enum - */ - enum CommandOperator - { - }; - - /** - * @brief DiceParser default constructor - */ - DiceParser(); - /** - * @brief ~DiceParser - */ - virtual ~DiceParser(); - - /** - * @brief parseLine, method to call for starting the dice roll. It will parse the command and run the execution - * tree. - * @param str dice command - * @return bool every thing is fine or not - */ - bool parseLine(QString str, bool allowAlias= true); - /** - * @brief getStartNodeCount - * @return - */ - int getStartNodeCount() const; - /** - * @brief Start running the execution tree - * - */ - void start(); - - /** - * @brief displayResult - */ - QString displayResult(); - /** - * @brief readExpression - * @param str - * @param node - * @return - */ - bool readExpression(QString& str, ExecutionNode*& node); - /** - * @brief displayDotTree - Write the execution tree into file using dot format. - * @param filepath absolute or relative path to the tree file. - */ - void writeDownDotTree(QString filepath); - /** - * @brief getLastIntegerResults - * @return - */ - QList getLastIntegerResults(); - /** - * @brief getSumOfDiceResult - * @return - */ - QList getSumOfDiceResult(); - /** - * @brief getLastDiceResult - * @return - */ - void getLastDiceResult(QList& diceValues, bool& homogeneous); - /** - * @brief hasIntegerResultNotInFirst - * @return - */ - bool hasIntegerResultNotInFirst(); - /** - * @brief hasDiceResult - * @return - */ - bool hasDiceResult(); - /** - * @brief getDiceCommand - * @return - */ - QString getDiceCommand() const; - /** - * @brief hasStringResult - * @return - */ - bool hasStringResult(); - /** - * @brief getStringResult - * @return - */ - QStringList getStringResult(); - /** - * @brief humanReadableError - * @return - */ - QString humanReadableError(); - /** - * @brief getAliases - * @return - */ - QList* getAliases(); - /** - * @brief insertAlias - */ - void insertAlias(DiceAlias*, int); - /** - * @brief DiceParser::convertAlias - * @param str - * @return - */ - QString convertAlias(QString str); - /** - * @brief getErrorList - * @return - */ - QMap getErrorMap(); - /** - * @brief setPathToHelp set the path to the documentation, this path must be adatped to the lang of application etc… - * @param l the path. - */ - void setPathToHelp(QString l); - /** - * @brief getAllStringResult - * @return - */ - QStringList getAllStringResult(bool& hasAlias); - /** - * @brief getAllDiceResult - * @param hasAlias - * @return - */ - QStringList getAllDiceResult(bool& hasAlias); - /** - * @brief hasSeparator allows to know if the current command has separator. - * @return true when the command has separator, false otherwise. - */ - bool hasSeparator() const; - /** - * @brief readIfInstruction reads the current command to build if node with proper parameters. - * @param str is the command string, if IF istruction is found, the str will be changed, in other case the string is - * unmodified - * @param trueNode is the branch's beginning to be executed if the IfNode is true. - * @param falseNode is the branch's beginning to be executed if the IfNode is false. - * @return true, ifNode has been found, false otherwise - */ - bool readIfInstruction(QString& str, ExecutionNode*& trueNode, ExecutionNode*& falseNode); - /** - * @brief setVariableDictionary - * @param variables - */ - void setVariableDictionary(const QHash& variables); - QString getComment() const; - void setComment(const QString& comment); - - bool readOptionFromNull(QString& str, ExecutionNode*& node); - bool readOperatorFromNull(QString& str, ExecutionNode*& node); - - bool readInstructionList(QString& str); - void getDiceResultFromAllInstruction(QList& resultList); - QString humanReadableWarning(); - - bool readValuesList(QString& str, ExecutionNode*& node); - -protected: - bool readParameterNode(QString& str, ExecutionNode*& node); - -private: - /** - * @brief readDice - * @param str - * @return - */ - bool readDice(QString& str, ExecutionNode*& node); - /** - * @brief readDiceOperator - * @return - */ - bool readDiceOperator(QString&, DiceOperator&); - /** - * @brief readDiceExpression - * @param node - * @return - */ - bool readDiceExpression(QString&, ExecutionNode*& node); - /** - * @brief readOperator - * @return - */ - bool readOperator(QString&, ExecutionNode* previous); - /** - * @brief DiceParser::readCommand - * @param str - * @param node - * @return - */ - bool readCommand(QString& str, ExecutionNode*& node); - - /** - * @brief readOption - */ - bool readOption(QString&, ExecutionNode* node); // OptionOperator& option, - - /** - * @brief addRollDiceNode - * @param faces - * @return - */ - DiceRollerNode* addRollDiceNode(qint64 faces, ExecutionNode*); - /** - * @brief addExplodeDiceNode - * @param faces - * @param previous - * @return - */ - ExplodeDiceNode* addExplodeDiceNode(qint64 faces, ExecutionNode* previous); - /** - * @brief readOperand - * @param node - * @return - */ - bool readOperand(QString&, ExecutionNode*& node); - - /** - * @brief readInstructionOperator - * @param c - * @return - */ - bool readInstructionOperator(QChar c); - /** - * @brief readNode - * @param str - * @param node - * @return - */ - bool readNode(QString& str, ExecutionNode*& node); - - /** - * @brief getLeafNode - * @return - */ - ExecutionNode* getLeafNode(ExecutionNode* node); - - /** - * @brief hasResultOfType - * @param notthelast - * @return - */ - bool hasResultOfType(Result::RESULT_TYPE, ExecutionNode* node, bool notthelast= false); - -private: - QMap* m_mapDiceOp; - QMap* m_OptionOp; - QMap* m_nodeActionMap; - QList* m_aliasList; - QStringList* m_commandList; - - QMap m_errorMap; - QMap m_warningMap; - - ExecutionNode* m_start= nullptr; - std::vector m_startNodes; - // ExecutionNode* m_current; - QString m_command; - ParsingToolBox* m_parsingToolbox; - QString m_helpPath; - bool m_currentTreeHasSeparator; - bool readBlocInstruction(QString& str, ExecutionNode*& resultnode); - QString m_comment; -}; - -#endif // DICEPARSER_H diff --git a/highlightdice.h b/highlightdice.h deleted file mode 100644 index 2e8f08a..0000000 --- a/highlightdice.h +++ /dev/null @@ -1,55 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2016 by Renaud Guezennec * - * http:://www.rolisteam.org/contact * - * * - * rolisteam is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef HighLightDice_H -#define HighLightDice_H - -#include -#include - -class HighLightDice -{ -public: - HighLightDice(QList result, bool isHighlighted, QString color, bool displayed, quint64 faces); - virtual ~HighLightDice(); - - QList getResult() const; - void setResult(const QList& result); - - bool isHighlighted() const; - void setHighlight(bool hasHighlight); - - QString getColor() const; - void setColor(const QString& color); - - bool getDisplayed() const; - void setDisplayed(bool displayed); - - quint64 getFaces() const; - void setFaces(const quint64& faces); - -private: - QList m_result; - bool m_hasHighlight= true; - QString m_color; - bool m_displayed= false; - quint64 m_faces; -}; - -#endif // HighLightDice_H diff --git a/include/dicealias.h b/include/dicealias.h new file mode 100644 index 0000000..463a654 --- /dev/null +++ b/include/dicealias.h @@ -0,0 +1,119 @@ +/*************************************************************************** + * Copyright (C) 2014 by Renaud Guezennec * + * http://www.rolisteam.org/contact * + * * + * This file is part of DiceParser * + * * + * DiceParser is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DICEALIAS_H +#define DICEALIAS_H + +#include +/** + * @brief The DiceAlias class is dedicated to store aliases, alias is mainly two QString. The Alias and its replacement. + * The replacement can be a simple QString or a RegExp. + */ +class DiceAlias +{ +public: + enum RESOLUTION_TYPE + { + REPLACE, + REGEXP + }; + /** + * @brief DiceAlias + * @param cmd + * @param key + * @param isReplace + */ + DiceAlias(QString pattern, QString remplacement, bool isReplace= true, bool isEnable= true); + /** + * @brief ~DiceAlias + */ + virtual ~DiceAlias(); + /** + * @brief resolved + * @param str + * @return + */ + bool resolved(QString& str); + /** + * @brief setCommand + * @param key + */ + void setCommand(QString key); + /** + * @brief setValue + * @param value + */ + void setValue(QString value); + /** + * @brief setType + */ + void setType(RESOLUTION_TYPE); + + /** + * @brief getCommand + * @return + */ + QString getCommand() const; + /** + * @brief getValue + * @return + */ + QString getValue() const; + /** + * @brief isReplace + * @return + */ + bool isReplace() const; + /** + * @brief setReplace + */ + void setReplace(bool); + + /** + * @brief isEnable + * @return + */ + bool isEnable() const; + /** + * @brief setEnable + * @param b + */ + void setEnable(bool b); + /** + * @brief getComment + * @return + */ + QString getComment() const; + /** + * @brief setComment + * @param comment + */ + void setComment(const QString& comment); + +private: + QString m_command; + QString m_value; + QString m_comment; + RESOLUTION_TYPE m_type; + bool m_isEnable; +}; + +#endif // DICEALIAS_H diff --git a/include/diceparser.h b/include/diceparser.h new file mode 100644 index 0000000..8ecfb50 --- /dev/null +++ b/include/diceparser.h @@ -0,0 +1,362 @@ +/*************************************************************************** + * Copyright (C) 2014 by Renaud Guezennec * + * http://www.rolisteam.org/contact * + * * + * This file is part of DiceParser * + * * + * DiceParser is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef DICEPARSER_H +#define DICEPARSER_H + +#include +#include + +#include "dicealias.h" +#include "highlightdice.h" +#include "node/executionnode.h" + +typedef QList ListDiceResult; +typedef QMap ExportedDiceResult; + +class ExplodeDiceNode; +class ParsingToolBox; +class DiceRollerNode; +/** + * @page DiceParser Dice Parser + * + * @section Intro Introduction + * Diceparser is the software component dedicated to compute dice command in rolisteam.
+ * + * @section grammar The Grammar + * + * The grammar is described in Readme.md + */ + +/** + * @brief The DiceParser class facade class, it receives a command and return a DiceResult class (not yet implemented). + */ +class DiceParser +{ +public: + /** + * @brief The DiceOperator enum gathering all dice operators + */ + enum DiceOperator + { + D, + L + }; + /** + * @brief The DiceSymbol enum + */ + enum NodeAction + { + JumpBackward + }; + /** + * @brief The OptionOperator enum gathering all options availables for result. + */ + enum OptionOperator + { + KeepAndExplode, + Keep, + Reroll, + RerollUntil, + Explode, + Sort, + Count, + RerollAndAdd, + Merge, + ifOperator, + Painter, + Filter, + Split, + Group, + Occurences, + Unique, + Bind + }; + /** + * @brief The CommandOperator enum + */ + enum CommandOperator + { + }; + + /** + * @brief DiceParser default constructor + */ + DiceParser(); + /** + * @brief ~DiceParser + */ + virtual ~DiceParser(); + + /** + * @brief parseLine, method to call for starting the dice roll. It will parse the command and run the execution + * tree. + * @param str dice command + * @return bool every thing is fine or not + */ + bool parseLine(QString str, bool allowAlias= true); + /** + * @brief getStartNodeCount + * @return + */ + int getStartNodeCount() const; + /** + * @brief Start running the execution tree + * + */ + void start(); + + /** + * @brief displayResult + */ + QString displayResult(); + /** + * @brief readExpression + * @param str + * @param node + * @return + */ + bool readExpression(QString& str, ExecutionNode*& node); + /** + * @brief displayDotTree - Write the execution tree into file using dot format. + * @param filepath absolute or relative path to the tree file. + */ + void writeDownDotTree(QString filepath); + /** + * @brief getLastIntegerResults + * @return + */ + QList getLastIntegerResults(); + /** + * @brief getSumOfDiceResult + * @return + */ + QList getSumOfDiceResult(); + /** + * @brief getLastDiceResult + * @return + */ + void getLastDiceResult(QList& diceValues, bool& homogeneous); + /** + * @brief hasIntegerResultNotInFirst + * @return + */ + bool hasIntegerResultNotInFirst(); + /** + * @brief hasDiceResult + * @return + */ + bool hasDiceResult(); + /** + * @brief getDiceCommand + * @return + */ + QString getDiceCommand() const; + /** + * @brief hasStringResult + * @return + */ + bool hasStringResult(); + /** + * @brief getStringResult + * @return + */ + QStringList getStringResult(); + /** + * @brief humanReadableError + * @return + */ + QString humanReadableError(); + /** + * @brief getAliases + * @return + */ + QList* getAliases(); + /** + * @brief insertAlias + */ + void insertAlias(DiceAlias*, int); + /** + * @brief DiceParser::convertAlias + * @param str + * @return + */ + QString convertAlias(QString str); + /** + * @brief getErrorList + * @return + */ + QMap getErrorMap(); + /** + * @brief setPathToHelp set the path to the documentation, this path must be adatped to the lang of application etc… + * @param l the path. + */ + void setPathToHelp(QString l); + /** + * @brief getAllStringResult + * @return + */ + QStringList getAllStringResult(bool& hasAlias); + /** + * @brief getAllDiceResult + * @param hasAlias + * @return + */ + QStringList getAllDiceResult(bool& hasAlias); + /** + * @brief hasSeparator allows to know if the current command has separator. + * @return true when the command has separator, false otherwise. + */ + bool hasSeparator() const; + /** + * @brief readIfInstruction reads the current command to build if node with proper parameters. + * @param str is the command string, if IF istruction is found, the str will be changed, in other case the string is + * unmodified + * @param trueNode is the branch's beginning to be executed if the IfNode is true. + * @param falseNode is the branch's beginning to be executed if the IfNode is false. + * @return true, ifNode has been found, false otherwise + */ + bool readIfInstruction(QString& str, ExecutionNode*& trueNode, ExecutionNode*& falseNode); + /** + * @brief setVariableDictionary + * @param variables + */ + void setVariableDictionary(const QHash& variables); + QString getComment() const; + void setComment(const QString& comment); + + bool readOptionFromNull(QString& str, ExecutionNode*& node); + bool readOperatorFromNull(QString& str, ExecutionNode*& node); + + bool readInstructionList(QString& str); + void getDiceResultFromAllInstruction(QList& resultList); + QString humanReadableWarning(); + + bool readValuesList(QString& str, ExecutionNode*& node); + +protected: + bool readParameterNode(QString& str, ExecutionNode*& node); + +private: + /** + * @brief readDice + * @param str + * @return + */ + bool readDice(QString& str, ExecutionNode*& node); + /** + * @brief readDiceOperator + * @return + */ + bool readDiceOperator(QString&, DiceOperator&); + /** + * @brief readDiceExpression + * @param node + * @return + */ + bool readDiceExpression(QString&, ExecutionNode*& node); + /** + * @brief readOperator + * @return + */ + bool readOperator(QString&, ExecutionNode* previous); + /** + * @brief DiceParser::readCommand + * @param str + * @param node + * @return + */ + bool readCommand(QString& str, ExecutionNode*& node); + + /** + * @brief readOption + */ + bool readOption(QString&, ExecutionNode* node); // OptionOperator& option, + + /** + * @brief addRollDiceNode + * @param faces + * @return + */ + DiceRollerNode* addRollDiceNode(qint64 faces, ExecutionNode*); + /** + * @brief addExplodeDiceNode + * @param faces + * @param previous + * @return + */ + ExplodeDiceNode* addExplodeDiceNode(qint64 faces, ExecutionNode* previous); + /** + * @brief readOperand + * @param node + * @return + */ + bool readOperand(QString&, ExecutionNode*& node); + + /** + * @brief readInstructionOperator + * @param c + * @return + */ + bool readInstructionOperator(QChar c); + /** + * @brief readNode + * @param str + * @param node + * @return + */ + bool readNode(QString& str, ExecutionNode*& node); + + /** + * @brief getLeafNode + * @return + */ + ExecutionNode* getLeafNode(ExecutionNode* node); + + /** + * @brief hasResultOfType + * @param notthelast + * @return + */ + bool hasResultOfType(Result::RESULT_TYPE, ExecutionNode* node, bool notthelast= false); + +private: + QMap* m_mapDiceOp; + QMap* m_OptionOp; + QMap* m_nodeActionMap; + QList* m_aliasList; + QStringList* m_commandList; + + QMap m_errorMap; + QMap m_warningMap; + + ExecutionNode* m_start= nullptr; + std::vector m_startNodes; + // ExecutionNode* m_current; + QString m_command; + ParsingToolBox* m_parsingToolbox; + QString m_helpPath; + bool m_currentTreeHasSeparator; + bool readBlocInstruction(QString& str, ExecutionNode*& resultnode); + QString m_comment; +}; + +#endif // DICEPARSER_H diff --git a/include/diceparserhelper.h b/include/diceparserhelper.h new file mode 100644 index 0000000..4f53293 --- /dev/null +++ b/include/diceparserhelper.h @@ -0,0 +1,4 @@ +#ifndef DICEPARSERHELPER_H +#define DICEPARSERHELPER_H + +#endif // DICEPARSERHELPER_H diff --git a/include/highlightdice.h b/include/highlightdice.h new file mode 100644 index 0000000..2e8f08a --- /dev/null +++ b/include/highlightdice.h @@ -0,0 +1,55 @@ +/*************************************************************************** + * Copyright (C) 2016 by Renaud Guezennec * + * http:://www.rolisteam.org/contact * + * * + * rolisteam is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef HighLightDice_H +#define HighLightDice_H + +#include +#include + +class HighLightDice +{ +public: + HighLightDice(QList result, bool isHighlighted, QString color, bool displayed, quint64 faces); + virtual ~HighLightDice(); + + QList getResult() const; + void setResult(const QList& result); + + bool isHighlighted() const; + void setHighlight(bool hasHighlight); + + QString getColor() const; + void setColor(const QString& color); + + bool getDisplayed() const; + void setDisplayed(bool displayed); + + quint64 getFaces() const; + void setFaces(const quint64& faces); + +private: + QList m_result; + bool m_hasHighlight= true; + QString m_color; + bool m_displayed= false; + quint64 m_faces; +}; + +#endif // HighLightDice_H diff --git a/include/parsingtoolbox.h b/include/parsingtoolbox.h new file mode 100644 index 0000000..b91db1a --- /dev/null +++ b/include/parsingtoolbox.h @@ -0,0 +1,247 @@ +/*************************************************************************** + * Copyright (C) 2014 by Renaud Guezennec * + * http://www.rolisteam.org/contact * + * * + * This file is part of DiceParser * + * * + * DiceParser is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef PARSINGTOOLBOX_H +#define PARSINGTOOLBOX_H + +#include + +#include "booleancondition.h" +#include "compositevalidator.h" +#include "node/dicerollernode.h" +#include "node/executionnode.h" +#include "node/ifnode.h" +#include "node/paintnode.h" +#include "node/scalaroperatornode.h" +#include "operationcondition.h" +#include "range.h" + +class SubtituteInfo +{ +public: + SubtituteInfo(); + + bool isValid() const; + + int length() const; + void setLength(int length); + + int resultIndex() const; + void setResultIndex(int valueIndex); + + int position() const; + void setPosition(int position); + + int digitNumber() const; + void setDigitNumber(int digitNumber); + +private: + int m_length= 2; + int m_digitNumber= 0; + int m_resultIndex= -1; + int m_position= -1; +}; + +/** + * @brief The ParsingToolBox is gathering many useful methods for dice parsing. + * Its goal is to make the diceparser a bit lighter. + */ +class ParsingToolBox +{ +public: + enum LIST_OPERATOR + { + NONE, + UNIQUE + }; + + /** + * @brief ParsingToolBox + */ + ParsingToolBox(); + /** + * @brief ParsingToolBox + * @param data + */ + ParsingToolBox(const ParsingToolBox& data); + /** + * @brief ~ParsingToolBox + */ + virtual ~ParsingToolBox(); + /** + * @brief addSort + * @param e + * @param b + * @return + */ + ExecutionNode* addSort(ExecutionNode* e, bool b); + /** + * @brief readAscending + * @param str + * @return + */ + static bool readAscending(QString& str); + /** + * @brief readLogicOperator + * @param str + * @param op + * @return + */ + bool readLogicOperator(QString& str, BooleanCondition::LogicOperator& op); + /** + * @brief readValidator + * @param str + * @return + */ + Validator* readValidator(QString& str, bool hasSquare=false); + /** + * @brief readCompositeValidator + * @param str + * @return + */ + Validator* readCompositeValidator(QString& str); + + /** + * @brief readNumber read number in the given str and remove from the string the read character. + * @param str the command line + * @param myNumber reference to the found number + * @return true, succeed to read number, false otherwise. + */ + static bool readNumber(QString& str, qint64& myNumber); + + /** + * @brief readString + * @param str + * @param strResult + * @return + */ + static bool readString(QString& str, QString& strresult); + /** + * @brief readVariable + * @param str + * @param myNumber + * @return + */ + static bool readVariable(QString& str, qint64& myNumber, QString& reasonFail); + /** + * @brief readOpenParentheses + * @param str + * @return + */ + static bool readOpenParentheses(QString& str); + /** + * @brief readCloseParentheses + * @param str + * @return + */ + static bool readCloseParentheses(QString& str); + + /** + * @brief readNumber read number in the given str and remove from the string the read character. + * @param str the command line + * @param myNumber reference to the found number + * @return true, succeed to read number, false otherwise. + */ + static bool readDynamicVariable(QString& str, qint64& index); + + /** + * @brief readList + * @param str + * @param list + * @return + */ + bool readList(QString& str, QStringList& list, QList& ranges); + /** + * @brief isValidValidator + * @param previous + * @param val + * @return + */ + bool isValidValidator(ExecutionNode* previous, Validator* val); + /** + * @brief getDiceRollerNode + * @param previous + * @return + */ + DiceRollerNode* getDiceRollerNode(ExecutionNode* previous); + + /** + * @brief readDiceRange + * @param str + * @param start + * @param end + * @return + */ + bool readDiceRange(QString& str, qint64& start, qint64& end); + /** + * @brief readListOperator + * @param str + * @return + */ + static LIST_OPERATOR readListOperator(QString& str); + + void readProbability(QStringList& str, QList& ranges); + + bool readLogicOperation(QString& str, CompositeValidator::LogicOperation& op); + + bool readDiceLogicOperator(QString& str, OperationCondition::ConditionOperator& op); + + bool readArithmeticOperator(QString& str, Die::ArithmeticOperator& op); + + static void readPainterParameter(PainterNode* painter, QString& str); + + static QHash getVariableHash(); + static void setVariableHash(const QHash& variableHash); + /** + * @brief readConditionType + * @param str + * @return + */ + static IfNode::ConditionType readConditionType(QString& str); + + bool readComment(QString& str, QString&, QString&); + static ExecutionNode* getLatestNode(ExecutionNode* node); + + static std::vector* getStartNodes(); + static void setStartNodes(std::vector* startNodes); + + static bool readOperand(QString& str, ExecutionNode*& node); + static int findClosingCharacterIndexOf(QChar open, QChar closing, const QString& str, int offset); + + static QString replaceVariableToValue(const QString& source, QStringList values); + + static SubtituteInfo readVariableFromString(const QString& source, int& start); + + static void readSubtitutionParameters(SubtituteInfo& info, QString& rest); + + static bool readComma(QString& str); + +private: + QMap* m_logicOp; + QMap* m_logicOperation; + QMap* m_conditionOperation; + QHash* m_arithmeticOperation; + + static QHash m_variableHash; + static std::vector* m_startNodes; +}; + +#endif // PARSINGTOOLBOX_H diff --git a/parsingtoolbox.h b/parsingtoolbox.h deleted file mode 100644 index b91db1a..0000000 --- a/parsingtoolbox.h +++ /dev/null @@ -1,247 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2014 by Renaud Guezennec * - * http://www.rolisteam.org/contact * - * * - * This file is part of DiceParser * - * * - * DiceParser is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ -#ifndef PARSINGTOOLBOX_H -#define PARSINGTOOLBOX_H - -#include - -#include "booleancondition.h" -#include "compositevalidator.h" -#include "node/dicerollernode.h" -#include "node/executionnode.h" -#include "node/ifnode.h" -#include "node/paintnode.h" -#include "node/scalaroperatornode.h" -#include "operationcondition.h" -#include "range.h" - -class SubtituteInfo -{ -public: - SubtituteInfo(); - - bool isValid() const; - - int length() const; - void setLength(int length); - - int resultIndex() const; - void setResultIndex(int valueIndex); - - int position() const; - void setPosition(int position); - - int digitNumber() const; - void setDigitNumber(int digitNumber); - -private: - int m_length= 2; - int m_digitNumber= 0; - int m_resultIndex= -1; - int m_position= -1; -}; - -/** - * @brief The ParsingToolBox is gathering many useful methods for dice parsing. - * Its goal is to make the diceparser a bit lighter. - */ -class ParsingToolBox -{ -public: - enum LIST_OPERATOR - { - NONE, - UNIQUE - }; - - /** - * @brief ParsingToolBox - */ - ParsingToolBox(); - /** - * @brief ParsingToolBox - * @param data - */ - ParsingToolBox(const ParsingToolBox& data); - /** - * @brief ~ParsingToolBox - */ - virtual ~ParsingToolBox(); - /** - * @brief addSort - * @param e - * @param b - * @return - */ - ExecutionNode* addSort(ExecutionNode* e, bool b); - /** - * @brief readAscending - * @param str - * @return - */ - static bool readAscending(QString& str); - /** - * @brief readLogicOperator - * @param str - * @param op - * @return - */ - bool readLogicOperator(QString& str, BooleanCondition::LogicOperator& op); - /** - * @brief readValidator - * @param str - * @return - */ - Validator* readValidator(QString& str, bool hasSquare=false); - /** - * @brief readCompositeValidator - * @param str - * @return - */ - Validator* readCompositeValidator(QString& str); - - /** - * @brief readNumber read number in the given str and remove from the string the read character. - * @param str the command line - * @param myNumber reference to the found number - * @return true, succeed to read number, false otherwise. - */ - static bool readNumber(QString& str, qint64& myNumber); - - /** - * @brief readString - * @param str - * @param strResult - * @return - */ - static bool readString(QString& str, QString& strresult); - /** - * @brief readVariable - * @param str - * @param myNumber - * @return - */ - static bool readVariable(QString& str, qint64& myNumber, QString& reasonFail); - /** - * @brief readOpenParentheses - * @param str - * @return - */ - static bool readOpenParentheses(QString& str); - /** - * @brief readCloseParentheses - * @param str - * @return - */ - static bool readCloseParentheses(QString& str); - - /** - * @brief readNumber read number in the given str and remove from the string the read character. - * @param str the command line - * @param myNumber reference to the found number - * @return true, succeed to read number, false otherwise. - */ - static bool readDynamicVariable(QString& str, qint64& index); - - /** - * @brief readList - * @param str - * @param list - * @return - */ - bool readList(QString& str, QStringList& list, QList& ranges); - /** - * @brief isValidValidator - * @param previous - * @param val - * @return - */ - bool isValidValidator(ExecutionNode* previous, Validator* val); - /** - * @brief getDiceRollerNode - * @param previous - * @return - */ - DiceRollerNode* getDiceRollerNode(ExecutionNode* previous); - - /** - * @brief readDiceRange - * @param str - * @param start - * @param end - * @return - */ - bool readDiceRange(QString& str, qint64& start, qint64& end); - /** - * @brief readListOperator - * @param str - * @return - */ - static LIST_OPERATOR readListOperator(QString& str); - - void readProbability(QStringList& str, QList& ranges); - - bool readLogicOperation(QString& str, CompositeValidator::LogicOperation& op); - - bool readDiceLogicOperator(QString& str, OperationCondition::ConditionOperator& op); - - bool readArithmeticOperator(QString& str, Die::ArithmeticOperator& op); - - static void readPainterParameter(PainterNode* painter, QString& str); - - static QHash getVariableHash(); - static void setVariableHash(const QHash& variableHash); - /** - * @brief readConditionType - * @param str - * @return - */ - static IfNode::ConditionType readConditionType(QString& str); - - bool readComment(QString& str, QString&, QString&); - static ExecutionNode* getLatestNode(ExecutionNode* node); - - static std::vector* getStartNodes(); - static void setStartNodes(std::vector* startNodes); - - static bool readOperand(QString& str, ExecutionNode*& node); - static int findClosingCharacterIndexOf(QChar open, QChar closing, const QString& str, int offset); - - static QString replaceVariableToValue(const QString& source, QStringList values); - - static SubtituteInfo readVariableFromString(const QString& source, int& start); - - static void readSubtitutionParameters(SubtituteInfo& info, QString& rest); - - static bool readComma(QString& str); - -private: - QMap* m_logicOp; - QMap* m_logicOperation; - QMap* m_conditionOperation; - QHash* m_arithmeticOperation; - - static QHash m_variableHash; - static std::vector* m_startNodes; -}; - -#endif // PARSINGTOOLBOX_H diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt deleted file mode 100644 index 4065cc5..0000000 --- a/tests/CMakeLists.txt +++ /dev/null @@ -1,9 +0,0 @@ -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra") -set(CMAKE_AUTOMOC ON) -find_package(Qt5Test REQUIRED) - -set(test_source testnode.cpp tst_dice.cpp) - -add_executable(test_dice ${test_source} ) -target_link_libraries(test_dice diceparser Qt5::Test) -add_test(tst_diceparser test_dice) diff --git a/tests/dice/CMakeLists.txt b/tests/dice/CMakeLists.txt index a0f27fd..4065cc5 100644 --- a/tests/dice/CMakeLists.txt +++ b/tests/dice/CMakeLists.txt @@ -1,17 +1,9 @@ -cmake_minimum_required(VERSION 3.5) -project(tst_diceParser) - -enable_testing(true) - -# Tell CMake to run moc when necessary: +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fno-permissive -pedantic -Wall -Wextra") set(CMAKE_AUTOMOC ON) - -# As moc files are generated in the binary dir, tell CMake -# to always look for includes there: -set(CMAKE_INCLUDE_CURRENT_DIR ON) - find_package(Qt5Test REQUIRED) -add_test(tst_diceParser tst_dice.cpp) +set(test_source testnode.cpp tst_dice.cpp) -target_link_libraries(foo Qt5::Test) +add_executable(test_dice ${test_source} ) +target_link_libraries(test_dice diceparser Qt5::Test) +add_test(tst_diceparser test_dice) diff --git a/tests/dice/Dice.pro b/tests/dice/Dice.pro deleted file mode 100644 index 9d24f91..0000000 --- a/tests/dice/Dice.pro +++ /dev/null @@ -1,25 +0,0 @@ -include(../tests.pri) - -SOURCES += \ - tst_dice.cpp - -TEMPLATE = app -TARGET= tst_diceParser -MOC_DIR=trash -OBJECTS_DIR=trash - -CONFIG+=testcase - -QT += testlib quick qml widgets - -INCLUDEPATH += $$ROLISTEAMSRC/diceparser/ -INCLUDEPATH += $$ROLISTEAMSRC/diceparser/node -INCLUDEPATH += $$ROLISTEAMSRC/diceparser/result - - -include($$ROLISTEAMSRC/diceparser/diceparser.pri) - -HEADERS -= ../../../rolisteam/client/diceparser/qmltypesregister.h -SOURCES -= ../../../rolisteam/client/diceparser/qmltypesregister.cpp - - diff --git a/tests/dice/testnode.cpp b/tests/dice/testnode.cpp new file mode 100644 index 0000000..de9fc05 --- /dev/null +++ b/tests/dice/testnode.cpp @@ -0,0 +1,49 @@ +#include "testnode.h" +#include "die.h" + +TestNode::TestNode() {} + +TestNode::~TestNode() +{ + m_nextNode= nullptr; + m_result= nullptr; +} +void TestNode::run(ExecutionNode* previous) +{ + Q_UNUSED(previous) + if(nullptr != m_nextNode) + { + m_nextNode->run(this); + } +} + +QString TestNode::toString(bool wl) const +{ + if(wl) + { + return QStringLiteral("%1 [label=\"TestNode \"]").arg(m_id); + } + else + { + return m_id; + } +} +qint64 TestNode::getPriority() const +{ + qint64 priority= 4; + return priority; +} +ExecutionNode* TestNode::getCopy() const +{ + TestNode* node= new TestNode(); + if(nullptr != m_nextNode) + { + node->setNextNode(m_nextNode->getCopy()); + } + return node; +} + +void TestNode::setResult(Result* result) +{ + m_result= result; +} diff --git a/tests/dice/testnode.h b/tests/dice/testnode.h new file mode 100644 index 0000000..5c918ee --- /dev/null +++ b/tests/dice/testnode.h @@ -0,0 +1,44 @@ +#ifndef TESTNODE_H +#define TESTNODE_H + +#include + +#include "executionnode.h" +#include "result/diceresult.h" +#include +/** + * @brief The TestNode class replaces any kind of node for test purpose. + */ +class TestNode : public ExecutionNode +{ +public: + /** + * @brief TestNode builds an instance + * @param faces, number of faces of dices + * @param offset, first value of dice. + */ + TestNode(); + virtual ~TestNode() override; + + /** + * @brief run - starts to roll dice. + */ + virtual void run(ExecutionNode*) override; + /** + * @brief toString + * @param wl + * @return use to generate dot tree; + */ + virtual QString toString(bool wl) const override; + /** + * @brief getPriority + * @return priority for dice roll: 4 (higher) + */ + virtual qint64 getPriority() const override; + + virtual ExecutionNode* getCopy() const override; + + void setResult(Result* result); +}; + +#endif // TESTNODE_H diff --git a/tests/dice/tst_dice.cpp b/tests/dice/tst_dice.cpp new file mode 100644 index 0000000..1fe2641 --- /dev/null +++ b/tests/dice/tst_dice.cpp @@ -0,0 +1,1069 @@ +/*************************************************************************** + * Copyright (C) 2011 by Renaud Guezennec * + * http://renaudguezennec.homelinux.org/accueil,3.html * + * * + * Rolisteam is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include + +#include "dicealias.h" +#include "diceparser.h" +#include "die.h" + +// node +#include "booleancondition.h" +#include "node/bind.h" +#include "node/countexecutenode.h" +#include "node/explodedicenode.h" +#include "node/filternode.h" +#include "node/groupnode.h" +#include "node/ifnode.h" +#include "node/jumpbackwardnode.h" +#include "node/keepdiceexecnode.h" +#include "node/numbernode.h" +#include "node/occurencecountnode.h" +#include "node/rerolldicenode.h" +#include "node/sortresult.h" +#include "node/splitnode.h" +#include "node/stringnode.h" +#include "node/uniquenode.h" +#include "result/stringresult.h" +#include "testnode.h" + +class TestDice : public QObject +{ + Q_OBJECT + +public: + TestDice(); + +private slots: + void init(); + void getAndSetTest(); + void diceRollD10Test(); + void diceRollD20Test(); + void commandEndlessLoop(); + + void mathPriority(); + void mathPriority_data(); + + void commandsTest(); + void commandsTest_data(); + + void dangerousCommandsTest(); + void dangerousCommandsTest_data(); + + void wrongCommandsTest(); + void wrongCommandsTest_data(); + + void wrongCommandsExecutionTimeTest(); + void scopeDF(); + void scopeDF_data(); + + void severalInstruction(); + void testAlias(); + void cleanupTestCase(); + + void keepTest(); + void keepTest_data(); + + void sortTest(); + void sortTest_data(); + + void countTest(); + void countTest_data(); + + void rerollTest(); + void rerollTest_data(); + + void explodeTest(); + void explodeTest_data(); + + void rerollUntilTest(); + void rerollUntilTest_data(); + + void rerollAddTest(); + void rerollAddTest_data(); + + void mergeTest(); + void mergeTest_data(); + + void ifTest(); + void ifTest_data(); + + void ifCommandTest(); + void ifCommandTest_data(); + + void paintTest(); + void paintTest_data(); + + void filterTest(); + void filterTest_data(); + + void uniqueTest(); + void uniqueTest_data(); + + void spreadTest(); + void spreadTest_data(); + + void groupTest(); + void groupTest_data(); + + void bindTest(); + void bindTest_data(); + + void occurenceTest(); + void occurenceTest_data(); + +private: + std::unique_ptr m_die; + std::unique_ptr m_diceParser; +}; + +TestDice::TestDice() {} + +void TestDice::init() +{ + m_die.reset(new Die()); + m_diceParser.reset(new DiceParser()); +} + +void TestDice::getAndSetTest() +{ + for(unsigned int i= 0; i < 2000; i++) + { + m_die->setMaxValue(i); + QVERIFY(m_die->getMaxValue() == i); + } + + m_die->setSelected(true); + QVERIFY(m_die->isSelected() == true); + + m_die->setSelected(false); + QVERIFY(m_die->isSelected() == false); +} + +void TestDice::diceRollD10Test() +{ + m_die->setMaxValue(10); + for(int i= 0; i < 2000; i++) + { + m_die->roll(false); + QVERIFY(m_die->getValue() > 0); + QVERIFY(m_die->getValue() < 11); + } +} +void TestDice::diceRollD20Test() +{ + m_die->setMaxValue(20); + for(int i= 0; i < 2000; i++) + { + m_die->roll(false); + QVERIFY(m_die->getValue() > 0); + QVERIFY(m_die->getValue() < 21); + } +} +void TestDice::commandEndlessLoop() +{ + bool a= m_diceParser->parseLine("1D10e[>0]"); + QVERIFY(!a); +} + +void TestDice::commandsTest() +{ + QFETCH(QString, cmd); + + bool a= m_diceParser->parseLine(cmd); + QVERIFY2(a, "parsing"); + + m_diceParser->start(); + QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error"); + QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning"); +} + +void TestDice::commandsTest_data() +{ + QTest::addColumn("cmd"); + + QTest::addRow("cmd1") << "1L[cheminée,chocolat,épée,arc,chute de pierre]"; + QTest::addRow("cmd2") << "10d10c[>=6]-@c[=1]"; + QTest::addRow("cmd3") << "10d10c[>=6]-@c[=1]-@c[=1]"; + QTest::addRow("cmd4") << "10d10c[>6]+@c[=10]"; + QTest::addRow("cmd5") << "1+1D10"; + QTest::addRow("cmd6") << "3d10c[>=5]"; + QTest::addRow("cmd7") << "1+(4*3)D10"; + QTest::addRow("cmd8") << "2+4/4"; + QTest::addRow("cmd9") << "2D10*2D20*8"; + QTest::addRow("cmd10") << "1+(4*3)D10"; + QTest::addRow("cmd11") << "(4D6)D10"; + QTest::addRow("cmd12") << "1D100a[>=95]a[>=96]a[>=97]a[>=98]a[>=99]e[>=100]"; + QTest::addRow("cmd13") << "3D100"; + QTest::addRow("cmd14") << "4k3"; + QTest::addRow("cmd15") << "10D10e[>=6]sc[>=6]"; + QTest::addRow("cmd16") << "10D10e10s"; + QTest::addRow("cmd17") << "10D10s"; + QTest::addRow("cmd18") << "15D10e10c[8-10]"; + QTest::addRow("cmd19") << "10d10e10"; + QTest::addRow("cmd30") << "(4+4)^4"; + QTest::addRow("cmd31") << "(1d20+20)*7/10"; + QTest::addRow("cmd32") << "20*7/10"; + QTest::addRow("cmd33") << "1D8+2D6+7"; + QTest::addRow("cmd34") << "D25"; + QTest::addRow("cmd35") << "1L[tete[10],ventre[50],jambe[40]]"; + QTest::addRow("cmd36") << "2d6c[%2=0]"; + QTest::addRow("cmd37") << "D25+D10"; + QTest::addRow("cmd38") << "D25;D10"; + QTest::addRow("cmd39") << "8+8+8"; + QTest::addRow("cmd40") << "1D20-88"; + QTest::addRow("cmd41") << "100*1D20*2D6"; + QTest::addRow("cmd42") << "2D6 # two 6sided dice"; + QTest::addRow("cmd43") << "100/28*3"; + QTest::addRow("cmd44") << "100/8"; + QTest::addRow("cmd45") << "100*3*8"; + QTest::addRow("cmd46") << "help"; + QTest::addRow("cmd47") << "la"; + QTest::addRow("cmd48") << "10D10c[<2|>7]"; + QTest::addRow("cmd49") << "10D6c[=2|=4|=6]"; + QTest::addRow("cmd50") << "10D10e[=1|=10]k4"; + QTest::addRow("cmd51") << "1L[tete,bras droit,bras gauche,jambe droite,jambe gauche,ventre[6-7],buste[8-10]]"; + QTest::addRow("cmd52") << "10+10s"; + QTest::addRow("cmd53") << "1d6e6;1d4e4mk1"; + QTest::addRow("cmd54") << "1d6e6;1d4e4mk1"; + QTest::addRow("cmd55") << "400D20/400000"; + QTest::addRow("cmd56") << "1d100e[>=95]i[<5]{-1d100e95}"; + QTest::addRow("cmd57") << "100*3*8"; + QTest::addRow("cmd58") << "1d100i[<70]{1d10i[=10]{1d100i[<70]{1d10e10}}}"; + QTest::addRow("cmd59") << "10d6c[<2|>5]"; + QTest::addRow("cmd60") << "5-5*5+5"; + QTest::addRow("cmd61") << "((3+4)*2)d6"; + QTest::addRow("cmd62") << "4d6i[=6]{+1d6}"; + QTest::addRow("cmd63") << "10d[-8--1]"; + QTest::addRow("cmd64") << "4d6e6i[=4]{-4}+2"; + QTest::addRow("cmd65") << "4d6e6f[!=4]+2"; + QTest::addRow("cmd66") << "5d10g10"; + QTest::addRow("cmd67") << "4d6p[4:blue]c[>=4];1d6p[1:#FFFFFF]c6-@c1;1d6p[1:#FF0000]c[>=4]+@c6-@c1"; + QTest::addRow("cmd68") << "10d[0-9]"; + QTest::addRow("cmd69") << "1d8e8;1d6e6mk1+2"; + QTest::addRow("cmd70") << "3d100g50"; + QTest::addRow("cmd71") << "3d100g33"; + QTest::addRow("cmd72") << "3d100g5"; + QTest::addRow("cmd73") << "3d100g40"; + QTest::addRow("cmd74") << "2d10k1+2d10k1+2d10k1"; + QTest::addRow("cmd75") << "2d10k1-2d10k1-2d10k1"; + QTest::addRow("cmd76") << "(2d10k1)-2d10k1-2d10k1"; + QTest::addRow("cmd77") << "2d10k1-(2d10k1)-2d10k1"; + QTest::addRow("cmd78") << "2d10k1-2d10k1-(2d10k1)"; + QTest::addRow("cmd79") << "1d6-2d6e6"; + QTest::addRow("cmd80") << "(1)-1d6e6"; + QTest::addRow("cmd81") << "(1)-(1d6e6)"; + QTest::addRow("cmd82") << "8d10o"; + QTest::addRow("cmd83") << "8d10o2,4"; + QTest::addRow("cmd84") << "8d10o2[>2]"; + QTest::addRow("cmd85") << "8d10ok2"; + QTest::addRow("cmd86") << "[100,200,300]k2"; + QTest::addRow("cmd87") << "100;200;300;[$1,$2,$3]k2"; +} + +void TestDice::wrongCommandsTest() +{ + // << "pajaejlbnmàw"; + QFETCH(QString, cmd); + QFETCH(bool, valid); + bool a= m_diceParser->parseLine(cmd); + if(a) + { + m_diceParser->start(); + auto map= m_diceParser->getErrorMap(); + a= map.isEmpty(); + } + QCOMPARE(a, valid); +} + +void TestDice::wrongCommandsTest_data() +{ + QTest::addColumn("cmd"); + QTest::addColumn("valid"); + + QTest::newRow("test1") << "1L[cheminée,chocolat,épée,arc,chute de pierre" << false; + QTest::newRow("test2") << "10d10c" << false; + QTest::newRow("test3") << "10d10a" << false; + QTest::newRow("test4") << "10d0a[>7]" << false; + QTest::newRow("test5") << "aiteanetauearuteurn" << false; + QTest::newRow("test6") << "meregue" << false; + QTest::newRow("test7") << "p i follow rivers" << false; + QTest::newRow("test8") << "manga violet evergarden" << false; + QTest::newRow("test9") << "((1d8e8+2);(1d6e6+2))" << true; +} + +void TestDice::wrongCommandsExecutionTimeTest() +{ + QStringList commands; + + //<< "8D20+10*@c[=20]" + commands << "1/0" + << "" + << "0d10" + << "10d10k11" + << "!!!!"; + + for(QString cmd : commands) + { + bool test= m_diceParser->parseLine(cmd); + m_diceParser->start(); + + QVERIFY2(m_diceParser->getErrorMap().isEmpty() == false || !test, cmd.toStdString().c_str()); + } +} +void TestDice::scopeDF() +{ + QFETCH(QString, cmd); + QFETCH(int, min); + QFETCH(int, max); + QFETCH(bool, valid); + + bool test= m_diceParser->parseLine(cmd); + QVERIFY2(test == valid, cmd.toStdString().c_str()); + m_diceParser->start(); + auto results= m_diceParser->getLastIntegerResults(); + + for(auto result : results) + QVERIFY(result >= min && result <= max); +} + +void TestDice::scopeDF_data() +{ + QTest::addColumn("cmd"); + QTest::addColumn("min"); + QTest::addColumn("max"); + QTest::addColumn("valid"); + + QTest::newRow("test1") << "1D[-1-1]" << -1 << 1 << true; + QTest::newRow("test2") << "1D[-10--5]" << -10 << -5 << true; + QTest::newRow("test3") << "1D[-100-100]" << -100 << 100 << true; + QTest::newRow("test4") << "1D[-1-0]" << -1 << 0 << true; + QTest::newRow("test5") << "1D[10-20]" << 10 << 20 << true; + QTest::newRow("test6") << "1D[30-100]" << 30 << 100 << true; + QTest::newRow("test7") << "1D[0-99]" << 0 << 99 << true; + QTest::newRow("test8") << "5-5*5+5" << -15 << -15 << true; + QTest::newRow("test9") << "2d20c[<=13]+@c[<=3]" << 0 << 4 << true; + QTest::newRow("test10") << "6d10c[>=6]-@c1" << -6 << 6 << true; + QTest::newRow("test11") << "2d6k1+2d8k1+2d10k1" << 3 << 30 << true; + QTest::newRow("test12") << "1D[-2-50]" << -2 << 50 << true; +} +void TestDice::testAlias() +{ + m_diceParser->insertAlias(new DiceAlias("!", "3d6c"), 0); + m_diceParser->insertAlias(new DiceAlias("g", "d10k"), 1); + m_diceParser->insertAlias(new DiceAlias("(.*)C(.*)", QStringLiteral("\\1d10e10c[>=\\2]"), false), 2); + + QStringList cmds; + cmds << "!2" + << "${rang}g4" + << "${rang}g4 # gerald" + << "5C3" + << "1d100i:[<101]{\"great!\"}{\"try again\"}"; + + QStringList expected; + expected << "3d6c2" + << "${rang}d10k4" + << "${rang}d10k4 # gerald" + << "5d10e10c[>=3]" + << "1d100i:[<101]{\"great!\"}{\"try again\"}"; + + int i= 0; + for(auto cmd : cmds) + { + auto result= m_diceParser->convertAlias(cmd); + QVERIFY2(result == expected[i], result.toLatin1()); + ++i; + } +} +void TestDice::severalInstruction() +{ + QStringList commands; + + commands << "1d10;2d20;$1+$2"; + + QList results; + results << 3; + + int i= 0; + for(auto cmd : commands) + { + auto test= m_diceParser->parseLine(cmd); + QVERIFY2(test, cmd.toStdString().c_str()); + QVERIFY2(m_diceParser->getStartNodeCount() == results[i], "Wrong number of instruction"); + } +} +void TestDice::mathPriority() +{ + QFETCH(QString, cmd); + QFETCH(int, expected); + + bool test= m_diceParser->parseLine(cmd); + QVERIFY(test); + m_diceParser->start(); + auto resultList= m_diceParser->getLastIntegerResults(); + QCOMPARE(resultList.size(), 1); + + auto value= resultList.first(); + QVERIFY(qFuzzyCompare(value, expected) == 1); +} + +void TestDice::mathPriority_data() +{ + QTest::addColumn("cmd"); + QTest::addColumn("expected"); + + QTest::addRow("cmd1") << "10+2" << 12; + QTest::addRow("cmd2") << "2-10" << -8; + QTest::addRow("cmd3") << "5+2*3" << 11; + QTest::addRow("cmd4") << "5-5*5+5" << -15; + QTest::addRow("cmd5") << "5-5/5+5" << 9; + QTest::addRow("cmd6") << "10*(3*2)" << 60; + QTest::addRow("cmd7") << "60/(3*2)" << 10; + QTest::addRow("cmd8") << "5-(5*5+5)" << -25; +} + +void TestDice::dangerousCommandsTest() +{ + QFETCH(QString, cmd); + + for(int i= 0; i < 1000; ++i) + { + auto b= m_diceParser->parseLine(cmd); + QVERIFY(b); + m_diceParser->start(); + } +} +void TestDice::dangerousCommandsTest_data() +{ + QTest::addColumn("cmd"); + + QTest::addRow("cmd1") << "10d6g10"; + QTest::addRow("cmd2") << "10d2g10"; + QTest::addRow("cmd3") << "10d10g10"; + // QTest::addRow("cmd4") << "10d10g10"; + // QTest::addRow("cmd5") << "10d10g10"; +} + +void makeResult(DiceResult& result, const QVector& values) +{ + for(int val : values) + { + auto die= new Die(); + die->setBase(1); + die->setMaxValue(10); + die->insertRollValue(val); + result.insertResult(die); + } +} + +void makeResultExplode(DiceResult& result, const QVector& values) +{ + auto die= new Die(); + die->setBase(1); + die->setMaxValue(10); + for(int val : values) + { + die->insertRollValue(val); + } + result.insertResult(die); +} + +Validator* makeValidator(int number, BooleanCondition::LogicOperator op) +{ + BooleanCondition* validator= new BooleanCondition(); + NumberNode* node= new NumberNode(); + node->setNumber(number); + validator->setValueNode(node); + validator->setOperator(op); + return validator; +} + +void TestDice::keepTest() +{ + QFETCH(QVector, values); + QFETCH(int, keep); + QFETCH(int, score); + QFETCH(bool, error); + + TestNode node; + KeepDiceExecNode keepN; + keepN.setDiceKeepNumber(keep); + + DiceResult result; + + makeResult(result, values); + + node.setResult(&result); + node.setNextNode(&keepN); + + node.run(nullptr); + + bool isErrorEmpty= !keepN.getExecutionErrorMap().isEmpty(); + + QCOMPARE(isErrorEmpty, error); + + if(error) + return; + + auto resultScore= keepN.getResult()->getResult(Result::SCALAR).toInt(); + + QCOMPARE(score, resultScore); +} + +void TestDice::keepTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("keep"); + QTest::addColumn("score"); + QTest::addColumn("error"); + + QTest::addRow("cmd1") << QVector({10, 9, 2}) << 1 << 10 << false; + QTest::addRow("cmd2") << QVector({10, 9, 2}) << 2 << 19 << false; + QTest::addRow("cmd3") << QVector({10, 9, 2}) << 3 << 21 << false; + QTest::addRow("cmd4") << QVector({10, 9, 2}) << 4 << 0 << true; +} + +void TestDice::sortTest() +{ + QFETCH(QVector, values); + QFETCH(bool, ascending); + QFETCH(QVector, scores); + + TestNode node; + SortResultNode sortN; + sortN.setSortAscending(ascending); + + DiceResult result; + + makeResult(result, values); + + node.setResult(&result); + node.setNextNode(&sortN); + + DiceResult expectedScore; + makeResult(expectedScore, scores); + + node.run(nullptr); + + auto list= dynamic_cast(sortN.getResult())->getResultList(); + + int i= 0; + auto expected= expectedScore.getResultList(); + for(auto sortedDie : list) + { + QCOMPARE(expected[i]->getValue(), sortedDie->getValue()); + ++i; + } +} + +void TestDice::sortTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("ascending"); + QTest::addColumn>("scores"); + + QTest::addRow("cmd1") << QVector({10, 9, 2}) << true << QVector({2, 9, 10}); + QTest::addRow("cmd2") << QVector({1, 2, 3}) << false << QVector({3, 2, 1}); + QTest::addRow("cmd3") << QVector({10, 9, 2}) << false << QVector({10, 9, 2}); + QTest::addRow("cmd4") << QVector({2, 9, 10}) << true << QVector({2, 9, 10}); + QTest::addRow("cmd5") << QVector({1, 25, 10}) << false << QVector({25, 10, 1}); + QTest::addRow("cmd6") << QVector({10, 2, 100}) << false << QVector({100, 10, 2}); +} + +void TestDice::countTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(int, score); + + TestNode node; + CountExecuteNode countN; + + auto validator= makeValidator(condition, BooleanCondition::GreaterThan); + + countN.setValidator(validator); + DiceResult result; + node.setResult(&result); + node.setNextNode(&countN); + + makeResult(result, values); + + node.run(nullptr); + + QCOMPARE(score, countN.getResult()->getResult(Result::SCALAR).toInt()); + + countN.setValidator(nullptr); +} + +void TestDice::countTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("score"); + + QTest::addRow("cmd1") << QVector({10, 9, 2}) << 3 << 2; + QTest::addRow("cmd2") << QVector({1, 2, 3}) << 3 << 0; +} + +void TestDice::rerollTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(bool, different); + + TestNode node; + RerollDiceNode reroll(true, false); + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + auto validator= makeValidator(condition, BooleanCondition::GreaterThan); + reroll.setValidator(validator); + node.setNextNode(&reroll); + + node.run(nullptr); + + auto list= dynamic_cast(reroll.getResult())->getResultList(); + + int i= 0; + auto expected= result.getResultList(); + bool resultDiff= false; + for(auto rerolled : list) + { + if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) + resultDiff= true; + ++i; + } + + QCOMPARE(different, resultDiff); +} + +void TestDice::rerollTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("different"); + + QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; + QTest::addRow("cmd2") << QVector({0, 0, 0}) << -1 << true; +} + +void TestDice::explodeTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(bool, different); + + TestNode node; + ExplodeDiceNode explode; + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + auto validator= makeValidator(condition, BooleanCondition::Equal); + explode.setValidator(validator); + node.setNextNode(&explode); + + node.run(nullptr); + + auto list= dynamic_cast(explode.getResult())->getResultList(); + + int i= 0; + auto expected= result.getResultList(); + bool resultDiff= false; + for(auto rerolled : list) + { + if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) + resultDiff= true; + ++i; + } + + QCOMPARE(different, resultDiff); +} + +void TestDice::explodeTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("different"); + + QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; + QTest::addRow("cmd2") << QVector({0, 0, 0}) << 0 << true; +} + +void TestDice::rerollUntilTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(bool, different); + + TestNode node; + RerollDiceNode reroll(false, false); + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + auto validator= makeValidator(condition, BooleanCondition::Equal); + reroll.setValidator(validator); + node.setNextNode(&reroll); + + node.run(nullptr); + + auto list= dynamic_cast(reroll.getResult())->getResultList(); + + int i= 0; + auto expected= result.getResultList(); + bool resultDiff= false; + for(auto rerolled : list) + { + if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) + resultDiff= true; + ++i; + } + + QCOMPARE(different, resultDiff); +} +void TestDice::rerollUntilTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("different"); + + QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; + QTest::addRow("cmd2") << QVector({0, 0, 0}) << 0 << true; +} + +void TestDice::rerollAddTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(bool, different); + + TestNode node; + RerollDiceNode reroll(true, true); + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + auto validator= makeValidator(condition, BooleanCondition::Equal); + reroll.setValidator(validator); + node.setNextNode(&reroll); + + node.run(nullptr); + + auto list= dynamic_cast(reroll.getResult())->getResultList(); + + int i= 0; + auto expected= result.getResultList(); + bool resultDiff= false; + for(auto rerolled : list) + { + if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) + resultDiff= true; + ++i; + } + + QCOMPARE(different, resultDiff); +} +void TestDice::rerollAddTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("different"); + + QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; + QTest::addRow("cmd2") << QVector({0, 0, 0}) << 0 << true; +} + +void TestDice::mergeTest() {} +void TestDice::mergeTest_data() {} + +void TestDice::ifTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(int, valCondition); + QFETCH(QString, expectedResult); + + IfNode::ConditionType conditionType= static_cast(condition); + + TestNode node; + IfNode ifNode; + ifNode.setConditionType(conditionType); + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + StringNode trueNode; + trueNode.setString(QStringLiteral("True")); + StringNode falseNode; + falseNode.setString(QStringLiteral("False")); + + ifNode.setInstructionTrue(&trueNode); + ifNode.setInstructionFalse(&falseNode); + + auto validator= makeValidator(valCondition, BooleanCondition::Equal); + ifNode.setValidator(validator); + node.setNextNode(&ifNode); + + node.run(nullptr); + + auto text= dynamic_cast(ifNode.getNextNode()->getResult())->getText(); + + QCOMPARE(expectedResult, text); + + ifNode.setNextNode(nullptr); +} +void TestDice::ifTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("valCondition"); + QTest::addColumn("expectedResult"); + + int onEach= 0; + int oneOfThem= 1; + int allOfThem= 2; + int onScalar= 3; + + QTest::addRow("cmd1") << QVector({8, 9, 2}) << onEach << 0 << "False"; + QTest::addRow("cmd2") << QVector({2, 2, 2}) << onEach << 2 << "True"; + + QTest::addRow("cmd3") << QVector({0, 0, 0}) << oneOfThem << 10 << "False"; + QTest::addRow("cmd4") << QVector({10, 9, 5}) << oneOfThem << 10 << "True"; + QTest::addRow("cmd5") << QVector({9, 9, 9}) << oneOfThem << 9 << "True"; + + QTest::addRow("cmd6") << QVector({8, 9, 2}) << allOfThem << 1 << "False"; + QTest::addRow("cmd7") << QVector({8, 9, 2}) << allOfThem << 9 << "False"; + QTest::addRow("cmd8") << QVector({8, 8, 8}) << allOfThem << 8 << "True"; + + QTest::addRow("cmd9") << QVector({25, 8, 14}) << onScalar << 1 << "False"; + QTest::addRow("cmd10") << QVector({25, 8, 14}) << onScalar << 47 << "True"; +} + +void TestDice::paintTest() {} +void TestDice::paintTest_data() {} + +void TestDice::filterTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(bool, different); + + TestNode node; + FilterNode filter; + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + auto validator= makeValidator(condition, BooleanCondition::Different); + filter.setValidator(validator); + node.setNextNode(&filter); + + node.run(nullptr); + + auto list= dynamic_cast(filter.getResult())->getResultList(); + + auto expected= result.getResultList(); + bool resultDiff= (list.size() != expected.size()); + + QCOMPARE(different, resultDiff); +} + +void TestDice::filterTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("different"); + + QTest::addRow("cmd1") << QVector({8, 4, 2}) << 4 << true; + QTest::addRow("cmd2") << QVector({0, 0, 0}) << 1 << false; +} + +void TestDice::uniqueTest() +{ + QFETCH(QVector, values); + QFETCH(QVector, expected); + + TestNode node; + UniqueNode unique; + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + node.setNextNode(&unique); + node.run(nullptr); + + auto list= dynamic_cast(unique.getResult())->getResultList(); + QVector resultVal; + + std::transform(list.begin(), list.end(), std::back_inserter(resultVal), [](Die* die) { return die->getValue(); }); + + QVERIFY(resultVal == expected); +} + +void TestDice::uniqueTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn>("expected"); + + QTest::addRow("cmd1") << QVector({8, 4, 2, 8}) << QVector({8, 4, 2}); + QTest::addRow("cmd2") << QVector({8, 4, 2}) << QVector({8, 4, 2}); +} + +void TestDice::spreadTest() +{ + QFETCH(QVector, values); + + TestNode node; + SplitNode split; + + DiceResult result; + makeResultExplode(result, values); + node.setResult(&result); + + node.setNextNode(&split); + + node.run(nullptr); + + auto list= dynamic_cast(split.getResult())->getResultList(); + + auto expected= result.getResultList(); + QVERIFY(list.size() == values.size()); +} + +void TestDice::spreadTest_data() +{ + QTest::addColumn>("values"); + + QTest::addRow("cmd1") << QVector({8, 4, 2}); +} + +void TestDice::groupTest() {} +void TestDice::groupTest_data() {} + +void TestDice::bindTest() {} +void TestDice::bindTest_data() {} + +void TestDice::occurenceTest() +{ + QFETCH(QVector, values); + QFETCH(int, condition); + QFETCH(QString, expected); + + TestNode node; + OccurenceCountNode count; + + DiceResult result; + makeResult(result, values); + node.setResult(&result); + + auto validator= makeValidator(condition, BooleanCondition::GreaterThan); + count.setValidator(validator); + node.setNextNode(&count); + + node.run(nullptr); + + auto text= dynamic_cast(count.getResult())->getText(); + + QVERIFY(text.startsWith(expected)); +} +void TestDice::occurenceTest_data() +{ + QTest::addColumn>("values"); + QTest::addColumn("condition"); + QTest::addColumn("expected"); + + QTest::addRow("cmd1") << QVector({8, 8, 2}) << 7 << "2x8"; + QTest::addRow("cmd2") << QVector({0, 0, 0}) << 1 << "No matching result"; +} + +void TestDice::ifCommandTest() +{ + QFETCH(QString, cmd); + QFETCH(BooleanCondition::LogicOperator, compare); + QFETCH(QList, level); + QFETCH(QStringList, startExperted); + + bool test= m_diceParser->parseLine(cmd); + QVERIFY2(test, cmd.toStdString().c_str()); + m_diceParser->start(); + auto results= m_diceParser->getLastIntegerResults(); + auto strResult= m_diceParser->getStringResult(); + + QCOMPARE(results.size(), 1); + QCOMPARE(strResult.size(), 1); + + auto result= results.first(); + auto it= std::find_if(level.begin(), level.end(), [compare, result](int level) { + if(compare == BooleanCondition::GreaterOrEqual) + return result >= level; + else if(compare == BooleanCondition::GreaterThan) + return result > level; + else if(compare == BooleanCondition::LesserThan) + return result < level; + else if(compare == BooleanCondition::LesserOrEqual) + return result <= level; + else if(compare == BooleanCondition::Equal) + return qFuzzyCompare(result, level); + else // if(compare == BooleanCondition::Different) + return !qFuzzyCompare(result, level); + }); + + auto index= std::distance(level.begin(), it); + + auto strResultExpected= startExperted[index]; + auto resultText= strResult.first(); + + QVERIFY2(resultText.startsWith(strResultExpected), "string result does not fit the expectation"); +} + +void TestDice::ifCommandTest_data() +{ + QTest::addColumn("cmd"); + QTest::addColumn("compare"); + QTest::addColumn>("level"); + QTest::addColumn("startExperted"); + + QTest::addRow("cmd1") << "2d10i:[>=15]{\"Complete Success: %1 [%2]\"}{i:[>=10]{\"Success with Complications: %1 " + "[%2]\"}{\"Failure: %1 [%2]\"}}" + << BooleanCondition::GreaterOrEqual << QList({15, 10, 1}) + << QStringList({"Complete Success:", "Success with Complications:", "Failure:"}); + QTest::addRow("cmd2") + << "2d10;$1i:[>=15]{\"Complete Success: %1 [%2]\"}{$1i:[>=10]{\"Success with Complications: %1 " + "[%2]\"}{\"Failure: %1 [%2]\"}}" + << BooleanCondition::GreaterOrEqual << QList({15, 10, 1}) + << QStringList({"Complete Success:", "Success with Complications:", "Failure:"}); +} + +void TestDice::cleanupTestCase() {} + +QTEST_MAIN(TestDice) + +#include "tst_dice.moc" diff --git a/tests/testnode.cpp b/tests/testnode.cpp deleted file mode 100644 index de9fc05..0000000 --- a/tests/testnode.cpp +++ /dev/null @@ -1,49 +0,0 @@ -#include "testnode.h" -#include "die.h" - -TestNode::TestNode() {} - -TestNode::~TestNode() -{ - m_nextNode= nullptr; - m_result= nullptr; -} -void TestNode::run(ExecutionNode* previous) -{ - Q_UNUSED(previous) - if(nullptr != m_nextNode) - { - m_nextNode->run(this); - } -} - -QString TestNode::toString(bool wl) const -{ - if(wl) - { - return QStringLiteral("%1 [label=\"TestNode \"]").arg(m_id); - } - else - { - return m_id; - } -} -qint64 TestNode::getPriority() const -{ - qint64 priority= 4; - return priority; -} -ExecutionNode* TestNode::getCopy() const -{ - TestNode* node= new TestNode(); - if(nullptr != m_nextNode) - { - node->setNextNode(m_nextNode->getCopy()); - } - return node; -} - -void TestNode::setResult(Result* result) -{ - m_result= result; -} diff --git a/tests/testnode.h b/tests/testnode.h deleted file mode 100644 index 5c918ee..0000000 --- a/tests/testnode.h +++ /dev/null @@ -1,44 +0,0 @@ -#ifndef TESTNODE_H -#define TESTNODE_H - -#include - -#include "executionnode.h" -#include "result/diceresult.h" -#include -/** - * @brief The TestNode class replaces any kind of node for test purpose. - */ -class TestNode : public ExecutionNode -{ -public: - /** - * @brief TestNode builds an instance - * @param faces, number of faces of dices - * @param offset, first value of dice. - */ - TestNode(); - virtual ~TestNode() override; - - /** - * @brief run - starts to roll dice. - */ - virtual void run(ExecutionNode*) override; - /** - * @brief toString - * @param wl - * @return use to generate dot tree; - */ - virtual QString toString(bool wl) const override; - /** - * @brief getPriority - * @return priority for dice roll: 4 (higher) - */ - virtual qint64 getPriority() const override; - - virtual ExecutionNode* getCopy() const override; - - void setResult(Result* result); -}; - -#endif // TESTNODE_H diff --git a/tests/tst_dice.cpp b/tests/tst_dice.cpp deleted file mode 100644 index 1fe2641..0000000 --- a/tests/tst_dice.cpp +++ /dev/null @@ -1,1069 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2011 by Renaud Guezennec * - * http://renaudguezennec.homelinux.org/accueil,3.html * - * * - * Rolisteam is free software; you can redistribute it and/or modify * - * it under the terms of the GNU General Public License as published by * - * the Free Software Foundation; either version 2 of the License, or * - * (at your option) any later version. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program; if not, write to the * - * Free Software Foundation, Inc., * - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * - ***************************************************************************/ - -#include -#include -#include - -#include "dicealias.h" -#include "diceparser.h" -#include "die.h" - -// node -#include "booleancondition.h" -#include "node/bind.h" -#include "node/countexecutenode.h" -#include "node/explodedicenode.h" -#include "node/filternode.h" -#include "node/groupnode.h" -#include "node/ifnode.h" -#include "node/jumpbackwardnode.h" -#include "node/keepdiceexecnode.h" -#include "node/numbernode.h" -#include "node/occurencecountnode.h" -#include "node/rerolldicenode.h" -#include "node/sortresult.h" -#include "node/splitnode.h" -#include "node/stringnode.h" -#include "node/uniquenode.h" -#include "result/stringresult.h" -#include "testnode.h" - -class TestDice : public QObject -{ - Q_OBJECT - -public: - TestDice(); - -private slots: - void init(); - void getAndSetTest(); - void diceRollD10Test(); - void diceRollD20Test(); - void commandEndlessLoop(); - - void mathPriority(); - void mathPriority_data(); - - void commandsTest(); - void commandsTest_data(); - - void dangerousCommandsTest(); - void dangerousCommandsTest_data(); - - void wrongCommandsTest(); - void wrongCommandsTest_data(); - - void wrongCommandsExecutionTimeTest(); - void scopeDF(); - void scopeDF_data(); - - void severalInstruction(); - void testAlias(); - void cleanupTestCase(); - - void keepTest(); - void keepTest_data(); - - void sortTest(); - void sortTest_data(); - - void countTest(); - void countTest_data(); - - void rerollTest(); - void rerollTest_data(); - - void explodeTest(); - void explodeTest_data(); - - void rerollUntilTest(); - void rerollUntilTest_data(); - - void rerollAddTest(); - void rerollAddTest_data(); - - void mergeTest(); - void mergeTest_data(); - - void ifTest(); - void ifTest_data(); - - void ifCommandTest(); - void ifCommandTest_data(); - - void paintTest(); - void paintTest_data(); - - void filterTest(); - void filterTest_data(); - - void uniqueTest(); - void uniqueTest_data(); - - void spreadTest(); - void spreadTest_data(); - - void groupTest(); - void groupTest_data(); - - void bindTest(); - void bindTest_data(); - - void occurenceTest(); - void occurenceTest_data(); - -private: - std::unique_ptr m_die; - std::unique_ptr m_diceParser; -}; - -TestDice::TestDice() {} - -void TestDice::init() -{ - m_die.reset(new Die()); - m_diceParser.reset(new DiceParser()); -} - -void TestDice::getAndSetTest() -{ - for(unsigned int i= 0; i < 2000; i++) - { - m_die->setMaxValue(i); - QVERIFY(m_die->getMaxValue() == i); - } - - m_die->setSelected(true); - QVERIFY(m_die->isSelected() == true); - - m_die->setSelected(false); - QVERIFY(m_die->isSelected() == false); -} - -void TestDice::diceRollD10Test() -{ - m_die->setMaxValue(10); - for(int i= 0; i < 2000; i++) - { - m_die->roll(false); - QVERIFY(m_die->getValue() > 0); - QVERIFY(m_die->getValue() < 11); - } -} -void TestDice::diceRollD20Test() -{ - m_die->setMaxValue(20); - for(int i= 0; i < 2000; i++) - { - m_die->roll(false); - QVERIFY(m_die->getValue() > 0); - QVERIFY(m_die->getValue() < 21); - } -} -void TestDice::commandEndlessLoop() -{ - bool a= m_diceParser->parseLine("1D10e[>0]"); - QVERIFY(!a); -} - -void TestDice::commandsTest() -{ - QFETCH(QString, cmd); - - bool a= m_diceParser->parseLine(cmd); - QVERIFY2(a, "parsing"); - - m_diceParser->start(); - QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error"); - QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning"); -} - -void TestDice::commandsTest_data() -{ - QTest::addColumn("cmd"); - - QTest::addRow("cmd1") << "1L[cheminée,chocolat,épée,arc,chute de pierre]"; - QTest::addRow("cmd2") << "10d10c[>=6]-@c[=1]"; - QTest::addRow("cmd3") << "10d10c[>=6]-@c[=1]-@c[=1]"; - QTest::addRow("cmd4") << "10d10c[>6]+@c[=10]"; - QTest::addRow("cmd5") << "1+1D10"; - QTest::addRow("cmd6") << "3d10c[>=5]"; - QTest::addRow("cmd7") << "1+(4*3)D10"; - QTest::addRow("cmd8") << "2+4/4"; - QTest::addRow("cmd9") << "2D10*2D20*8"; - QTest::addRow("cmd10") << "1+(4*3)D10"; - QTest::addRow("cmd11") << "(4D6)D10"; - QTest::addRow("cmd12") << "1D100a[>=95]a[>=96]a[>=97]a[>=98]a[>=99]e[>=100]"; - QTest::addRow("cmd13") << "3D100"; - QTest::addRow("cmd14") << "4k3"; - QTest::addRow("cmd15") << "10D10e[>=6]sc[>=6]"; - QTest::addRow("cmd16") << "10D10e10s"; - QTest::addRow("cmd17") << "10D10s"; - QTest::addRow("cmd18") << "15D10e10c[8-10]"; - QTest::addRow("cmd19") << "10d10e10"; - QTest::addRow("cmd30") << "(4+4)^4"; - QTest::addRow("cmd31") << "(1d20+20)*7/10"; - QTest::addRow("cmd32") << "20*7/10"; - QTest::addRow("cmd33") << "1D8+2D6+7"; - QTest::addRow("cmd34") << "D25"; - QTest::addRow("cmd35") << "1L[tete[10],ventre[50],jambe[40]]"; - QTest::addRow("cmd36") << "2d6c[%2=0]"; - QTest::addRow("cmd37") << "D25+D10"; - QTest::addRow("cmd38") << "D25;D10"; - QTest::addRow("cmd39") << "8+8+8"; - QTest::addRow("cmd40") << "1D20-88"; - QTest::addRow("cmd41") << "100*1D20*2D6"; - QTest::addRow("cmd42") << "2D6 # two 6sided dice"; - QTest::addRow("cmd43") << "100/28*3"; - QTest::addRow("cmd44") << "100/8"; - QTest::addRow("cmd45") << "100*3*8"; - QTest::addRow("cmd46") << "help"; - QTest::addRow("cmd47") << "la"; - QTest::addRow("cmd48") << "10D10c[<2|>7]"; - QTest::addRow("cmd49") << "10D6c[=2|=4|=6]"; - QTest::addRow("cmd50") << "10D10e[=1|=10]k4"; - QTest::addRow("cmd51") << "1L[tete,bras droit,bras gauche,jambe droite,jambe gauche,ventre[6-7],buste[8-10]]"; - QTest::addRow("cmd52") << "10+10s"; - QTest::addRow("cmd53") << "1d6e6;1d4e4mk1"; - QTest::addRow("cmd54") << "1d6e6;1d4e4mk1"; - QTest::addRow("cmd55") << "400D20/400000"; - QTest::addRow("cmd56") << "1d100e[>=95]i[<5]{-1d100e95}"; - QTest::addRow("cmd57") << "100*3*8"; - QTest::addRow("cmd58") << "1d100i[<70]{1d10i[=10]{1d100i[<70]{1d10e10}}}"; - QTest::addRow("cmd59") << "10d6c[<2|>5]"; - QTest::addRow("cmd60") << "5-5*5+5"; - QTest::addRow("cmd61") << "((3+4)*2)d6"; - QTest::addRow("cmd62") << "4d6i[=6]{+1d6}"; - QTest::addRow("cmd63") << "10d[-8--1]"; - QTest::addRow("cmd64") << "4d6e6i[=4]{-4}+2"; - QTest::addRow("cmd65") << "4d6e6f[!=4]+2"; - QTest::addRow("cmd66") << "5d10g10"; - QTest::addRow("cmd67") << "4d6p[4:blue]c[>=4];1d6p[1:#FFFFFF]c6-@c1;1d6p[1:#FF0000]c[>=4]+@c6-@c1"; - QTest::addRow("cmd68") << "10d[0-9]"; - QTest::addRow("cmd69") << "1d8e8;1d6e6mk1+2"; - QTest::addRow("cmd70") << "3d100g50"; - QTest::addRow("cmd71") << "3d100g33"; - QTest::addRow("cmd72") << "3d100g5"; - QTest::addRow("cmd73") << "3d100g40"; - QTest::addRow("cmd74") << "2d10k1+2d10k1+2d10k1"; - QTest::addRow("cmd75") << "2d10k1-2d10k1-2d10k1"; - QTest::addRow("cmd76") << "(2d10k1)-2d10k1-2d10k1"; - QTest::addRow("cmd77") << "2d10k1-(2d10k1)-2d10k1"; - QTest::addRow("cmd78") << "2d10k1-2d10k1-(2d10k1)"; - QTest::addRow("cmd79") << "1d6-2d6e6"; - QTest::addRow("cmd80") << "(1)-1d6e6"; - QTest::addRow("cmd81") << "(1)-(1d6e6)"; - QTest::addRow("cmd82") << "8d10o"; - QTest::addRow("cmd83") << "8d10o2,4"; - QTest::addRow("cmd84") << "8d10o2[>2]"; - QTest::addRow("cmd85") << "8d10ok2"; - QTest::addRow("cmd86") << "[100,200,300]k2"; - QTest::addRow("cmd87") << "100;200;300;[$1,$2,$3]k2"; -} - -void TestDice::wrongCommandsTest() -{ - // << "pajaejlbnmàw"; - QFETCH(QString, cmd); - QFETCH(bool, valid); - bool a= m_diceParser->parseLine(cmd); - if(a) - { - m_diceParser->start(); - auto map= m_diceParser->getErrorMap(); - a= map.isEmpty(); - } - QCOMPARE(a, valid); -} - -void TestDice::wrongCommandsTest_data() -{ - QTest::addColumn("cmd"); - QTest::addColumn("valid"); - - QTest::newRow("test1") << "1L[cheminée,chocolat,épée,arc,chute de pierre" << false; - QTest::newRow("test2") << "10d10c" << false; - QTest::newRow("test3") << "10d10a" << false; - QTest::newRow("test4") << "10d0a[>7]" << false; - QTest::newRow("test5") << "aiteanetauearuteurn" << false; - QTest::newRow("test6") << "meregue" << false; - QTest::newRow("test7") << "p i follow rivers" << false; - QTest::newRow("test8") << "manga violet evergarden" << false; - QTest::newRow("test9") << "((1d8e8+2);(1d6e6+2))" << true; -} - -void TestDice::wrongCommandsExecutionTimeTest() -{ - QStringList commands; - - //<< "8D20+10*@c[=20]" - commands << "1/0" - << "" - << "0d10" - << "10d10k11" - << "!!!!"; - - for(QString cmd : commands) - { - bool test= m_diceParser->parseLine(cmd); - m_diceParser->start(); - - QVERIFY2(m_diceParser->getErrorMap().isEmpty() == false || !test, cmd.toStdString().c_str()); - } -} -void TestDice::scopeDF() -{ - QFETCH(QString, cmd); - QFETCH(int, min); - QFETCH(int, max); - QFETCH(bool, valid); - - bool test= m_diceParser->parseLine(cmd); - QVERIFY2(test == valid, cmd.toStdString().c_str()); - m_diceParser->start(); - auto results= m_diceParser->getLastIntegerResults(); - - for(auto result : results) - QVERIFY(result >= min && result <= max); -} - -void TestDice::scopeDF_data() -{ - QTest::addColumn("cmd"); - QTest::addColumn("min"); - QTest::addColumn("max"); - QTest::addColumn("valid"); - - QTest::newRow("test1") << "1D[-1-1]" << -1 << 1 << true; - QTest::newRow("test2") << "1D[-10--5]" << -10 << -5 << true; - QTest::newRow("test3") << "1D[-100-100]" << -100 << 100 << true; - QTest::newRow("test4") << "1D[-1-0]" << -1 << 0 << true; - QTest::newRow("test5") << "1D[10-20]" << 10 << 20 << true; - QTest::newRow("test6") << "1D[30-100]" << 30 << 100 << true; - QTest::newRow("test7") << "1D[0-99]" << 0 << 99 << true; - QTest::newRow("test8") << "5-5*5+5" << -15 << -15 << true; - QTest::newRow("test9") << "2d20c[<=13]+@c[<=3]" << 0 << 4 << true; - QTest::newRow("test10") << "6d10c[>=6]-@c1" << -6 << 6 << true; - QTest::newRow("test11") << "2d6k1+2d8k1+2d10k1" << 3 << 30 << true; - QTest::newRow("test12") << "1D[-2-50]" << -2 << 50 << true; -} -void TestDice::testAlias() -{ - m_diceParser->insertAlias(new DiceAlias("!", "3d6c"), 0); - m_diceParser->insertAlias(new DiceAlias("g", "d10k"), 1); - m_diceParser->insertAlias(new DiceAlias("(.*)C(.*)", QStringLiteral("\\1d10e10c[>=\\2]"), false), 2); - - QStringList cmds; - cmds << "!2" - << "${rang}g4" - << "${rang}g4 # gerald" - << "5C3" - << "1d100i:[<101]{\"great!\"}{\"try again\"}"; - - QStringList expected; - expected << "3d6c2" - << "${rang}d10k4" - << "${rang}d10k4 # gerald" - << "5d10e10c[>=3]" - << "1d100i:[<101]{\"great!\"}{\"try again\"}"; - - int i= 0; - for(auto cmd : cmds) - { - auto result= m_diceParser->convertAlias(cmd); - QVERIFY2(result == expected[i], result.toLatin1()); - ++i; - } -} -void TestDice::severalInstruction() -{ - QStringList commands; - - commands << "1d10;2d20;$1+$2"; - - QList results; - results << 3; - - int i= 0; - for(auto cmd : commands) - { - auto test= m_diceParser->parseLine(cmd); - QVERIFY2(test, cmd.toStdString().c_str()); - QVERIFY2(m_diceParser->getStartNodeCount() == results[i], "Wrong number of instruction"); - } -} -void TestDice::mathPriority() -{ - QFETCH(QString, cmd); - QFETCH(int, expected); - - bool test= m_diceParser->parseLine(cmd); - QVERIFY(test); - m_diceParser->start(); - auto resultList= m_diceParser->getLastIntegerResults(); - QCOMPARE(resultList.size(), 1); - - auto value= resultList.first(); - QVERIFY(qFuzzyCompare(value, expected) == 1); -} - -void TestDice::mathPriority_data() -{ - QTest::addColumn("cmd"); - QTest::addColumn("expected"); - - QTest::addRow("cmd1") << "10+2" << 12; - QTest::addRow("cmd2") << "2-10" << -8; - QTest::addRow("cmd3") << "5+2*3" << 11; - QTest::addRow("cmd4") << "5-5*5+5" << -15; - QTest::addRow("cmd5") << "5-5/5+5" << 9; - QTest::addRow("cmd6") << "10*(3*2)" << 60; - QTest::addRow("cmd7") << "60/(3*2)" << 10; - QTest::addRow("cmd8") << "5-(5*5+5)" << -25; -} - -void TestDice::dangerousCommandsTest() -{ - QFETCH(QString, cmd); - - for(int i= 0; i < 1000; ++i) - { - auto b= m_diceParser->parseLine(cmd); - QVERIFY(b); - m_diceParser->start(); - } -} -void TestDice::dangerousCommandsTest_data() -{ - QTest::addColumn("cmd"); - - QTest::addRow("cmd1") << "10d6g10"; - QTest::addRow("cmd2") << "10d2g10"; - QTest::addRow("cmd3") << "10d10g10"; - // QTest::addRow("cmd4") << "10d10g10"; - // QTest::addRow("cmd5") << "10d10g10"; -} - -void makeResult(DiceResult& result, const QVector& values) -{ - for(int val : values) - { - auto die= new Die(); - die->setBase(1); - die->setMaxValue(10); - die->insertRollValue(val); - result.insertResult(die); - } -} - -void makeResultExplode(DiceResult& result, const QVector& values) -{ - auto die= new Die(); - die->setBase(1); - die->setMaxValue(10); - for(int val : values) - { - die->insertRollValue(val); - } - result.insertResult(die); -} - -Validator* makeValidator(int number, BooleanCondition::LogicOperator op) -{ - BooleanCondition* validator= new BooleanCondition(); - NumberNode* node= new NumberNode(); - node->setNumber(number); - validator->setValueNode(node); - validator->setOperator(op); - return validator; -} - -void TestDice::keepTest() -{ - QFETCH(QVector, values); - QFETCH(int, keep); - QFETCH(int, score); - QFETCH(bool, error); - - TestNode node; - KeepDiceExecNode keepN; - keepN.setDiceKeepNumber(keep); - - DiceResult result; - - makeResult(result, values); - - node.setResult(&result); - node.setNextNode(&keepN); - - node.run(nullptr); - - bool isErrorEmpty= !keepN.getExecutionErrorMap().isEmpty(); - - QCOMPARE(isErrorEmpty, error); - - if(error) - return; - - auto resultScore= keepN.getResult()->getResult(Result::SCALAR).toInt(); - - QCOMPARE(score, resultScore); -} - -void TestDice::keepTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("keep"); - QTest::addColumn("score"); - QTest::addColumn("error"); - - QTest::addRow("cmd1") << QVector({10, 9, 2}) << 1 << 10 << false; - QTest::addRow("cmd2") << QVector({10, 9, 2}) << 2 << 19 << false; - QTest::addRow("cmd3") << QVector({10, 9, 2}) << 3 << 21 << false; - QTest::addRow("cmd4") << QVector({10, 9, 2}) << 4 << 0 << true; -} - -void TestDice::sortTest() -{ - QFETCH(QVector, values); - QFETCH(bool, ascending); - QFETCH(QVector, scores); - - TestNode node; - SortResultNode sortN; - sortN.setSortAscending(ascending); - - DiceResult result; - - makeResult(result, values); - - node.setResult(&result); - node.setNextNode(&sortN); - - DiceResult expectedScore; - makeResult(expectedScore, scores); - - node.run(nullptr); - - auto list= dynamic_cast(sortN.getResult())->getResultList(); - - int i= 0; - auto expected= expectedScore.getResultList(); - for(auto sortedDie : list) - { - QCOMPARE(expected[i]->getValue(), sortedDie->getValue()); - ++i; - } -} - -void TestDice::sortTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("ascending"); - QTest::addColumn>("scores"); - - QTest::addRow("cmd1") << QVector({10, 9, 2}) << true << QVector({2, 9, 10}); - QTest::addRow("cmd2") << QVector({1, 2, 3}) << false << QVector({3, 2, 1}); - QTest::addRow("cmd3") << QVector({10, 9, 2}) << false << QVector({10, 9, 2}); - QTest::addRow("cmd4") << QVector({2, 9, 10}) << true << QVector({2, 9, 10}); - QTest::addRow("cmd5") << QVector({1, 25, 10}) << false << QVector({25, 10, 1}); - QTest::addRow("cmd6") << QVector({10, 2, 100}) << false << QVector({100, 10, 2}); -} - -void TestDice::countTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(int, score); - - TestNode node; - CountExecuteNode countN; - - auto validator= makeValidator(condition, BooleanCondition::GreaterThan); - - countN.setValidator(validator); - DiceResult result; - node.setResult(&result); - node.setNextNode(&countN); - - makeResult(result, values); - - node.run(nullptr); - - QCOMPARE(score, countN.getResult()->getResult(Result::SCALAR).toInt()); - - countN.setValidator(nullptr); -} - -void TestDice::countTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("score"); - - QTest::addRow("cmd1") << QVector({10, 9, 2}) << 3 << 2; - QTest::addRow("cmd2") << QVector({1, 2, 3}) << 3 << 0; -} - -void TestDice::rerollTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(bool, different); - - TestNode node; - RerollDiceNode reroll(true, false); - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - auto validator= makeValidator(condition, BooleanCondition::GreaterThan); - reroll.setValidator(validator); - node.setNextNode(&reroll); - - node.run(nullptr); - - auto list= dynamic_cast(reroll.getResult())->getResultList(); - - int i= 0; - auto expected= result.getResultList(); - bool resultDiff= false; - for(auto rerolled : list) - { - if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) - resultDiff= true; - ++i; - } - - QCOMPARE(different, resultDiff); -} - -void TestDice::rerollTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("different"); - - QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; - QTest::addRow("cmd2") << QVector({0, 0, 0}) << -1 << true; -} - -void TestDice::explodeTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(bool, different); - - TestNode node; - ExplodeDiceNode explode; - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - auto validator= makeValidator(condition, BooleanCondition::Equal); - explode.setValidator(validator); - node.setNextNode(&explode); - - node.run(nullptr); - - auto list= dynamic_cast(explode.getResult())->getResultList(); - - int i= 0; - auto expected= result.getResultList(); - bool resultDiff= false; - for(auto rerolled : list) - { - if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) - resultDiff= true; - ++i; - } - - QCOMPARE(different, resultDiff); -} - -void TestDice::explodeTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("different"); - - QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; - QTest::addRow("cmd2") << QVector({0, 0, 0}) << 0 << true; -} - -void TestDice::rerollUntilTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(bool, different); - - TestNode node; - RerollDiceNode reroll(false, false); - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - auto validator= makeValidator(condition, BooleanCondition::Equal); - reroll.setValidator(validator); - node.setNextNode(&reroll); - - node.run(nullptr); - - auto list= dynamic_cast(reroll.getResult())->getResultList(); - - int i= 0; - auto expected= result.getResultList(); - bool resultDiff= false; - for(auto rerolled : list) - { - if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) - resultDiff= true; - ++i; - } - - QCOMPARE(different, resultDiff); -} -void TestDice::rerollUntilTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("different"); - - QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; - QTest::addRow("cmd2") << QVector({0, 0, 0}) << 0 << true; -} - -void TestDice::rerollAddTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(bool, different); - - TestNode node; - RerollDiceNode reroll(true, true); - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - auto validator= makeValidator(condition, BooleanCondition::Equal); - reroll.setValidator(validator); - node.setNextNode(&reroll); - - node.run(nullptr); - - auto list= dynamic_cast(reroll.getResult())->getResultList(); - - int i= 0; - auto expected= result.getResultList(); - bool resultDiff= false; - for(auto rerolled : list) - { - if(!resultDiff && rerolled->getValue() != expected[i]->getValue()) - resultDiff= true; - ++i; - } - - QCOMPARE(different, resultDiff); -} -void TestDice::rerollAddTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("different"); - - QTest::addRow("cmd1") << QVector({8, 9, 2}) << 10 << false; - QTest::addRow("cmd2") << QVector({0, 0, 0}) << 0 << true; -} - -void TestDice::mergeTest() {} -void TestDice::mergeTest_data() {} - -void TestDice::ifTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(int, valCondition); - QFETCH(QString, expectedResult); - - IfNode::ConditionType conditionType= static_cast(condition); - - TestNode node; - IfNode ifNode; - ifNode.setConditionType(conditionType); - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - StringNode trueNode; - trueNode.setString(QStringLiteral("True")); - StringNode falseNode; - falseNode.setString(QStringLiteral("False")); - - ifNode.setInstructionTrue(&trueNode); - ifNode.setInstructionFalse(&falseNode); - - auto validator= makeValidator(valCondition, BooleanCondition::Equal); - ifNode.setValidator(validator); - node.setNextNode(&ifNode); - - node.run(nullptr); - - auto text= dynamic_cast(ifNode.getNextNode()->getResult())->getText(); - - QCOMPARE(expectedResult, text); - - ifNode.setNextNode(nullptr); -} -void TestDice::ifTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("valCondition"); - QTest::addColumn("expectedResult"); - - int onEach= 0; - int oneOfThem= 1; - int allOfThem= 2; - int onScalar= 3; - - QTest::addRow("cmd1") << QVector({8, 9, 2}) << onEach << 0 << "False"; - QTest::addRow("cmd2") << QVector({2, 2, 2}) << onEach << 2 << "True"; - - QTest::addRow("cmd3") << QVector({0, 0, 0}) << oneOfThem << 10 << "False"; - QTest::addRow("cmd4") << QVector({10, 9, 5}) << oneOfThem << 10 << "True"; - QTest::addRow("cmd5") << QVector({9, 9, 9}) << oneOfThem << 9 << "True"; - - QTest::addRow("cmd6") << QVector({8, 9, 2}) << allOfThem << 1 << "False"; - QTest::addRow("cmd7") << QVector({8, 9, 2}) << allOfThem << 9 << "False"; - QTest::addRow("cmd8") << QVector({8, 8, 8}) << allOfThem << 8 << "True"; - - QTest::addRow("cmd9") << QVector({25, 8, 14}) << onScalar << 1 << "False"; - QTest::addRow("cmd10") << QVector({25, 8, 14}) << onScalar << 47 << "True"; -} - -void TestDice::paintTest() {} -void TestDice::paintTest_data() {} - -void TestDice::filterTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(bool, different); - - TestNode node; - FilterNode filter; - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - auto validator= makeValidator(condition, BooleanCondition::Different); - filter.setValidator(validator); - node.setNextNode(&filter); - - node.run(nullptr); - - auto list= dynamic_cast(filter.getResult())->getResultList(); - - auto expected= result.getResultList(); - bool resultDiff= (list.size() != expected.size()); - - QCOMPARE(different, resultDiff); -} - -void TestDice::filterTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("different"); - - QTest::addRow("cmd1") << QVector({8, 4, 2}) << 4 << true; - QTest::addRow("cmd2") << QVector({0, 0, 0}) << 1 << false; -} - -void TestDice::uniqueTest() -{ - QFETCH(QVector, values); - QFETCH(QVector, expected); - - TestNode node; - UniqueNode unique; - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - node.setNextNode(&unique); - node.run(nullptr); - - auto list= dynamic_cast(unique.getResult())->getResultList(); - QVector resultVal; - - std::transform(list.begin(), list.end(), std::back_inserter(resultVal), [](Die* die) { return die->getValue(); }); - - QVERIFY(resultVal == expected); -} - -void TestDice::uniqueTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn>("expected"); - - QTest::addRow("cmd1") << QVector({8, 4, 2, 8}) << QVector({8, 4, 2}); - QTest::addRow("cmd2") << QVector({8, 4, 2}) << QVector({8, 4, 2}); -} - -void TestDice::spreadTest() -{ - QFETCH(QVector, values); - - TestNode node; - SplitNode split; - - DiceResult result; - makeResultExplode(result, values); - node.setResult(&result); - - node.setNextNode(&split); - - node.run(nullptr); - - auto list= dynamic_cast(split.getResult())->getResultList(); - - auto expected= result.getResultList(); - QVERIFY(list.size() == values.size()); -} - -void TestDice::spreadTest_data() -{ - QTest::addColumn>("values"); - - QTest::addRow("cmd1") << QVector({8, 4, 2}); -} - -void TestDice::groupTest() {} -void TestDice::groupTest_data() {} - -void TestDice::bindTest() {} -void TestDice::bindTest_data() {} - -void TestDice::occurenceTest() -{ - QFETCH(QVector, values); - QFETCH(int, condition); - QFETCH(QString, expected); - - TestNode node; - OccurenceCountNode count; - - DiceResult result; - makeResult(result, values); - node.setResult(&result); - - auto validator= makeValidator(condition, BooleanCondition::GreaterThan); - count.setValidator(validator); - node.setNextNode(&count); - - node.run(nullptr); - - auto text= dynamic_cast(count.getResult())->getText(); - - QVERIFY(text.startsWith(expected)); -} -void TestDice::occurenceTest_data() -{ - QTest::addColumn>("values"); - QTest::addColumn("condition"); - QTest::addColumn("expected"); - - QTest::addRow("cmd1") << QVector({8, 8, 2}) << 7 << "2x8"; - QTest::addRow("cmd2") << QVector({0, 0, 0}) << 1 << "No matching result"; -} - -void TestDice::ifCommandTest() -{ - QFETCH(QString, cmd); - QFETCH(BooleanCondition::LogicOperator, compare); - QFETCH(QList, level); - QFETCH(QStringList, startExperted); - - bool test= m_diceParser->parseLine(cmd); - QVERIFY2(test, cmd.toStdString().c_str()); - m_diceParser->start(); - auto results= m_diceParser->getLastIntegerResults(); - auto strResult= m_diceParser->getStringResult(); - - QCOMPARE(results.size(), 1); - QCOMPARE(strResult.size(), 1); - - auto result= results.first(); - auto it= std::find_if(level.begin(), level.end(), [compare, result](int level) { - if(compare == BooleanCondition::GreaterOrEqual) - return result >= level; - else if(compare == BooleanCondition::GreaterThan) - return result > level; - else if(compare == BooleanCondition::LesserThan) - return result < level; - else if(compare == BooleanCondition::LesserOrEqual) - return result <= level; - else if(compare == BooleanCondition::Equal) - return qFuzzyCompare(result, level); - else // if(compare == BooleanCondition::Different) - return !qFuzzyCompare(result, level); - }); - - auto index= std::distance(level.begin(), it); - - auto strResultExpected= startExperted[index]; - auto resultText= strResult.first(); - - QVERIFY2(resultText.startsWith(strResultExpected), "string result does not fit the expectation"); -} - -void TestDice::ifCommandTest_data() -{ - QTest::addColumn("cmd"); - QTest::addColumn("compare"); - QTest::addColumn>("level"); - QTest::addColumn("startExperted"); - - QTest::addRow("cmd1") << "2d10i:[>=15]{\"Complete Success: %1 [%2]\"}{i:[>=10]{\"Success with Complications: %1 " - "[%2]\"}{\"Failure: %1 [%2]\"}}" - << BooleanCondition::GreaterOrEqual << QList({15, 10, 1}) - << QStringList({"Complete Success:", "Success with Complications:", "Failure:"}); - QTest::addRow("cmd2") - << "2d10;$1i:[>=15]{\"Complete Success: %1 [%2]\"}{$1i:[>=10]{\"Success with Complications: %1 " - "[%2]\"}{\"Failure: %1 [%2]\"}}" - << BooleanCondition::GreaterOrEqual << QList({15, 10, 1}) - << QStringList({"Complete Success:", "Success with Complications:", "Failure:"}); -} - -void TestDice::cleanupTestCase() {} - -QTEST_MAIN(TestDice) - -#include "tst_dice.moc" -- cgit v1.2.3-70-g09d2