File indexing completed on 2024-05-12 05:39:33

0001 /***************************************************************************
0002  *   Copyright (C) 2011 by Renaud Guezennec                                *
0003  *   http://renaudguezennec.homelinux.org/accueil,3.html                   *
0004  *                                                                         *
0005  *   Rolisteam is free software; you can redistribute it and/or modify     *
0006  *   it under the terms of the GNU General Public License as published by  *
0007  *   the Free Software Foundation; either version 2 of the License, or     *
0008  *   (at your option) any later version.                                   *
0009  *                                                                         *
0010  *   This program is distributed in the hope that it will be useful,       *
0011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0013  *   GNU General Public License for more details.                          *
0014  *                                                                         *
0015  *   You should have received a copy of the GNU General Public License     *
0016  *   along with this program; if not, write to the                         *
0017  *   Free Software Foundation, Inc.,                                       *
0018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
0019  ***************************************************************************/
0020 
0021 #include <QtCore/QCoreApplication>
0022 #include <QtCore/QString>
0023 #include <QtTest/QtTest>
0024 
0025 #include "diceparser/dicealias.h"
0026 #include "diceparser/diceparser.h"
0027 #include "die.h"
0028 
0029 // node
0030 #include "booleancondition.h"
0031 #include "diceparser/parsingtoolbox.h"
0032 #include "node/bind.h"
0033 #include "node/countexecutenode.h"
0034 #include "node/explodedicenode.h"
0035 #include "node/filternode.h"
0036 #include "node/groupnode.h"
0037 #include "node/ifnode.h"
0038 #include "node/jumpbackwardnode.h"
0039 #include "node/keepdiceexecnode.h"
0040 #include "node/numbernode.h"
0041 #include "node/occurencecountnode.h"
0042 #include "node/rerolldicenode.h"
0043 #include "node/sortresult.h"
0044 #include "node/splitnode.h"
0045 #include "node/stringnode.h"
0046 #include "node/switchcasenode.h"
0047 #include "node/uniquenode.h"
0048 #include "node/valueslistnode.h"
0049 #include "operationcondition.h"
0050 #include "result/stringresult.h"
0051 #include "testnode.h"
0052 #include "validatorlist.h"
0053 
0054 void makeResult(DiceResult& result, const QVector<int>& values, const QVector<int>& subvalues= QVector<int>(),
0055                 int base= 1, int max= 10)
0056 {
0057     int i= 0;
0058     for(int val : values)
0059     {
0060         auto die= new Die();
0061         die->setBase(base);
0062         die->setMaxValue(max);
0063         die->insertRollValue(val);
0064         if(i == 0 && !subvalues.empty())
0065         {
0066             for(int sval : subvalues)
0067             {
0068                 die->insertRollValue(sval);
0069             }
0070         }
0071         result.insertResult(die);
0072         ++i;
0073     }
0074 }
0075 
0076 void makeResultExplode(DiceResult& result, const QVector<int>& values)
0077 {
0078     auto die= new Die();
0079     die->setBase(1);
0080     die->setMaxValue(10);
0081     for(int val : values)
0082     {
0083         die->insertRollValue(val);
0084     }
0085     result.insertResult(die);
0086 }
0087 
0088 ValidatorList* makeValidator(QVector<int> number, Dice::CompareOperator op,
0089                              QVector<Dice::LogicOperation> vector= QVector<Dice::LogicOperation>())
0090 {
0091     ValidatorList* list= new ValidatorList();
0092     QList<Validator*> validList;
0093     for(auto num : number)
0094     {
0095         BooleanCondition* validator= new BooleanCondition();
0096         NumberNode* node= new NumberNode();
0097         node->setNumber(num);
0098         validator->setValueNode(node);
0099         validator->setOperator(op);
0100         validList.append(validator);
0101     }
0102     list->setValidators(validList);
0103     if(!vector.isEmpty())
0104         list->setOperationList(vector);
0105     return list;
0106 }
0107 
0108 class TestDice : public QObject
0109 {
0110     Q_OBJECT
0111 
0112 public:
0113     TestDice();
0114 
0115 private slots:
0116     void init();
0117     void getAndSetTest();
0118 
0119     void validatorListTest();
0120     void validatorListTest_data();
0121 
0122     void diceRollD10Test();
0123     void diceRollD20Test();
0124     void commandEndlessLoop();
0125 
0126     void mathPriority();
0127     void mathPriority_data();
0128 
0129     void commandsTest();
0130     void commandsTest_data();
0131 
0132     void rangedCommandsTest();
0133     void rangedCommandsTest_data();
0134 
0135     void dangerousCommandsTest();
0136     void dangerousCommandsTest_data();
0137 
0138     void wrongCommandsTest();
0139     void wrongCommandsTest_data();
0140 
0141     void wrongCommandsExecutionTimeTest();
0142     void scopeDF();
0143     void scopeDF_data();
0144 
0145     void severalInstruction();
0146     void testAlias();
0147     void testAlias_data();
0148     void cleanupTestCase();
0149 
0150     void keepTest();
0151     void keepTest_data();
0152 
0153     void sortTest();
0154     void sortTest_data();
0155 
0156     void countTest();
0157     void countTest_data();
0158 
0159     void rerollTest();
0160     void rerollTest_data();
0161 
0162     void explodeTest();
0163     void explodeTest_data();
0164 
0165     void rerollUntilTest();
0166     void rerollUntilTest_data();
0167 
0168     void rerollAddTest();
0169     void rerollAddTest_data();
0170 
0171     void mergeTest();
0172     void mergeTest_data();
0173 
0174     void ifTest();
0175     void ifTest_data();
0176 
0177     void ifCommandTest();
0178     void ifCommandTest_data();
0179 
0180     void paintTest();
0181     void paintTest_data();
0182 
0183     void filterTest();
0184     void filterTest_data();
0185 
0186     void uniqueTest();
0187     void uniqueTest_data();
0188 
0189     void spreadTest();
0190     void spreadTest_data();
0191 
0192     void groupTest();
0193     void groupTest_data();
0194 
0195     void bindTest();
0196     void bindTest_data();
0197 
0198     void occurenceTest();
0199     void occurenceTest_data();
0200 
0201     void operatoionConditionValidatorTest();
0202 
0203     void switchCaseTest();
0204     void switchCaseTest_data();
0205 
0206     void deterministTest();
0207     void deterministTest_data();
0208 
0209 private:
0210     std::unique_ptr<Die> m_die;
0211     std::unique_ptr<DiceParser> m_diceParser;
0212     std::unique_ptr<ParsingToolBox> m_parsingToolBox;
0213 };
0214 
0215 TestDice::TestDice() {}
0216 
0217 void TestDice::init()
0218 {
0219     m_die.reset(new Die());
0220     m_diceParser.reset(new DiceParser());
0221     m_parsingToolBox.reset(new ParsingToolBox());
0222 }
0223 
0224 void TestDice::getAndSetTest()
0225 {
0226     for(unsigned int i= 0; i < 2000; i++)
0227     {
0228         m_die->setMaxValue(i);
0229         QVERIFY(m_die->getMaxValue() == i);
0230     }
0231 
0232     m_die->setSelected(true);
0233     QVERIFY(m_die->isSelected() == true);
0234 
0235     m_die->setSelected(false);
0236     QVERIFY(m_die->isSelected() == false);
0237 }
0238 
0239 void TestDice::validatorListTest()
0240 {
0241     QFETCH(QString, cmd);
0242     QFETCH(int, result);
0243 
0244     auto parsing= m_diceParser->parseLine(cmd);
0245     QVERIFY2(parsing, "parsing");
0246 
0247     m_diceParser->start();
0248     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
0249     QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning");
0250 
0251     auto resultCmd= m_diceParser->scalarResultsFromEachInstruction();
0252 
0253     QCOMPARE(resultCmd.size(), 1);
0254 
0255     QCOMPARE(resultCmd.first(), result);
0256 }
0257 
0258 void TestDice::validatorListTest_data()
0259 {
0260     QTest::addColumn<QString>("cmd");
0261     QTest::addColumn<int>("result");
0262 
0263     QTest::addRow("cmd1") << "2d[6..6]c6" << 2;
0264     QTest::addRow("cmd2") << "[6,2]c[:>6&%2=0]" << 2;
0265     QTest::addRow("cmd3") << "[6,1,1]c[=6|=1]" << 3;
0266 }
0267 
0268 void TestDice::diceRollD10Test()
0269 {
0270     m_die->setMaxValue(10);
0271     for(int i= 0; i < 2000; i++)
0272     {
0273         m_die->roll(false);
0274         QVERIFY(m_die->getValue() > 0);
0275         QVERIFY(m_die->getValue() < 11);
0276     }
0277 }
0278 void TestDice::diceRollD20Test()
0279 {
0280     m_die->setMaxValue(20);
0281     for(int i= 0; i < 2000; i++)
0282     {
0283         m_die->roll(false);
0284         QVERIFY(m_die->getValue() > 0);
0285         QVERIFY(m_die->getValue() < 21);
0286     }
0287 }
0288 
0289 void TestDice::commandEndlessLoop()
0290 {
0291     bool a= m_diceParser->parseLine("1D10e[>0]");
0292     QVERIFY(!a);
0293 }
0294 
0295 void TestDice::commandsTest()
0296 {
0297     QFETCH(QString, cmd);
0298 
0299     bool a= m_diceParser->parseLine(cmd);
0300     QVERIFY2(a, "parsing");
0301 
0302     m_diceParser->start();
0303     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
0304     QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning");
0305 }
0306 
0307 void TestDice::commandsTest_data()
0308 {
0309     QTest::addColumn<QString>("cmd");
0310 
0311     QTest::addRow("cmd1") << "1L[cheminée,chocolat,épée,arc,chute de pierre]";
0312     QTest::addRow("cmd2") << "10d10c[>=6]-@c[=1]";
0313     QTest::addRow("cmd3") << "10d10c[>=6]-@c[=1]-@c[=1]";
0314     QTest::addRow("cmd4") << "10d10c[>6]+@c[=10]";
0315     QTest::addRow("cmd5") << "1+1D10";
0316     QTest::addRow("cmd6") << "3d10c[>=5]";
0317     QTest::addRow("cmd7") << "1+(4*3)D10";
0318     QTest::addRow("cmd8") << "2+4/4";
0319     QTest::addRow("cmd9") << "2D10*2D20*8";
0320     QTest::addRow("cmd10") << "1+(4*3)D10";
0321     QTest::addRow("cmd11") << "(4D6)D10";
0322     QTest::addRow("cmd12") << "1D100a[>=95]a[>=96]a[>=97]a[>=98]a[>=99]e[>=100]";
0323     QTest::addRow("cmd13") << "3D100";
0324     QTest::addRow("cmd14") << "4k3";
0325 
0326     QTest::addRow("cmd15") << "10D10e[>=6]sc[>=6]";
0327     QTest::addRow("cmd16") << "10D10e10s";
0328     QTest::addRow("cmd17") << "10D10s";
0329     QTest::addRow("cmd18") << "15D10e10c[8..10]";
0330     QTest::addRow("cmd19") << "10d10e10";
0331     QTest::addRow("cmd30") << "(4+4)**4";
0332     QTest::addRow("cmd31") << "(1d20+20)*7/10";
0333     QTest::addRow("cmd32") << "20*7/10";
0334     QTest::addRow("cmd33") << "1D8+2D6+7";
0335     QTest::addRow("cmd34") << "D25";
0336     QTest::addRow("cmd35") << "1L[tete[10],ventre[50],jambe[40]]";
0337     QTest::addRow("cmd36") << "2d6c[%2=0]";
0338     QTest::addRow("cmd37") << "D25+D10";
0339     QTest::addRow("cmd38") << "D25;D10";
0340     QTest::addRow("cmd39") << "8+8+8";
0341     QTest::addRow("cmd40") << "1D20-88";
0342     QTest::addRow("cmd41") << "100*1D20*2D6";
0343     QTest::addRow("cmd42") << "2D6 # two 6sided dice";
0344     QTest::addRow("cmd43") << "100/28*3";
0345     QTest::addRow("cmd44") << "100/8";
0346     QTest::addRow("cmd45") << "100*3*8";
0347     QTest::addRow("cmd46") << "help";
0348     QTest::addRow("cmd47") << "la";
0349     QTest::addRow("cmd48") << "10D10c[<2|>7]";
0350     QTest::addRow("cmd49") << "10D6c[=2|=4|=6]";
0351     QTest::addRow("cmd50") << "10D10e[=1|=10]k4";
0352     QTest::addRow("cmd51") << "1L[tete,bras droit,bras gauche,jambe droite,jambe "
0353                               "gauche,ventre[6..7],buste[8..10]]";
0354     QTest::addRow("cmd52") << "10+10s";
0355     QTest::addRow("cmd53") << "1d6e6;1d4e4mk1";
0356     QTest::addRow("cmd54") << "1d6e6;1d4e4mk1";
0357     QTest::addRow("cmd55") << "400D20/400000";
0358     QTest::addRow("cmd56") << "1d100e[>=95]i[<5]{-1d100e95}";
0359     QTest::addRow("cmd57") << "100*3*8";
0360     QTest::addRow("cmd58") << "1d100i[<70]{1d10i[=10]{1d100i[<70]{1d10e10}}}";
0361     QTest::addRow("cmd59") << "10d6c[<2|>5]";
0362     QTest::addRow("cmd60") << "5-5*5+5";
0363     QTest::addRow("cmd61") << "((3+4)*2)d6";
0364     QTest::addRow("cmd62") << "4d6i[=6]{+1d6}";
0365     QTest::addRow("cmd63") << "10d[-8..-1]";
0366     QTest::addRow("cmd64") << "4d6e6i[=4]{-4}+2";
0367     QTest::addRow("cmd65") << "4d6e6f[!=4]+2";
0368     QTest::addRow("cmd66") << "5d10g10";
0369     QTest::addRow("cmd67") << "4d6p[4:blue]c[>=4];1d6p[1:#FFFFFF]c6-@c1;1d6p[1:#"
0370                               "FF0000]c[>=4]+@c6-@c1";
0371     QTest::addRow("cmd68") << "10d[0..9]";
0372     QTest::addRow("cmd69") << "1d8e8;1d6e6mk1+2";
0373     QTest::addRow("cmd70") << "3d100g50";
0374     QTest::addRow("cmd71") << "3d100g33";
0375     QTest::addRow("cmd72") << "3d100g5";
0376     QTest::addRow("cmd73") << "3d100g40";
0377     QTest::addRow("cmd74") << "2d10k1+2d10k1+2d10k1";
0378     QTest::addRow("cmd75") << "2d10k1-2d10k1-2d10k1";
0379     QTest::addRow("cmd76") << "(2d10k1)-2d10k1-2d10k1";
0380     QTest::addRow("cmd77") << "2d10k1-(2d10k1)-2d10k1";
0381     QTest::addRow("cmd78") << "2d10k1-2d10k1-(2d10k1)";
0382     QTest::addRow("cmd79") << "1d6-2d6e6";
0383     QTest::addRow("cmd80") << "(1)-1d6e6";
0384     QTest::addRow("cmd81") << "(1)-(1d6e6)";
0385     QTest::addRow("cmd82") << "8d10o";
0386     QTest::addRow("cmd83") << "8d10o2,4";
0387     QTest::addRow("cmd84") << "8d10o2[>2]";
0388     QTest::addRow("cmd85") << "8d10ok2";
0389     QTest::addRow("cmd86") << "[100,200,300]k2";
0390     QTest::addRow("cmd87") << "100;200;300;[$1,$2,$3]k2";
0391     QTest::addRow("cmd88") << "1d20|3i:[>1]{\"Success\"}{\"Failure\"}";
0392     QTest::addRow("cmd89") << "1L[-3,-2,2,3]+10";
0393     QTest::addRow("cmd90") << "1L[-3,-2,2,3]+10;1L[-3,-2,2,3]";
0394     QTest::addRow("cmd91") << "1d20|3i:[>1]{\"Success\"}{\"Failure\"}";
0395     QTest::addRow("cmd92") << "4d10k3;4d10k3;4d10k3;[$1,$2,$3]s;\"Score @4\"";
0396     QTest::addRow("cmd93") << "4d10e(10)10";
0397 }
0398 
0399 void TestDice::rangedCommandsTest()
0400 {
0401     QFETCH(QString, cmd);
0402     QFETCH(int, min);
0403     QFETCH(int, max);
0404 
0405     bool a= m_diceParser->parseLine(cmd);
0406     QVERIFY2(a, "parsing");
0407 
0408     m_diceParser->start();
0409     auto results= m_diceParser->scalarResultsFromEachInstruction();
0410 
0411     QVERIFY(results.size() == 1);
0412 
0413     auto score= results.first();
0414 
0415     QVERIFY(score >= min);
0416     QVERIFY(score <= max);
0417 
0418     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
0419     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
0420 
0421     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
0422     QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning");
0423 }
0424 
0425 void TestDice::rangedCommandsTest_data()
0426 {
0427     QTest::addColumn<QString>("cmd");
0428     QTest::addColumn<int>("min");
0429     QTest::addColumn<int>("max");
0430 
0431     QTest::addRow("cmd1") << "1L[5,6,7,8]+10" << 15 << 18;
0432     QTest::addRow("cmd2") << "2L[5,6,7,8]+10" << 20 << 26;
0433 }
0434 
0435 void TestDice::wrongCommandsTest()
0436 {
0437     //            << "pajaejlbnmàw";
0438     QFETCH(QString, cmd);
0439     QFETCH(bool, valid);
0440     bool a= m_diceParser->parseLine(cmd);
0441     if(a)
0442     {
0443         m_diceParser->start();
0444         auto map= m_diceParser->errorMap();
0445         a= map.isEmpty();
0446     }
0447     QCOMPARE(a, valid);
0448 }
0449 
0450 void TestDice::wrongCommandsTest_data()
0451 {
0452     QTest::addColumn<QString>("cmd");
0453     QTest::addColumn<bool>("valid");
0454 
0455     QTest::newRow("test1") << "1L[cheminée,chocolat,épée,arc,chute de pierre" << false;
0456     QTest::newRow("test2") << "10d10c" << false;
0457     QTest::newRow("test3") << "10d10a" << false;
0458     QTest::newRow("test4") << "10d0a[>7]" << false;
0459     QTest::newRow("test5") << "aiteanetauearuteurn" << false;
0460     QTest::newRow("test6") << "meregue" << false;
0461     QTest::newRow("test7") << "p i follow rivers" << false;
0462     QTest::newRow("test8") << "manga violet evergarden" << false;
0463     QTest::newRow("test9") << "((1d8e8+2);(1d6e6+2))" << true;
0464 }
0465 
0466 void TestDice::wrongCommandsExecutionTimeTest()
0467 {
0468     QStringList commands;
0469 
0470     //<< "8D20+10*@c[=20]"
0471     commands << "1/0"
0472              << ""
0473              << "0d10"
0474              << "10d10k11"
0475              << "!!!!";
0476 
0477     for(QString cmd : commands)
0478     {
0479         bool test= m_diceParser->parseLine(cmd);
0480         m_diceParser->start();
0481 
0482         QVERIFY2(m_diceParser->errorMap().isEmpty() == false || !test, cmd.toStdString().c_str());
0483     }
0484 }
0485 void TestDice::scopeDF()
0486 {
0487     QFETCH(QString, cmd);
0488     QFETCH(int, min);
0489     QFETCH(int, max);
0490     QFETCH(bool, valid);
0491 
0492     bool test= m_diceParser->parseLine(cmd);
0493     QVERIFY2(test == valid, cmd.toStdString().c_str());
0494     m_diceParser->start();
0495     auto results= m_diceParser->scalarResultsFromEachInstruction();
0496 
0497     for(auto const& result : qAsConst(results))
0498         QVERIFY(result >= min && result <= max);
0499 }
0500 
0501 void TestDice::scopeDF_data()
0502 {
0503     QTest::addColumn<QString>("cmd");
0504     QTest::addColumn<int>("min");
0505     QTest::addColumn<int>("max");
0506     QTest::addColumn<bool>("valid");
0507 
0508     QTest::newRow("test1") << "1D[-1..1]" << -1 << 1 << true;
0509     QTest::newRow("test2") << "1D[-10..-5]" << -10 << -5 << true;
0510     QTest::newRow("test3") << "1D[-100..100]" << -100 << 100 << true;
0511     QTest::newRow("test4") << "1D[-1..0]" << -1 << 0 << true;
0512     QTest::newRow("test5") << "1D[10..20]" << 10 << 20 << true;
0513     QTest::newRow("test6") << "1D[30..100]" << 30 << 100 << true;
0514     QTest::newRow("test7") << "1D[0..99]" << 0 << 99 << true;
0515     QTest::newRow("test8") << "5-5*5+5" << -15 << -15 << true;
0516     QTest::newRow("test9") << "2d20c[<=13]+@c[<=3]" << 0 << 4 << true;
0517     QTest::newRow("test10") << "6d10c[>=6]-@c1" << -6 << 6 << true;
0518     QTest::newRow("test11") << "2d6k1+2d8k1+2d10k1" << 3 << 30 << true;
0519     QTest::newRow("test12") << "1D[-2..50]" << -2 << 50 << true;
0520 }
0521 void TestDice::testAlias()
0522 {
0523     m_parsingToolBox->insertAlias(new DiceAlias("!", "3d6c"), 0);
0524     m_parsingToolBox->insertAlias(new DiceAlias("g", "d10k"), 1);
0525     m_parsingToolBox->insertAlias(new DiceAlias("(.*)C(.*)", QStringLiteral("\\1d10e10c[>=\\2]"), QString(), false), 2);
0526 
0527     QFETCH(QString, cmd);
0528     QFETCH(QString, expected);
0529 
0530     auto result= m_parsingToolBox->convertAlias(cmd);
0531     QCOMPARE(result, expected);
0532 }
0533 
0534 void TestDice::testAlias_data()
0535 {
0536     QTest::addColumn<QString>("cmd");
0537     QTest::addColumn<QString>("expected");
0538 
0539     QTest::newRow("test1") << "!2"
0540                            << "3d6c2";
0541     QTest::newRow("test2") << "${rang}g4"
0542                            << "${rang}d10k4";
0543     QTest::newRow("test3") << "${rang}g4 # gerald"
0544                            << "${rang}d10k4 # gerald";
0545     QTest::newRow("test4") << "5C3"
0546                            << "5d10e10c[>=3]";
0547     QTest::newRow("test5") << "1d100i:[<101]{\"great!\"}{\"try again\"}"
0548                            << "1d100i:[<101]{\"great!\"}{\"try again\"}";
0549 }
0550 
0551 void TestDice::severalInstruction()
0552 {
0553     QStringList commands;
0554 
0555     commands << "1d10;2d20;$1+$2";
0556 
0557     QList<int> results;
0558     results << 3;
0559 
0560     int i= 0;
0561     for(auto const& cmd : qAsConst(commands))
0562     {
0563         auto test= m_diceParser->parseLine(cmd);
0564         QVERIFY2(test, cmd.toStdString().c_str());
0565         QVERIFY2(m_diceParser->startNodeCount() == results[i], "Wrong number of instruction");
0566     }
0567 }
0568 void TestDice::mathPriority()
0569 {
0570     QFETCH(QString, cmd);
0571     QFETCH(int, expected);
0572 
0573     bool test= m_diceParser->parseLine(cmd);
0574     QVERIFY(test);
0575     m_diceParser->start();
0576     auto resultList= m_diceParser->scalarResultsFromEachInstruction();
0577     QCOMPARE(resultList.size(), 1);
0578 
0579     auto value= resultList.first();
0580     QCOMPARE(value, expected);
0581 }
0582 
0583 void TestDice::mathPriority_data()
0584 {
0585     QTest::addColumn<QString>("cmd");
0586     QTest::addColumn<int>("expected");
0587 
0588     QTest::addRow("cmd1") << "10+2" << 12;
0589     QTest::addRow("cmd2") << "2-10" << -8;
0590     QTest::addRow("cmd3") << "5+2*3" << 11;
0591     QTest::addRow("cmd4") << "5-5*5+5" << -15;
0592     QTest::addRow("cmd5") << "5-5/5+5" << 9;
0593     QTest::addRow("cmd6") << "10*(3*2)" << 60;
0594     QTest::addRow("cmd7") << "60/(3*2)" << 10;
0595     QTest::addRow("cmd8") << "5-(5*5+5)" << -25;
0596 }
0597 
0598 void TestDice::dangerousCommandsTest()
0599 {
0600     QFETCH(QString, cmd);
0601 
0602     auto b= m_diceParser->parseLine(cmd);
0603     QVERIFY(b);
0604     m_diceParser->start();
0605 }
0606 void TestDice::dangerousCommandsTest_data()
0607 {
0608     QTest::addColumn<QString>("cmd");
0609 
0610     QTest::addRow("cmd1") << "10d6g10";
0611     QTest::addRow("cmd2") << "10d2g10";
0612     QTest::addRow("cmd3") << "10d10g10";
0613     // QTest::addRow("cmd4") << "10d10g10";
0614     // QTest::addRow("cmd5") << "10d10g10";
0615 }
0616 
0617 void TestDice::keepTest()
0618 {
0619     QFETCH(QVector<int>, values);
0620     QFETCH(int, keep);
0621     QFETCH(int, score);
0622     QFETCH(bool, error);
0623 
0624     TestNode node;
0625     KeepDiceExecNode keepN;
0626     NumberNode* numberNode= new NumberNode();
0627     numberNode->setNumber(keep);
0628     keepN.setDiceKeepNumber(numberNode);
0629 
0630     DiceResult result;
0631 
0632     makeResult(result, values);
0633 
0634     node.setResult(&result);
0635     node.setNextNode(&keepN);
0636 
0637     node.run(nullptr);
0638 
0639     bool isErrorEmpty= !keepN.getExecutionErrorMap().isEmpty();
0640 
0641     QCOMPARE(isErrorEmpty, error);
0642 
0643     if(error)
0644         return;
0645 
0646     auto resultScore= keepN.getResult()->getResult(Dice::RESULT_TYPE::SCALAR).toInt();
0647 
0648     QCOMPARE(score, resultScore);
0649 }
0650 
0651 void TestDice::keepTest_data()
0652 {
0653     QTest::addColumn<QVector<int>>("values");
0654     QTest::addColumn<int>("keep");
0655     QTest::addColumn<int>("score");
0656     QTest::addColumn<bool>("error");
0657 
0658     QTest::addRow("cmd1") << QVector<int>({10, 9, 2}) << 1 << 10 << false;
0659     QTest::addRow("cmd2") << QVector<int>({10, 9, 2}) << 2 << 19 << false;
0660     QTest::addRow("cmd3") << QVector<int>({10, 9, 2}) << 3 << 21 << false;
0661     QTest::addRow("cmd4") << QVector<int>({10, 9, 2}) << 4 << 0 << true;
0662 }
0663 
0664 void TestDice::sortTest()
0665 {
0666     QFETCH(QVector<int>, values);
0667     QFETCH(bool, ascending);
0668     QFETCH(QVector<int>, scores);
0669 
0670     TestNode node;
0671     SortResultNode sortN;
0672     sortN.setSortAscending(ascending);
0673 
0674     DiceResult result;
0675 
0676     makeResult(result, values);
0677 
0678     node.setResult(&result);
0679     node.setNextNode(&sortN);
0680 
0681     DiceResult expectedScore;
0682     makeResult(expectedScore, scores);
0683 
0684     node.run(nullptr);
0685 
0686     auto list= dynamic_cast<DiceResult*>(sortN.getResult())->getResultList();
0687 
0688     int i= 0;
0689     auto expected= expectedScore.getResultList();
0690     for(auto sortedDie : list)
0691     {
0692         QCOMPARE(expected[i]->getValue(), sortedDie->getValue());
0693         ++i;
0694     }
0695 }
0696 
0697 void TestDice::sortTest_data()
0698 {
0699     QTest::addColumn<QVector<int>>("values");
0700     QTest::addColumn<bool>("ascending");
0701     QTest::addColumn<QVector<int>>("scores");
0702 
0703     QTest::addRow("cmd1") << QVector<int>({10, 9, 2}) << true << QVector<int>({2, 9, 10});
0704     QTest::addRow("cmd2") << QVector<int>({1, 2, 3}) << false << QVector<int>({3, 2, 1});
0705     QTest::addRow("cmd3") << QVector<int>({10, 9, 2}) << false << QVector<int>({10, 9, 2});
0706     QTest::addRow("cmd4") << QVector<int>({2, 9, 10}) << true << QVector<int>({2, 9, 10});
0707     QTest::addRow("cmd5") << QVector<int>({1, 25, 10}) << false << QVector<int>({25, 10, 1});
0708     QTest::addRow("cmd6") << QVector<int>({10, 2, 100}) << false << QVector<int>({100, 10, 2});
0709 }
0710 
0711 void TestDice::countTest()
0712 {
0713     QFETCH(QVector<int>, values);
0714     QFETCH(QVector<int>, condition);
0715     QFETCH(int, score);
0716     QFETCH(QVector<int>, subvalues);
0717     QFETCH(int, boolOp);
0718 
0719     TestNode node;
0720     CountExecuteNode countN;
0721 
0722     QVector<Dice::LogicOperation> vector;
0723 
0724     bool first= true;
0725     for(const auto& i : condition)
0726     {
0727         Q_UNUSED(i)
0728         if(!first)
0729         {
0730             first= !first;
0731             continue;
0732         }
0733 
0734         vector.push_back(Dice::LogicOperation::OR);
0735     }
0736 
0737     auto validator= makeValidator(condition, static_cast<Dice::CompareOperator>(boolOp), vector);
0738 
0739     countN.setValidatorList(validator);
0740     DiceResult result;
0741     node.setResult(&result);
0742     node.setNextNode(&countN);
0743 
0744     makeResult(result, values, subvalues);
0745 
0746     node.run(nullptr);
0747 
0748     QCOMPARE(score, countN.getResult()->getResult(Dice::RESULT_TYPE::SCALAR).toInt());
0749 
0750     countN.setValidatorList(nullptr);
0751 }
0752 
0753 void TestDice::countTest_data()
0754 {
0755     QTest::addColumn<QVector<int>>("values");
0756     QTest::addColumn<QVector<int>>("condition");
0757     QTest::addColumn<int>("score");
0758     QTest::addColumn<QVector<int>>("subvalues");
0759     QTest::addColumn<int>("boolOp");
0760 
0761     // clang-format off
0762     QTest::addRow("cmd1") << QVector<int>({10, 9, 2}) << QVector<int>({3}) << 2 << QVector<int>() << static_cast<int>(Dice::CompareOperator::GreaterThan);
0763     QTest::addRow("cmd2") << QVector<int>({1, 2, 3})  << QVector<int>({3}) << 0 << QVector<int>() << static_cast<int>(Dice::CompareOperator::GreaterThan);
0764     QTest::addRow("cmd3") << QVector<int>({10, 7, 4}) << QVector<int>({7}) << 3 << QVector<int>({10, 10, 2}) << static_cast<int>(Dice::CompareOperator::GreaterThan);
0765     QTest::addRow("cmd4") << QVector<int>({1, 1, 6}) << QVector<int>({1,6}) << 3 << QVector<int>() << static_cast<int>(Dice::CompareOperator::Equal);
0766     // clang-format on
0767 }
0768 
0769 void TestDice::rerollTest()
0770 {
0771     QFETCH(QVector<int>, values);
0772     QFETCH(int, condition);
0773     QFETCH(bool, different);
0774 
0775     TestNode node;
0776     RerollDiceNode reroll(true, false);
0777 
0778     DiceResult result;
0779     makeResult(result, values);
0780     node.setResult(&result);
0781 
0782     auto validator= makeValidator(QVector<int>() << condition, Dice::CompareOperator::GreaterThan);
0783     reroll.setValidatorList(validator);
0784     node.setNextNode(&reroll);
0785 
0786     node.run(nullptr);
0787 
0788     auto list= dynamic_cast<DiceResult*>(reroll.getResult())->getResultList();
0789 
0790     int i= 0;
0791     auto expected= result.getResultList();
0792     bool resultDiff= false;
0793     for(auto rerolled : list)
0794     {
0795         if(!resultDiff && rerolled->getValue() != expected[i]->getValue())
0796             resultDiff= true;
0797         ++i;
0798     }
0799 
0800     QCOMPARE(different, resultDiff);
0801 }
0802 
0803 void TestDice::rerollTest_data()
0804 {
0805     QTest::addColumn<QVector<int>>("values");
0806     QTest::addColumn<int>("condition");
0807     QTest::addColumn<bool>("different");
0808 
0809     QTest::addRow("cmd1") << QVector<int>({8, 9, 2}) << 10 << false;
0810     QTest::addRow("cmd2") << QVector<int>({0, 0, 0}) << -1 << true;
0811 }
0812 
0813 void TestDice::explodeTest()
0814 {
0815     QFETCH(QVector<int>, values);
0816     QFETCH(int, condition);
0817     QFETCH(bool, different);
0818 
0819     TestNode node;
0820     ExplodeDiceNode explode;
0821 
0822     DiceResult result;
0823     makeResult(result, values);
0824     node.setResult(&result);
0825 
0826     auto validator= makeValidator(QVector<int>() << condition, Dice::CompareOperator::Equal);
0827     explode.setValidatorList(validator);
0828     node.setNextNode(&explode);
0829 
0830     node.run(nullptr);
0831 
0832     auto list= dynamic_cast<DiceResult*>(explode.getResult())->getResultList();
0833 
0834     int i= 0;
0835     auto expected= result.getResultList();
0836     bool resultDiff= false;
0837     for(auto rerolled : list)
0838     {
0839         if(!resultDiff && rerolled->getValue() != expected[i]->getValue())
0840             resultDiff= true;
0841         ++i;
0842     }
0843 
0844     QCOMPARE(different, resultDiff);
0845 }
0846 
0847 void TestDice::explodeTest_data()
0848 {
0849     QTest::addColumn<QVector<int>>("values");
0850     QTest::addColumn<int>("condition");
0851     QTest::addColumn<bool>("different");
0852 
0853     QTest::addRow("cmd1") << QVector<int>({8, 9, 2}) << 10 << false;
0854     QTest::addRow("cmd2") << QVector<int>({0, 0, 0}) << 0 << true;
0855 }
0856 
0857 void TestDice::rerollUntilTest()
0858 {
0859     QFETCH(QVector<int>, values);
0860     QFETCH(int, condition);
0861     QFETCH(bool, different);
0862 
0863     TestNode node;
0864     RerollDiceNode reroll(false, false);
0865 
0866     DiceResult result;
0867     makeResult(result, values, QVector<int>(), 0);
0868     node.setResult(&result);
0869 
0870     auto validator= makeValidator(QVector<int>() << condition, Dice::CompareOperator::Equal);
0871     reroll.setValidatorList(validator);
0872     node.setNextNode(&reroll);
0873 
0874     node.run(nullptr);
0875 
0876     auto list= dynamic_cast<DiceResult*>(reroll.getResult())->getResultList();
0877 
0878     int i= 0;
0879     auto expected= result.getResultList();
0880     bool resultDiff= false;
0881     for(auto rerolled : list)
0882     {
0883         if(!resultDiff && rerolled->getValue() != expected[i]->getValue())
0884             resultDiff= true;
0885         ++i;
0886     }
0887     QCOMPARE(different, resultDiff);
0888 }
0889 void TestDice::rerollUntilTest_data()
0890 {
0891     QTest::addColumn<QVector<int>>("values");
0892     QTest::addColumn<int>("condition");
0893     QTest::addColumn<bool>("different");
0894 
0895     QTest::addRow("cmd1") << QVector<int>({8, 9, 2}) << 10 << false;
0896     QTest::addRow("cmd2") << QVector<int>({0, 0, 0}) << 0 << true;
0897 }
0898 
0899 void TestDice::rerollAddTest()
0900 {
0901     QFETCH(QVector<int>, values);
0902     QFETCH(int, condition);
0903     QFETCH(bool, different);
0904 
0905     TestNode node;
0906     RerollDiceNode reroll(true, true);
0907 
0908     DiceResult result;
0909     makeResult(result, values);
0910     node.setResult(&result);
0911 
0912     auto validator= makeValidator(QVector<int>() << condition, Dice::CompareOperator::Equal);
0913     reroll.setValidatorList(validator);
0914     node.setNextNode(&reroll);
0915 
0916     node.run(nullptr);
0917 
0918     auto list= dynamic_cast<DiceResult*>(reroll.getResult())->getResultList();
0919 
0920     int i= 0;
0921     auto expected= result.getResultList();
0922     bool resultDiff= false;
0923     for(auto rerolled : list)
0924     {
0925         if(!resultDiff && rerolled->getValue() != expected[i]->getValue())
0926             resultDiff= true;
0927         ++i;
0928     }
0929 
0930     QCOMPARE(different, resultDiff);
0931 }
0932 void TestDice::rerollAddTest_data()
0933 {
0934     QTest::addColumn<QVector<int>>("values");
0935     QTest::addColumn<int>("condition");
0936     QTest::addColumn<bool>("different");
0937 
0938     QTest::addRow("cmd1") << QVector<int>({8, 9, 2}) << 10 << false;
0939     QTest::addRow("cmd2") << QVector<int>({0, 0, 0}) << 0 << true;
0940 }
0941 
0942 void TestDice::mergeTest() {}
0943 void TestDice::mergeTest_data() {}
0944 
0945 void TestDice::ifTest()
0946 {
0947     QFETCH(QVector<int>, values);
0948     QFETCH(int, condition);
0949     QFETCH(int, valCondition);
0950     QFETCH(QString, expectedResult);
0951 
0952     Dice::ConditionType conditionType= static_cast<Dice::ConditionType>(condition);
0953 
0954     TestNode node;
0955     IfNode ifNode;
0956     ifNode.setConditionType(conditionType);
0957 
0958     DiceResult result;
0959     makeResult(result, values);
0960     node.setResult(&result);
0961 
0962     StringNode trueNode;
0963     trueNode.setString(QStringLiteral("True"));
0964     StringNode falseNode;
0965     falseNode.setString(QStringLiteral("False"));
0966 
0967     ifNode.setInstructionTrue(&trueNode);
0968     ifNode.setInstructionFalse(&falseNode);
0969 
0970     auto validator= makeValidator(QVector<int>() << valCondition, Dice::CompareOperator::Equal);
0971     ifNode.setValidatorList(validator);
0972     node.setNextNode(&ifNode);
0973 
0974     node.run(nullptr);
0975 
0976     auto text= dynamic_cast<StringResult*>(ifNode.getNextNode()->getResult())->getText();
0977 
0978     QCOMPARE(expectedResult, text);
0979 
0980     ifNode.setNextNode(nullptr);
0981 }
0982 void TestDice::ifTest_data()
0983 {
0984     QTest::addColumn<QVector<int>>("values");
0985     QTest::addColumn<int>("condition");
0986     QTest::addColumn<int>("valCondition");
0987     QTest::addColumn<QString>("expectedResult");
0988 
0989     int onEach= 0;
0990     int onEachValue= 1;
0991     int oneOfThem= 2;
0992     int allOfThem= 3;
0993     int onScalar= 4;
0994 
0995     QTest::addRow("cmd1") << QVector<int>({8, 9, 2}) << onEach << 0 << "False";
0996     QTest::addRow("cmd2") << QVector<int>({2, 2, 2}) << onEach << 2 << "True";
0997 
0998     QTest::addRow("cmd3") << QVector<int>({0, 0, 0}) << oneOfThem << 10 << "False";
0999     QTest::addRow("cmd4") << QVector<int>({10, 9, 5}) << oneOfThem << 10 << "True";
1000     QTest::addRow("cmd5") << QVector<int>({9, 9, 9}) << oneOfThem << 9 << "True";
1001 
1002     QTest::addRow("cmd6") << QVector<int>({8, 9, 2}) << allOfThem << 1 << "False";
1003     QTest::addRow("cmd7") << QVector<int>({8, 9, 2}) << allOfThem << 9 << "False";
1004     QTest::addRow("cmd8") << QVector<int>({8, 8, 8}) << allOfThem << 8 << "True";
1005 
1006     QTest::addRow("cmd9") << QVector<int>({25, 8, 14}) << onScalar << 1 << "False";
1007     QTest::addRow("cmd10") << QVector<int>({25, 8, 14}) << onScalar << 47 << "True";
1008 
1009     // QTest::addRow("cmd11") << QVector<int>({25, 8, 14}) << onEachValue << 47 <<
1010     // "True";
1011 }
1012 
1013 void TestDice::paintTest() {}
1014 void TestDice::paintTest_data() {}
1015 
1016 void TestDice::filterTest()
1017 {
1018     QFETCH(QString, cmd);
1019     QFETCH(int, result);
1020 
1021     auto parsing= m_diceParser->parseLine(cmd);
1022     QVERIFY2(parsing, "parsing");
1023 
1024     m_diceParser->start();
1025     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
1026     QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning");
1027 
1028     auto resultCmd= m_diceParser->scalarResultsFromEachInstruction();
1029 
1030     QCOMPARE(resultCmd.size(), 1);
1031 
1032     QCOMPARE(resultCmd.first(), result);
1033 }
1034 
1035 void TestDice::filterTest_data()
1036 {
1037     QTest::addColumn<QString>("cmd");
1038     QTest::addColumn<int>("result");
1039 
1040     QTest::addRow("cmd1") << "[8, 4, 2]f4" << 4;
1041     QTest::addRow("cmd2") << "[0, 0, 0]f1" << 0;
1042     QTest::addRow("cmd3") << "[1, 2, 3]f[.>2&:>5]" << 6;
1043     QTest::addRow("cmd4") << "[1, 2, 6]f[.<2&>5]" << 6;
1044     QTest::addRow("cmd5") << "[2, 2, 6]f[.<2&>5]" << 0;
1045     QTest::addRow("cmd5") << "[1, 5, 1]f[.<2&>5]" << 0;
1046 }
1047 
1048 void TestDice::uniqueTest()
1049 {
1050     QFETCH(QVector<int>, values);
1051     QFETCH(QVector<int>, expected);
1052 
1053     TestNode node;
1054     UniqueNode unique;
1055 
1056     DiceResult result;
1057     makeResult(result, values);
1058     node.setResult(&result);
1059 
1060     node.setNextNode(&unique);
1061     node.run(nullptr);
1062 
1063     auto list= dynamic_cast<DiceResult*>(unique.getResult())->getResultList();
1064     QVector<int> resultVal;
1065 
1066     std::transform(list.begin(), list.end(), std::back_inserter(resultVal), [](Die* die) { return die->getValue(); });
1067 
1068     QVERIFY(resultVal == expected);
1069 }
1070 
1071 void TestDice::uniqueTest_data()
1072 {
1073     QTest::addColumn<QVector<int>>("values");
1074     QTest::addColumn<QVector<int>>("expected");
1075 
1076     QTest::addRow("cmd1") << QVector<int>({8, 4, 2, 8}) << QVector<int>({8, 4, 2});
1077     QTest::addRow("cmd2") << QVector<int>({8, 4, 2}) << QVector<int>({8, 4, 2});
1078 }
1079 
1080 void TestDice::spreadTest()
1081 {
1082     QFETCH(QVector<int>, values);
1083 
1084     TestNode node;
1085     SplitNode split;
1086 
1087     DiceResult result;
1088     makeResultExplode(result, values);
1089     node.setResult(&result);
1090 
1091     node.setNextNode(&split);
1092 
1093     node.run(nullptr);
1094 
1095     auto list= dynamic_cast<DiceResult*>(split.getResult())->getResultList();
1096 
1097     auto expected= result.getResultList();
1098     QVERIFY(list.size() == values.size());
1099 }
1100 
1101 void TestDice::spreadTest_data()
1102 {
1103     QTest::addColumn<QVector<int>>("values");
1104 
1105     QTest::addRow("cmd1") << QVector<int>({8, 4, 2});
1106 }
1107 
1108 void TestDice::groupTest() {}
1109 void TestDice::groupTest_data() {}
1110 
1111 void TestDice::bindTest() {}
1112 void TestDice::bindTest_data() {}
1113 
1114 void TestDice::occurenceTest()
1115 {
1116     QFETCH(QVector<int>, values);
1117     QFETCH(int, condition);
1118     QFETCH(QString, expected);
1119 
1120     TestNode node;
1121     OccurenceCountNode count;
1122 
1123     DiceResult result;
1124     makeResult(result, values);
1125     node.setResult(&result);
1126 
1127     auto validator= makeValidator(QVector<int>() << condition, Dice::CompareOperator::GreaterThan);
1128     count.setValidatorList(validator);
1129     node.setNextNode(&count);
1130 
1131     node.run(nullptr);
1132 
1133     auto text= dynamic_cast<StringResult*>(count.getResult())->getText();
1134 
1135     QVERIFY(text.startsWith(expected));
1136 }
1137 void TestDice::occurenceTest_data()
1138 {
1139     QTest::addColumn<QVector<int>>("values");
1140     QTest::addColumn<int>("condition");
1141     QTest::addColumn<QString>("expected");
1142 
1143     QTest::addRow("cmd1") << QVector<int>({8, 8, 2}) << 7 << "2x8";
1144     QTest::addRow("cmd2") << QVector<int>({0, 0, 0}) << 1 << "No matching result";
1145 }
1146 
1147 void TestDice::ifCommandTest()
1148 {
1149     QFETCH(QString, cmd);
1150     QFETCH(Dice::CompareOperator, compare);
1151     QFETCH(QList<int>, level);
1152     QFETCH(QStringList, startExperted);
1153 
1154     bool test= m_diceParser->parseLine(cmd);
1155     QVERIFY2(test, cmd.toStdString().c_str());
1156     m_diceParser->start();
1157     auto results= m_diceParser->scalarResultsFromEachInstruction();
1158     auto strResult= m_diceParser->finalStringResult([](const QString& result, const QString&, bool) { return result; });
1159 
1160     QCOMPARE(results.size(), 1);
1161 
1162     auto result= results.first();
1163     auto it= std::find_if(level.begin(), level.end(), [compare, result](int level) {
1164         if(compare == Dice::CompareOperator::GreaterOrEqual)
1165             return result >= level;
1166         else if(compare == Dice::CompareOperator::GreaterThan)
1167             return result > level;
1168         else if(compare == Dice::CompareOperator::LesserThan)
1169             return result < level;
1170         else if(compare == Dice::CompareOperator::LesserOrEqual)
1171             return result <= level;
1172         else if(compare == Dice::CompareOperator::Equal)
1173             return qFuzzyCompare(result, level);
1174         else // if(compare == BooleanCondition::Different)
1175             return !qFuzzyCompare(result, level);
1176     });
1177 
1178     auto index= std::distance(level.begin(), it);
1179 
1180     auto strResultExpected= startExperted[index];
1181     auto resultText= strResult;
1182 
1183     QVERIFY2(resultText.startsWith(strResultExpected), "string result does not fit the expectation");
1184 }
1185 
1186 void TestDice::ifCommandTest_data()
1187 {
1188     QTest::addColumn<QString>("cmd");
1189     QTest::addColumn<Dice::CompareOperator>("compare");
1190     QTest::addColumn<QList<int>>("level");
1191     QTest::addColumn<QStringList>("startExperted");
1192 
1193     QTest::addRow("cmd1") << "2d10i:[>=15]{\"Complete Success: %1 "
1194                              "[%2]\"}{i:[>=10]{\"Success with Complications: %1 "
1195                              "[%2]\"}{\"Failure: %1 [%2]\"}}"
1196                           << Dice::CompareOperator::GreaterOrEqual << QList<int>({15, 10, 1})
1197                           << QStringList({"Complete Success:", "Success with Complications:", "Failure:"});
1198     QTest::addRow("cmd2") << "2d10;$1i:[>=15]{\"Complete Success: %1 [%2]\"}{$1i:[>=10]{\"Success "
1199                              "with Complications: %1 "
1200                              "[%2]\"}{\"Failure: %1 [%2]\"}}"
1201                           << Dice::CompareOperator::GreaterOrEqual << QList<int>({15, 10, 1})
1202                           << QStringList({"Complete Success:", "Success with Complications:", "Failure:"});
1203 }
1204 
1205 void TestDice::operatoionConditionValidatorTest()
1206 {
1207     OperationCondition validator;
1208     NumberNode number;
1209     number.setNumber(2);
1210     validator.setValueNode(&number);
1211 
1212     BooleanCondition subValidator;
1213     subValidator.setOperator(Dice::CompareOperator::Equal);
1214     NumberNode subnumber;
1215     subnumber.setNumber(0);
1216     subValidator.setValueNode(&subnumber);
1217 
1218     validator.setBoolean(&subValidator);
1219 
1220     std::set<qint64> data= {2, 4, 6, 8, 10};
1221     auto value= validator.getPossibleValues(std::make_pair<qint64, qint64>(1, 10));
1222 
1223     subValidator.setValueNode(nullptr);
1224     validator.setValueNode(nullptr);
1225     validator.setBoolean(nullptr);
1226 
1227     QCOMPARE(value, data);
1228 }
1229 
1230 void TestDice::switchCaseTest()
1231 {
1232     QFETCH(int, value);
1233     QFETCH(QList<Dice::CompareOperator>, operatorList);
1234     QFETCH(QList<int>, threshold);
1235     QFETCH(QStringList, values);
1236     QFETCH(QString, expected);
1237     QFETCH(bool, stopatfirt);
1238 
1239     NumberNode* valNode= new NumberNode();
1240     ValuesListNode* node1= new ValuesListNode();
1241     valNode->setNumber(value);
1242     node1->insertValue(valNode);
1243 
1244     SwitchCaseNode* node2= new SwitchCaseNode();
1245     node2->setStopAtFirt(stopatfirt);
1246 
1247     int i= 0;
1248     for(const auto& val : values)
1249     {
1250         ValidatorList* validatorList= nullptr;
1251         if(i < threshold.size())
1252         {
1253             validatorList= makeValidator(QVector<int>{threshold[i]}, operatorList[i]);
1254         }
1255         auto stringNode= new StringNode();
1256         stringNode->setString(val);
1257         node2->insertCase(stringNode, validatorList);
1258         ++i;
1259     }
1260 
1261     node1->setNextNode(node2);
1262 
1263     node1->run(nullptr);
1264 
1265     auto result= node2->getResult();
1266     auto stringResult= result->getStringResult();
1267 
1268     QCOMPARE(stringResult, expected);
1269 }
1270 
1271 void TestDice::switchCaseTest_data()
1272 {
1273     using BC= Dice::CompareOperator;
1274     QTest::addColumn<int>("value");
1275     QTest::addColumn<QList<Dice::CompareOperator>>("operatorList");
1276     QTest::addColumn<QList<int>>("threshold");
1277     QTest::addColumn<QStringList>("values");
1278     QTest::addColumn<QString>("expected");
1279     QTest::addColumn<bool>("stopatfirt");
1280 
1281     QTest::addRow("cmd1") << 75 << QList<BC>{BC::Equal, BC::Equal} << QList<int>{75, 1} << QStringList{"a", "b"}
1282                           << QStringLiteral("a") << false;
1283 
1284     QTest::addRow("cmd2") << 1 << QList<BC>{BC::Equal, BC::Equal} << QList<int>{75, 1} << QStringList{"a", "b"}
1285                           << QStringLiteral("b") << true;
1286 
1287     QTest::addRow("cmd3") << 7
1288                           << QList<BC>{BC::GreaterThan, BC::GreaterThan, BC::GreaterThan, BC::GreaterThan,
1289                                        BC::GreaterThan}
1290                           << QList<int>{8, 29, 99, 54, 1} << QStringList{"a", "b", "c", "d", "e"} << QStringLiteral("e")
1291                           << false;
1292 
1293     QTest::addRow("cmd4") << 75 << QList<BC>{BC::LesserThan, BC::LesserThan, BC::LesserThan} << QList<int>{8, 7}
1294                           << QStringList{"a", "b", "c"} << QStringLiteral("c") << false;
1295 
1296     QTest::addRow("cmd5") << 2 << QList<BC>{BC::Different, BC::Different} << QList<int>{1, 2} << QStringList{"a", "b"}
1297                           << QStringLiteral("a") << false;
1298 
1299     QTest::addRow("cmd6") << 3
1300                           << QList<BC>{BC::GreaterOrEqual, BC::GreaterOrEqual, BC::GreaterOrEqual, BC::GreaterOrEqual}
1301                           << QList<int>{1, 2, 3, 4} << QStringList{"a", "b", "c", "d"} << QStringLiteral("a,b,c")
1302                           << false;
1303 
1304     QTest::addRow("cmd7") << 3 << QList<BC>{BC::LesserOrEqual, BC::LesserOrEqual, BC::LesserOrEqual, BC::LesserOrEqual}
1305                           << QList<int>{1, 2, 3, 4} << QStringList{"a", "b", "c", "d"} << QStringLiteral("c") << true;
1306 }
1307 
1308 void TestDice::deterministTest()
1309 {
1310     QFETCH(QString, command);
1311     QFETCH(QList<qreal>, results);
1312 
1313     auto parsing= m_diceParser->parseLine(command);
1314     QVERIFY2(parsing, "parsing");
1315     m_diceParser->start();
1316     QVERIFY2(m_diceParser->humanReadableError().isEmpty(), "no error");
1317     QVERIFY2(m_diceParser->humanReadableWarning().isEmpty(), "no warning");
1318 
1319     auto resultCmd= m_diceParser->scalarResultsFromEachInstruction();
1320     QCOMPARE(results, resultCmd);
1321 }
1322 
1323 void TestDice::deterministTest_data()
1324 {
1325     QTest::addColumn<QString>("command");
1326     QTest::addColumn<QList<qreal>>("results");
1327 
1328     QTest::addRow("cmd1") << "10;20;10+20;5-3;[$1,$2,$3]k$4" << QList<qreal>{10, 20, 30, 2, 50};
1329     QTest::addRow("cmd2") << "6;[10,7,8,4,4,3,2,2,1]k$1" << QList<qreal>{6, 36};
1330 
1331     // 1d6;10d10e10k\$1
1332 }
1333 
1334 void TestDice::cleanupTestCase() {}
1335 
1336 QTEST_MAIN(TestDice)
1337 
1338 #include "tst_dice.moc"