File indexing completed on 2024-05-19 03:50:38

0001 #include "ExpressionParserTest.h"
0002 #include "backend/gsl/ExpressionParser.h"
0003 #include "backend/gsl/functions.h"
0004 
0005 namespace {
0006 func_t1 getFunction1(const QString& s) {
0007     const QString functionName(s);
0008     for (int i = 0; i < _number_functions; i++) {
0009         if (functionName == QLatin1String(_functions[i].name)) {
0010             if (_functions[i].argc == 1)
0011                 return std::get<func_t1>(_functions[i].fnct);
0012         }
0013     }
0014     return nullptr;
0015 }
0016 
0017 func_t2 getFunction2(const QString& s) {
0018     const QString functionName(s);
0019     for (int i = 0; i < _number_functions; i++) {
0020         if (functionName == QLatin1String(_functions[i].name)) {
0021             if (_functions[i].argc == 2)
0022                 return std::get<func_t2>(_functions[i].fnct);
0023         }
0024     }
0025     return nullptr;
0026 }
0027 
0028 func_t3 getFunction3(const QString& s) {
0029     const QString functionName(s);
0030     for (int i = 0; i < _number_functions; i++) {
0031         if (functionName == QLatin1String(_functions[i].name)) {
0032             if (_functions[i].argc == 3)
0033                 return std::get<func_t3>(_functions[i].fnct);
0034         }
0035     }
0036     return nullptr;
0037 }
0038 } // anonymous namespace
0039 
0040 void ExpressionParserTest::testIsValid() {
0041     const QString expr = QStringLiteral("cell(5; x)");
0042     const QStringList vars = {QStringLiteral("x")};
0043 
0044     QCOMPARE(ExpressionParser::isValid(expr, vars), true); // should not crash
0045 }
0046 
0047 void ExpressionParserTest::testIsValidStdev() {
0048     const QString expr = QStringLiteral("stdev(x)");
0049     const QStringList vars = {QStringLiteral("x")};
0050 
0051     QCOMPARE(ExpressionParser::isValid(expr, vars), true);
0052 }
0053 
0054 void ExpressionParserTest::testFunctionArguments1() {
0055     const QString functionName(QStringLiteral("rand"));
0056     for (int i = 0; i < _number_functions; i++) {
0057         if (functionName == QLatin1String(_functions[i].name))
0058             QVERIFY(_functions[i].parameterFunction == nullptr);
0059     }
0060 
0061     QCOMPARE(ExpressionParser::parameters(functionName), QStringLiteral(""));
0062 }
0063 
0064 void ExpressionParserTest::testFunctionArguments2() {
0065     const QString functionName(QStringLiteral("if"));
0066     for (int i = 0; i < _number_functions; i++) {
0067         if (functionName == QLatin1String(_functions[i].name))
0068             QVERIFY(_functions[i].parameterFunction != nullptr);
0069     }
0070 
0071     QCOMPARE(ExpressionParser::parameters(functionName), QStringLiteral("(condition; trueValue; falseValue)"));
0072 }
0073 
0074 void ExpressionParserTest::testUniques() {
0075     QSet<QString> names;
0076     for (int i = 0; i < _number_functions; i++) {
0077         const QString name = QLatin1String(_functions[i].name);
0078         // Dawson is in two groups available with the same function access
0079         QVERIFY2(!names.contains(name) || name == QStringLiteral("dawson"), qPrintable(name));
0080         names.insert(name);
0081     }
0082 }
0083 
0084 void ExpressionParserTest::testgreaterThan() {
0085     auto fnct = getFunction2(QStringLiteral("greaterThan"));
0086     QVERIFY(fnct);
0087 
0088     QCOMPARE(fnct(1, 5), 0);
0089     QCOMPARE(fnct(4.99, 5), 0);
0090     QCOMPARE(fnct(5, 5), 0);
0091     QCOMPARE(fnct(5.000001, 5), 1);
0092     QCOMPARE(fnct(10, 5), 1);
0093     QCOMPARE(fnct(0, -0), 0);
0094 }
0095 void ExpressionParserTest::testgreaterEqualThan() {
0096     auto fnct = getFunction2(QStringLiteral("greaterEqualThan"));
0097     QVERIFY(fnct);
0098 
0099     QCOMPARE(fnct(1, 5), 0);
0100     QCOMPARE(fnct(4.99, 5), 0);
0101     QCOMPARE(fnct(5, 5), 1);
0102     QCOMPARE(fnct(5.000001, 5), 1);
0103     QCOMPARE(fnct(10, 5), 1);
0104     QCOMPARE(fnct(0, -0), 1);
0105 }
0106 void ExpressionParserTest::testlessThan() {
0107     auto fnct = getFunction2(QStringLiteral("lessThan"));
0108     QVERIFY(fnct);
0109 
0110     QCOMPARE(fnct(1, 5), 1);
0111     QCOMPARE(fnct(4.99, 5), 1);
0112     QCOMPARE(fnct(5, 5), 0);
0113     QCOMPARE(fnct(5.000001, 0), 0);
0114     QCOMPARE(fnct(10, 5), 0);
0115     QCOMPARE(fnct(0, -0), 0);
0116 }
0117 void ExpressionParserTest::testlessEqualThan() {
0118     auto fnct = getFunction2(QStringLiteral("lessEqualThan"));
0119     QVERIFY(fnct);
0120 
0121     QCOMPARE(fnct(1, 5), 1);
0122     QCOMPARE(fnct(4.99, 5), 1);
0123     QCOMPARE(fnct(5, 5), 1);
0124     QCOMPARE(fnct(5.000001, 0), 0);
0125     QCOMPARE(fnct(10, 5), 0);
0126     QCOMPARE(fnct(0, -0), 1);
0127 }
0128 void ExpressionParserTest::testequal() {
0129     auto fnct = getFunction2(QStringLiteral("equal"));
0130     QVERIFY(fnct);
0131 
0132     QCOMPARE(fnct(1, 5), 0);
0133     QCOMPARE(fnct(4.99, 5), 0);
0134     QCOMPARE(fnct(5, 5), 1);
0135     QCOMPARE(fnct(5.000001, 0), 0);
0136     QCOMPARE(fnct(10, 5), 0);
0137     QCOMPARE(fnct(0, -0), 1);
0138 }
0139 
0140 void ExpressionParserTest::testifCondition() {
0141     auto fnct = getFunction3(QStringLiteral("if"));
0142     QVERIFY(fnct);
0143 
0144     QCOMPARE(fnct(1, 1, 5), 1);
0145     QCOMPARE(fnct(0, 1, 5), 5);
0146 
0147     QCOMPARE(fnct(1.1, 1, 5), 1);
0148     QCOMPARE(fnct(-1, 1, 5), 1);
0149 }
0150 void ExpressionParserTest::testandFunction() {
0151     auto fnct = getFunction2(QStringLiteral("and"));
0152     QVERIFY(fnct);
0153 
0154     QCOMPARE(fnct(1, 1), 1);
0155     QCOMPARE(fnct(0, 1), 0);
0156     QCOMPARE(fnct(1, 0), 0);
0157     QCOMPARE(fnct(0, 0), 0);
0158     QCOMPARE(fnct(2, 5), 1);
0159 }
0160 void ExpressionParserTest::testorFunction() {
0161     auto fnct = getFunction2(QStringLiteral("or"));
0162     QVERIFY(fnct);
0163 
0164     QCOMPARE(fnct(1, 1), 1);
0165     QCOMPARE(fnct(0, 1), 1);
0166     QCOMPARE(fnct(1, 0), 1);
0167     QCOMPARE(fnct(0, 0), 0);
0168     QCOMPARE(fnct(2, 5), 1);
0169     QCOMPARE(fnct(0, 2.3345), 1);
0170 }
0171 void ExpressionParserTest::testxorFunction() {
0172     auto fnct = getFunction2(QStringLiteral("xor"));
0173     QVERIFY(fnct);
0174 
0175     QCOMPARE(fnct(1, 1), 0);
0176     QCOMPARE(fnct(0, 1), 1);
0177     QCOMPARE(fnct(1, 0), 1);
0178     QCOMPARE(fnct(0, 0), 0);
0179     QCOMPARE(fnct(2, 5), 0);
0180     QCOMPARE(fnct(0, 2.3345), 1);
0181     QCOMPARE(fnct(2.3345, 2.3345), 0);
0182     QCOMPARE(fnct(2.3345, 0), 1);
0183 }
0184 
0185 void ExpressionParserTest::testnotFunction() {
0186     auto fnct = getFunction1(QStringLiteral("not"));
0187     QVERIFY(fnct);
0188 
0189     QCOMPARE(fnct(1), 0);
0190     QCOMPARE(fnct(0), 1);
0191     QCOMPARE(fnct(-1), 0); // According to C/C++ standard. -1 is true and !-1 is false
0192     QCOMPARE(fnct(2), 0);
0193 }
0194 
0195 void ExpressionParserTest::testbetweenIncluded() {
0196     auto fnct = getFunction3(QStringLiteral("between_inc"));
0197     QVERIFY(fnct);
0198 
0199     QCOMPARE(fnct(0.99, 1, 5), 0);
0200     QCOMPARE(fnct(1, 1, 5), 1);
0201     QCOMPARE(fnct(2, 1, 5), 1);
0202     QCOMPARE(fnct(5, 1, 5), 1);
0203     QCOMPARE(fnct(5.11, 1, 5), 0);
0204 }
0205 void ExpressionParserTest::testoutsideIncluded() {
0206     auto fnct = getFunction3(QStringLiteral("outside_inc"));
0207     QVERIFY(fnct);
0208 
0209     QCOMPARE(fnct(0.99, 1, 5), 1);
0210     QCOMPARE(fnct(1, 1, 5), 1);
0211     QCOMPARE(fnct(2, 1, 5), 0);
0212     QCOMPARE(fnct(5, 1, 5), 1);
0213     QCOMPARE(fnct(5.11, 1, 5), 1);
0214 }
0215 void ExpressionParserTest::testbetween() {
0216     auto fnct = getFunction3(QStringLiteral("between"));
0217     QVERIFY(fnct);
0218 
0219     QCOMPARE(fnct(0.99, 1, 5), 0);
0220     QCOMPARE(fnct(1, 1, 5), 0);
0221     QCOMPARE(fnct(2, 1, 5), 1);
0222     QCOMPARE(fnct(5, 1, 5), 0);
0223     QCOMPARE(fnct(5.11, 1, 5), 0);
0224 }
0225 void ExpressionParserTest::testoutside() {
0226     auto fnct = getFunction3(QStringLiteral("outside"));
0227     QVERIFY(fnct);
0228 
0229     QCOMPARE(fnct(0.99, 1, 5), 1);
0230     QCOMPARE(fnct(1, 1, 5), 0);
0231     QCOMPARE(fnct(2, 1, 5), 0);
0232     QCOMPARE(fnct(5, 1, 5), 0);
0233     QCOMPARE(fnct(5.11, 1, 5), 1);
0234 }
0235 void ExpressionParserTest::testequalEpsilon() {
0236     auto fnct = getFunction3(QStringLiteral("equalE"));
0237     QVERIFY(fnct);
0238 
0239     QCOMPARE(fnct(0.99, 1, 5), 1);
0240     QCOMPARE(fnct(1, 1, 5), 1);
0241     QCOMPARE(fnct(2, 1, 5), 1);
0242     QCOMPARE(fnct(5, 1, 5), 1);
0243     QCOMPARE(fnct(5.11, 1, 5), 1);
0244 
0245     QCOMPARE(fnct(5.11, 5.3, 0.1), 0);
0246     QCOMPARE(fnct(-5.11, 5.3, 0.2), 0);
0247     QCOMPARE(fnct(-5.11, -5.3, 0.2), 1);
0248 }
0249 
0250 void ExpressionParserTest::testRoundn() {
0251     auto fnct = getFunction2(QStringLiteral("roundn"));
0252     QVERIFY(fnct);
0253 
0254     QCOMPARE(fnct(3.1415, 2), 3.14); // round down
0255     QCOMPARE(fnct(10.2397281298423, 5), 10.23973); // roundup
0256     QCOMPARE(fnct(10000.1, 5), 10000.1);
0257     QCOMPARE(fnct(123.45, -1), 120.);
0258     QCOMPARE(fnct(1.45, 1), 1.5);
0259     QCOMPARE(fnct(-1.45, 1), -1.5);
0260     QCOMPARE(fnct(-1.44, 1), -1.4);
0261     QCOMPARE(fnct(-123.45, 1), -123.5);
0262     QCOMPARE(fnct(-123.44, 1), -123.4);
0263     QCOMPARE(fnct(-123.45, -1), -120);
0264 }
0265 
0266 void ExpressionParserTest::testSpecialFunctions() {
0267     auto fnct = getFunction1(QStringLiteral("cbrt"));
0268     QVERIFY(fnct);
0269 
0270     QCOMPARE(fnct(8.), 2.);
0271     QCOMPARE(fnct(-8.), -2.);
0272 
0273     fnct = getFunction1(QStringLiteral("logb"));
0274     QVERIFY(fnct);
0275 
0276     QCOMPARE(fnct(0.1), -4.);
0277     QCOMPARE(fnct(0.4), -2.);
0278     QCOMPARE(fnct(0.5), -1.);
0279     QCOMPARE(fnct(8.), 3.);
0280     QCOMPARE(fnct(10.), 3.);
0281     QCOMPARE(fnct(100.), 6.);
0282 
0283     fnct = getFunction1(QStringLiteral("rint"));
0284     QVERIFY(fnct);
0285 
0286     QCOMPARE(fnct(0.), 0.);
0287     QCOMPARE(fnct(0.5), 0.);
0288     QCOMPARE(fnct(1.49), 1.);
0289     QCOMPARE(fnct(-0.5), 0.);
0290     QCOMPARE(fnct(-0.99), -1.);
0291     QCOMPARE(fnct(-1.5), -2.);
0292 
0293     fnct = getFunction1(QStringLiteral("round"));
0294     QVERIFY(fnct);
0295 
0296     QCOMPARE(fnct(0.), 0.);
0297     QCOMPARE(fnct(0.5), 1.);
0298     QCOMPARE(fnct(1.49), 1.);
0299     QCOMPARE(fnct(-0.5), -1.);
0300     QCOMPARE(fnct(-0.99), -1.);
0301     QCOMPARE(fnct(-1.5), -2.);
0302 
0303     fnct = getFunction1(QStringLiteral("trunc"));
0304     QVERIFY(fnct);
0305 
0306     QCOMPARE(fnct(0.), 0.);
0307     QCOMPARE(fnct(0.5), 0.);
0308     QCOMPARE(fnct(1.49), 1.);
0309     QCOMPARE(fnct(-0.5), -0.);
0310     QCOMPARE(fnct(-0.99), -0.);
0311     QCOMPARE(fnct(-1.5), -1.);
0312 }
0313 
0314 void ExpressionParserTest::testevaluateCartesian() {
0315     const QString expr = QStringLiteral("x+y");
0316     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0317 
0318     QVector<QVector<double>*> xVectors;
0319 
0320     xVectors << new QVector<double>({1., 2., 3.}); // x
0321     xVectors << new QVector<double>({4., 5., 6., 9.}); // y
0322     QVector<double> yVector({101., 123., 345., 239., 1290., 43290., 238., 342., 823., 239.});
0323     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0324 
0325     QVector<double> ref({5., 7., 9.});
0326     QCOMPARE(yVector.size(), 10);
0327     COMPARE_DOUBLE_VECTORS_AT_LEAST_LENGTH(yVector, ref);
0328     QCOMPARE(yVector.at(3), NAN);
0329     QCOMPARE(yVector.at(4), NAN);
0330     QCOMPARE(yVector.at(5), NAN);
0331     QCOMPARE(yVector.at(6), NAN);
0332     QCOMPARE(yVector.at(7), NAN);
0333     QCOMPARE(yVector.at(8), NAN);
0334     QCOMPARE(yVector.at(9), NAN);
0335 }
0336 
0337 void ExpressionParserTest::testevaluateCartesianConstExpr() {
0338     const QString expr = QStringLiteral("5 + 5");
0339     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0340 
0341     QVector<QVector<double>*> xVectors;
0342 
0343     xVectors << new QVector<double>({1., 2., 3.}); // x
0344     xVectors << new QVector<double>({4., 5., 6., 9.}); // y
0345     QVector<double> yVector({101., 123., 345., 239., 1290., 43290., 238., 342., 823., 239.});
0346     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0347 
0348     QCOMPARE(yVector.size(), 10);
0349     // All yVector rows are filled
0350     for (const auto v : yVector)
0351         QCOMPARE(v, 5. + 5.);
0352 }
0353 
0354 void ExpressionParserTest::testEvaluateAnd() {
0355     const QString expr = QStringLiteral("x && y");
0356     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0357 
0358     QVector<QVector<double>*> xVectors;
0359 
0360     xVectors << new QVector<double>({1., 0., 1., 0.}); // x
0361     xVectors << new QVector<double>({0., 0., 1., 1.}); // y
0362     QVector<double> yVector({
0363         5.,
0364         5.,
0365         5.,
0366         5.,
0367     }); // random value
0368     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0369 
0370     QCOMPARE(yVector.size(), 4);
0371     QCOMPARE(yVector.at(0), 0.);
0372     QCOMPARE(yVector.at(1), 0.);
0373     QCOMPARE(yVector.at(2), 1.);
0374     QCOMPARE(yVector.at(3), 0.);
0375 }
0376 
0377 void ExpressionParserTest::testEvaluateOr() {
0378     const QString expr = QStringLiteral("x || y");
0379     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0380 
0381     QVector<QVector<double>*> xVectors;
0382 
0383     xVectors << new QVector<double>({1., 0., 1., 0.}); // x
0384     xVectors << new QVector<double>({0., 0., 1., 1.}); // y
0385     QVector<double> yVector({
0386         5.,
0387         5.,
0388         5.,
0389         5.,
0390     }); // random value
0391     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0392 
0393     QCOMPARE(yVector.size(), 4);
0394     QCOMPARE(yVector.at(0), 1.);
0395     QCOMPARE(yVector.at(1), 0.);
0396     QCOMPARE(yVector.at(2), 1.);
0397     QCOMPARE(yVector.at(3), 1.);
0398 }
0399 
0400 void ExpressionParserTest::testEvaluateNot() {
0401     const QString expr = QStringLiteral("!x");
0402     const QStringList vars = {QStringLiteral("x")};
0403 
0404     QVector<QVector<double>*> xVectors;
0405 
0406     xVectors << new QVector<double>({1., 0., -1., 2.}); // x
0407     QVector<double> yVector({5., 5., 5., 5.}); // random value
0408     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0409 
0410     QCOMPARE(yVector.size(), 4);
0411     QCOMPARE(yVector.at(0), 0.);
0412     QCOMPARE(yVector.at(1), 1.);
0413     QCOMPARE(yVector.at(2), 0.); // According to C/C++ standard, -1 is true for bool and therefore the negated is false
0414     QCOMPARE(yVector.at(3), 0.);
0415 }
0416 
0417 void ExpressionParserTest::testEvaluateLogicalExpression() {
0418     const QString expr = QStringLiteral("!x || y && x");
0419     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0420 
0421     QVector<QVector<double>*> xVectors;
0422 
0423     xVectors << new QVector<double>({0., 1., 0., 1.}); // x
0424     xVectors << new QVector<double>({0., 0., 1., 1.}); // y
0425     QVector<double> yVector({
0426         5.,
0427         5.,
0428         5.,
0429         5.,
0430     }); // random value
0431     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0432 
0433     // if or evaluated first:
0434     // x y
0435     // 0 0 : 0
0436     // 1 0 : 0
0437     // 0 1 : 0
0438     // 1 1 : 1
0439 
0440     // if and evaluated first:
0441     // x y
0442     // 0 0 : 1
0443     // 1 0 : 0
0444     // 0 1 : 1
0445     // 1 1 : 1
0446 
0447     // And must be evaluated before or!
0448     QCOMPARE(yVector.size(), 4);
0449     QCOMPARE(yVector.at(0), 1.);
0450     QCOMPARE(yVector.at(1), 0.);
0451     QCOMPARE(yVector.at(2), 1.);
0452     QCOMPARE(yVector.at(3), 1.);
0453 }
0454 
0455 void ExpressionParserTest::testevaluateGreaterThan() {
0456     const QString expr = QStringLiteral("x > y");
0457     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0458 
0459     QVector<QVector<double>*> xVectors;
0460 
0461     xVectors << new QVector<double>({0., 1., 0., 1., -1., -std::numeric_limits<double>::infinity(), 1, std::numeric_limits<double>::infinity(), 7.}); // x
0462     xVectors << new QVector<double>({0., 0., 1., 1., -2., std::numeric_limits<double>::infinity(), std::nan("0"), 1e9, 7.}); // y
0463     QVector<double> yVector({5., 5., 5., 5., 5., 5., 5., 5., 5.}); // random value
0464     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0465 
0466     QCOMPARE(yVector.size(), 9);
0467     QCOMPARE(yVector.at(0), 0.);
0468     QCOMPARE(yVector.at(1), 1.);
0469     QCOMPARE(yVector.at(2), 0.);
0470     QCOMPARE(yVector.at(3), 0.);
0471     QCOMPARE(yVector.at(4), 1.);
0472     QCOMPARE(yVector.at(5), 0.);
0473     QCOMPARE(yVector.at(6), 0.);
0474     QCOMPARE(yVector.at(7), 1.);
0475     QCOMPARE(yVector.at(8), 0.);
0476 }
0477 
0478 void ExpressionParserTest::testevaluateLessThan() {
0479     const QString expr = QStringLiteral("x < y");
0480     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0481 
0482     QVector<QVector<double>*> xVectors;
0483 
0484     xVectors << new QVector<double>({0., 1., 0., 1., -1., -std::numeric_limits<double>::infinity(), 1, std::numeric_limits<double>::infinity(), 7.}); // x
0485     xVectors << new QVector<double>({0., 0., 1., 1., -2., std::numeric_limits<double>::infinity(), std::nan("0"), 1e9, 7.}); // y
0486     QVector<double> yVector({5., 5., 5., 5., 5., 5., 5., 5., 5.}); // random value
0487     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0488 
0489     QCOMPARE(yVector.size(), 9);
0490     QCOMPARE(yVector.at(0), 0.);
0491     QCOMPARE(yVector.at(1), 0.);
0492     QCOMPARE(yVector.at(2), 1.);
0493     QCOMPARE(yVector.at(3), 0.);
0494     QCOMPARE(yVector.at(4), 0.);
0495     QCOMPARE(yVector.at(5), 1.);
0496     QCOMPARE(yVector.at(6), 0.);
0497     QCOMPARE(yVector.at(7), 0.);
0498     QCOMPARE(yVector.at(8), 0.);
0499 }
0500 
0501 void ExpressionParserTest::testevaluateLessEqualThan() {
0502     const QString expr = QStringLiteral("x <= y");
0503     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0504 
0505     QVector<QVector<double>*> xVectors;
0506 
0507     xVectors << new QVector<double>({0., 1., 0., 1., -1., -std::numeric_limits<double>::infinity(), 1, std::numeric_limits<double>::infinity(), 7.}); // x
0508     xVectors << new QVector<double>({0., 0., 1., 1., -2., std::numeric_limits<double>::infinity(), std::nan("0"), 1e9, 7.}); // y
0509     QVector<double> yVector({5., 5., 5., 5., 5., 5., 5., 5., 5.}); // random value
0510     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0511 
0512     QCOMPARE(yVector.size(), 9);
0513     QCOMPARE(yVector.at(0), 1.);
0514     QCOMPARE(yVector.at(1), 0.);
0515     QCOMPARE(yVector.at(2), 1.);
0516     QCOMPARE(yVector.at(3), 1.);
0517     QCOMPARE(yVector.at(4), 0.);
0518     QCOMPARE(yVector.at(5), 1.);
0519     QCOMPARE(yVector.at(6), 0.);
0520     QCOMPARE(yVector.at(7), 0.);
0521     QCOMPARE(yVector.at(8), 1.);
0522 }
0523 
0524 void ExpressionParserTest::testevaluateGreaterEqualThan() {
0525     const QString expr = QStringLiteral("x >= y");
0526     const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0527 
0528     QVector<QVector<double>*> xVectors;
0529 
0530     xVectors << new QVector<double>({0., 1., 0., 1., -1., -std::numeric_limits<double>::infinity(), 1, std::numeric_limits<double>::infinity(), 7.}); // x
0531     xVectors << new QVector<double>({0., 0., 1., 1., -2., std::numeric_limits<double>::infinity(), std::nan("0"), 1e9, 7.}); // y
0532     QVector<double> yVector({5., 5., 5., 5., 5., 5., 5., 5., 5.}); // random value
0533     ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0534 
0535     QCOMPARE(yVector.size(), 9);
0536     QCOMPARE(yVector.at(0), 1.);
0537     QCOMPARE(yVector.at(1), 1.);
0538     QCOMPARE(yVector.at(2), 0.);
0539     QCOMPARE(yVector.at(3), 1.);
0540     QCOMPARE(yVector.at(4), 1.);
0541     QCOMPARE(yVector.at(5), 0.);
0542     QCOMPARE(yVector.at(6), 0.);
0543     QCOMPARE(yVector.at(7), 1.);
0544     QCOMPARE(yVector.at(8), 1.);
0545 }
0546 
0547 // This is not implemented. It uses always the smallest rowCount
0548 // Does not matter if the variable is used in the expression or not
0549 // void ExpressionParserTest::testevaluateCartesianConstExpr2() {
0550 //  const QString expr = QStringLiteral("5 + y");
0551 //  const QStringList vars = {QStringLiteral("x"), QStringLiteral("y")};
0552 
0553 //  QVector<QVector<double>*> xVectors;
0554 
0555 //  xVectors << new QVector<double>({1., 2., 3.}); // x
0556 //  xVectors << new QVector<double>({4., 5., 6., 9.}); // y
0557 //  QVector<double> yVector({101., 123., 345., 239., 1290., 43290., 238., 342., 823., 239.});
0558 //  ExpressionParser::evaluateCartesian(expr, vars, xVectors, &yVector);
0559 
0560 //  QVector<double> ref({9, 10, 11, 14}); // 5 + y
0561 //  QCOMPARE(yVector.size(), 10);
0562 //  COMPARE_DOUBLE_VECTORS_AT_LEAST_LENGTH(yVector, ref);
0563 //  QCOMPARE(yVector.at(4), NAN);
0564 //  QCOMPARE(yVector.at(5), NAN);
0565 //  QCOMPARE(yVector.at(6), NAN);
0566 //  QCOMPARE(yVector.at(7), NAN);
0567 //  QCOMPARE(yVector.at(8), NAN);
0568 //  QCOMPARE(yVector.at(9), NAN);
0569 //}
0570 
0571 void ExpressionParserTest::testLog2() {
0572     auto fnct = getFunction1(QStringLiteral("log2"));
0573     QVERIFY(fnct);
0574 
0575     QCOMPARE(fnct(2), 1.);
0576     QCOMPARE(fnct(10), 3.32192809489);
0577 }
0578 
0579 QTEST_MAIN(ExpressionParserTest)