File indexing completed on 2024-05-19 04:34:08

0001 /***************************************************************************
0002  *                                                                         *
0003  *   copyright : (C) 2007 The University of Toronto                        *
0004  *                                                                         *
0005  *   This program 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  ***************************************************************************/
0011 
0012 #include "testeqparser.h"
0013 
0014 #include <QtTest>
0015 
0016 #include <math_kst.h>
0017 #include <kst_inf.h>
0018 #include <enodes.h>
0019 #include <eparse-eh.h>
0020 #include <objectstore.h>
0021 #include <generatedvector.h>
0022 
0023 KSTMATH_EXPORT extern /*"C"*/ int yyparse(Kst::ObjectStore *store);
0024 KSTMATH_EXPORT extern /*"C"*/ void *ParsedEquation;
0025 KSTMATH_EXPORT extern /*"C"*/ struct yy_buffer_state *yy_scan_string(const char*);
0026 
0027 bool optimizerFailed = false;
0028 
0029 Kst::VectorMap vectorsUsed;
0030 Kst::VectorPtr xVector;
0031 
0032 
0033 #include <datacollection.h>
0034 
0035 static Kst::ObjectStore _store;
0036 double _NOPOINT = NAN;
0037 
0038 void TestEqParser::cleanupTestCase() {
0039   xVector = 0L;
0040   vectorsUsed.clear();
0041   _store.clear();
0042 }
0043 
0044 
0045 bool TestEqParser::validateText(const char *equation, const char *expect) {
0046   bool failure = false;
0047   QString txt;
0048   yy_scan_string(equation);
0049   int rc = yyparse(&_store);
0050   if (rc == 0) {
0051     vectorsUsed.clear();
0052     Equations::Node *eq = static_cast<Equations::Node*>(ParsedEquation);
0053     if (!eq)
0054       return false;
0055     ParsedEquation = 0L;
0056     //eq->collectVectors(vectorsUsed);
0057     txt = eq->text();
0058     failure = txt != expect;
0059     delete eq;
0060   } else {
0061     // Parse error
0062     delete (Equations::Node*)ParsedEquation;
0063     ParsedEquation = 0L;
0064     failure = true;
0065   }
0066 
0067   if (failure) {
0068     if (!Equations::errorStack.isEmpty()) {
0069       printf("Failures on [%s] -------------------------\n", equation);
0070       for (QStringList::ConstIterator i = Equations::errorStack.constBegin(); i != Equations::errorStack.constEnd(); ++i) {
0071         printf("%s\n", (*i).toLatin1().data());
0072       }
0073       printf("------------------------------------------\n");
0074     } else {
0075       printf("Got [%s], expected [%s]\n", txt.toLatin1().data(), expect);
0076     }
0077   }
0078   return !failure;
0079 }
0080 
0081 
0082 bool TestEqParser::validateEquation(const char *equation, double x, double result, const double tol) {
0083   yy_scan_string(equation);
0084   int rc = yyparse(&_store);
0085   if (rc == 0) {
0086     vectorsUsed.clear();
0087     Equations::Node *eq = static_cast<Equations::Node*>(ParsedEquation);
0088     if (!eq)
0089       return false;
0090     ParsedEquation = 0L;
0091     Equations::Context ctx;
0092     ctx.sampleCount = 2;
0093     ctx.noPoint = _NOPOINT;
0094     ctx.x = x;
0095     ctx.xVector = xVector;
0096     if (xVector) {
0097       ctx.sampleCount = xVector->length();
0098     }
0099     Equations::FoldVisitor vis(&ctx, &eq);
0100     if (eq->isConst() && !dynamic_cast<Equations::Number*>(eq)) {
0101       if (!optimizerFailed) {
0102         optimizerFailed = true;
0103         printf("Optimizer bug: found an unoptimized const equation.  Optimizing for coverage purposes.\n");
0104       }
0105       double v = eq->value(&ctx);
0106       delete eq;
0107       eq = new Equations::Number(v);
0108     }
0109     Kst::ScalarMap scm;
0110     Kst::StringMap stm;
0111     eq->collectObjects(vectorsUsed, scm, stm);
0112     eq->update(&ctx);
0113     double v = eq->value(&ctx);
0114     delete eq;
0115     if (fabs(v - result) < tol || (result != result && v != v) || (result == INF && v == INF) || (result == -INF && v == -INF)) {
0116       return true;
0117     } else {
0118       printf("Result: %.16f\n", v);
0119       return false;
0120     }
0121   } else {
0122     // Parse error
0123     printf("Failures on [%s] -------------------------\n", equation);
0124     for (QStringList::ConstIterator i = Equations::errorStack.constBegin(); i != Equations::errorStack.constEnd(); ++i) {
0125       printf("%s\n", (*i).toLatin1().data());
0126     }
0127     printf("------------------------------------------\n");
0128     delete (Equations::Node*)ParsedEquation;
0129     ParsedEquation = 0L;
0130     return false;
0131   }
0132 }
0133 
0134 
0135 bool TestEqParser::validateParserFailures(const char *equation) {
0136   bool success = true;
0137   yy_scan_string(equation);
0138   if (0 == yyparse(&_store)) {
0139     printf("Test of (%s) parsing passed, but should have failed.\n", equation);
0140     success = false;
0141   } else {
0142     if (Equations::errorStack.count() == 1 && (Equations::errorStack.first() == "parse error" || Equations::errorStack.first() == "syntax error")) {
0143       printf("ERROR: [%s] doesn't have error handling yet!\n", equation);
0144       success = false;
0145 #ifdef DUMP_FAIL_MSGS
0146     } else {
0147       printf("Failures on [%s] -------------------------\n", equation);
0148       for (QStringList::ConstIterator i = Equations::errorStack.constBegin(); i != Equations::errorStack.constEnd(); ++i) {
0149         printf("%s\n", (*i).toLatin1().data());
0150       }
0151       printf("------------------------------------------\n");
0152 #endif
0153     }
0154   }
0155   return success;
0156 }
0157 
0158 
0159 
0160 void TestEqParser::testEqParser() {
0161 
0162   // Base cases
0163   QVERIFY(validateEquation("0", 1.0, 0.0));
0164   QVERIFY(validateEquation("1.0", 2.0, 1.0));
0165 
0166   // Basics
0167   QVERIFY(validateEquation("x", -1.0, -1.0));
0168   QVERIFY(validateEquation("-x", -1.0, 1.0));
0169   QVERIFY(validateEquation("x^2", -1.0, 1.0));
0170   QVERIFY(validateEquation("     x^2", -1.0, 1.0));
0171   QVERIFY(validateEquation("     x^2           ", -1.0, 1.0));
0172   QVERIFY(validateEquation("x^2 ", -1.0, 1.0));
0173   QVERIFY(validateEquation("x^2 +   x^2", -1.0, 2.0));
0174   QVERIFY(validateEquation("y", 0.0, _NOPOINT));
0175   QVERIFY(validateEquation("foo()", 0.0, _NOPOINT));
0176   QVERIFY(validateEquation("foo(1.0, 2.0, 3.0)", 0.0, _NOPOINT));
0177 
0178   // Order of evaluation and parser issues
0179   QVERIFY(validateEquation("-x^2", 2.0, -4.0));
0180   QVERIFY(validateEquation("(-x)^2", 2.0, 4.0));
0181   QVERIFY(validateEquation("-(x^2)", 2.0, -4.0));
0182   QVERIFY(validateEquation("(-x^2)", 2.0, -4.0));
0183   QVERIFY(validateEquation("x*x+5", 2.0, 9.0));
0184   QVERIFY(validateEquation("5+x*x", 2.0, 9.0));
0185   QVERIFY(validateEquation("5*4/2*5", 1.0, 50.0));
0186   QVERIFY(validateEquation("asin(sin(x))", 3.14159265358979323, 0.0));
0187   QVERIFY(validateEquation("x^(1/2)", 2.0, sqrt(2.0)));
0188   QVERIFY(validateEquation("x^(1/2)*2", 2.0, 2.0*sqrt(2.0)));
0189   QVERIFY(validateEquation("(1/2)*x^2+3*x-5", 1.0, -1.5));
0190   QVERIFY(validateEquation("2^3^4", 0.0, 2417851639229258349412352.0));
0191   QVERIFY(validateEquation("sin(x)^2", 0.5*3.14159265358979323, 1.0));
0192   QVERIFY(validateEquation("(2)^(3)", 0.0, 8));
0193   QVERIFY(validateEquation("(2*3)^(3*4)", 0.0, 2176782336.0));
0194   QVERIFY(validateEquation("sin(x^2)", sqrt(3.14159265358979323), 0.0));
0195   QVERIFY(validateEquation("5*4/2", 0.0, 10.0));
0196   QVERIFY(validateEquation("5/4*2", 0.0, 2.5));
0197   QVERIFY(validateEquation("10%2", 0.0, 0.0));
0198   QVERIFY(validateEquation("10.5%2", 0.0, 0.5));
0199   QVERIFY(validateEquation("0%2", 0.0, 0.0));
0200   QVERIFY(validateEquation("2%0", 0.0, _NOPOINT));
0201   QVERIFY(validateEquation("--x", 1.0, 1.0));
0202   QVERIFY(validateEquation("--x", -1.0, -1.0));
0203   QVERIFY(validateEquation("---x", -1.0, 1.0));
0204   QVERIFY(validateEquation("---x", 1.0, -1.0));
0205 
0206   // Constants
0207   QVERIFY(validateEquation("e", 0.0, 2.7128182846));
0208   QVERIFY(validateEquation("pi", 0.0, 3.1415926536));
0209 
0210   // Functions
0211   QVERIFY(validateEquation("sin()", 0.0, _NOPOINT));
0212   QVERIFY(validateEquation("sin(0.0)", 0.0, 0.0));
0213   QVERIFY(validateEquation("sin(3.14159265358979323)", 0.0, 0.0));
0214   QVERIFY(validateEquation("sin(3.14159265358979323/2.00000000000000000000000000)", 0.0, 1.0));
0215   QVERIFY(validateEquation("cos()", 0.0, _NOPOINT));
0216   QVERIFY(validateEquation("cos(0.0)", 0.0, 1.0));
0217   QVERIFY(validateEquation("cos(3.14159265358979323)", 0.0, -1.0));
0218   QVERIFY(validateEquation("cos(3.14159265358979323/2.00000000000000000000000000)", 0.0, 0.0));
0219 
0220   QVERIFY(validateEquation("sec(0.2332744)", 0.0, 1.0278393504553487));
0221   QVERIFY(validateEquation("csc(0.2332744)", 0.0, 4.3259243283703714));
0222   QVERIFY(validateEquation("cot(0.2332744)", 0.0, 4.2087553141976128));
0223   QVERIFY(validateEquation("1/cos(0.2332744)", 0.0, 1.0278393504553487));
0224   QVERIFY(validateEquation("1/sin(0.2332744)", 0.0, 4.3259243283703714));
0225   QVERIFY(validateEquation("1/tan(0.2332744)", 0.0, 4.2087553141976128));
0226 
0227   QVERIFY(validateEquation("sec(0.2332744) == 1/cos(0.2332744)", 0.2332744, 1.0));
0228   QVERIFY(validateEquation("csc(0.2332744) == 1/sin(0.2332744)", 0.2332744, 1.0));
0229   QVERIFY(validateEquation("cot(0.2332744) == 1/tan(0.2332744)", 0.2332744, 1.0));
0230 
0231   QVERIFY(validateEquation("sec(x) == 1/cos(x)", 0.2332744, 1.0));
0232   QVERIFY(validateEquation("csc(x) == 1/sin(x)", 0.2332744, 1.0));
0233   QVERIFY(validateEquation("cot(x) == 1/tan(x)", 0.2332744, 1.0));
0234 
0235   QVERIFY(validateEquation("abs(0.0)", 0.0, 0.0));
0236   QVERIFY(validateEquation("abs(x)", 1.0, 1.0));
0237   QVERIFY(validateEquation("abs(x)", -1.0, 1.0));
0238   QVERIFY(validateEquation("abs(x)", _NOPOINT, _NOPOINT));
0239   QVERIFY(validateEquation("abs(x)", INF, INF));
0240   QVERIFY(validateEquation("abs(x)", -INF, INF));
0241   QVERIFY(validateEquation("abs(-0.000000000001)", 0.0, 0.000000000001));
0242 
0243   QVERIFY(validateEquation("cos(acos(x))", 0.3875823288, 0.3875823288, 0.0000000001));
0244   QVERIFY(validateEquation("acos(cos(x))", 2.3875823288, 2.3875823288, 0.0000000001));
0245   QVERIFY(validateEquation("asin(sin(x))", 0.7540103248, 0.7540103248, 0.0000000001));
0246   QVERIFY(validateEquation("sin(asin(x))", 0.3875823288, 0.3875823288, 0.0000000001));
0247   QVERIFY(validateEquation("tan(atan(x))", 2.3875823288, 2.3875823288, 0.0000000001));
0248   QVERIFY(validateEquation("atan(tan(x))", 0.3875823288, 0.3875823288, 0.0000000001));
0249 
0250   QVERIFY(validateEquation("sqrt(4) == 2.0", 0.0, 1.0));
0251   QVERIFY(validateEquation("sqrt(0) == 0.0", 0.0, 1.0));
0252   QVERIFY(validateEquation("sqrt(-1)", 0.0, _NOPOINT));
0253   QVERIFY(validateEquation("sqrt(2)", 0.0, 1.4142135623730951));
0254 
0255 #ifndef Q_WS_WIN32
0256   QVERIFY(validateEquation("cbrt(0.0) == 0.0", 0.0, 1.0));
0257   QVERIFY(validateEquation("cbrt(8.0) == 2.0", 0.0, 1.0));
0258   QVERIFY(validateEquation("cbrt(-1)", 0.0, -1.0));
0259   QVERIFY(validateEquation("cbrt(2)", 0.0, 1.2599210498948734));
0260 #endif
0261 
0262   // TODO: cosh, exp, log, ln, sinh, tanh
0263 
0264   // Expressions / Comparison
0265   QVERIFY(validateEquation("0.0>0.0", 0.0, 0.0));
0266   QVERIFY(validateEquation("0.0>=0.0", 0.0, 1.0));
0267   QVERIFY(validateEquation("0.0<0.0", 0.0, 0.0));
0268   QVERIFY(validateEquation("0.0<=0.0", 0.0, 1.0));
0269   QVERIFY(validateEquation("0.0=0.0", 0.0, 1.0));
0270   QVERIFY(validateEquation("0.0!=0.0", 0.0, 0.0));
0271   QVERIFY(validateEquation("1.0!=0.0", 0.0, 1.0));
0272   QVERIFY(validateEquation("sin(1.0)!=sin(0.0)", 0.0, 1.0));
0273   QVERIFY(validateEquation("sin()!=sin()", 0.0, 1.0));
0274   QVERIFY(validateEquation("0.0==0.0", 0.0, 1.0));
0275   QVERIFY(validateEquation("1.0>0.0", 0.0, 1.0));
0276   QVERIFY(validateEquation("1.0>=0.0", 0.0, 1.0));
0277   QVERIFY(validateEquation("0.0>1.0", 0.0, 0.0));
0278   QVERIFY(validateEquation("0.0>=1.0", 0.0, 0.0));
0279   QVERIFY(validateEquation("1.0<0.0", 0.0, 0.0));
0280   QVERIFY(validateEquation("1.0<=0.0", 0.0, 0.0));
0281   QVERIFY(validateEquation("0.0<1.0", 0.0, 1.0));
0282   QVERIFY(validateEquation("0.0<=1.0", 0.0, 1.0));
0283   QVERIFY(validateEquation("(0.0/0.0)==(0.0/0.0)", 0.0, 0.0));
0284   QVERIFY(validateEquation("(0.0/0.0)==(1.0/0.0)", 0.0, 0.0));
0285   QVERIFY(validateEquation("(1.0/0.0)==(1.0/0.0)", 0.0, 1.0)); // INF == INF
0286   QVERIFY(validateEquation("(1.0/0.0)==-(1.0/0.0)", 0.0, 0.0));
0287   QVERIFY(validateEquation("(0.0/0.0)==-(1.0/0.0)", 0.0, 0.0));
0288   QVERIFY(validateEquation("(1.0/0.0)==(0.0/0.0)", 0.0, 0.0));
0289   QVERIFY(validateEquation("1&&1", 0.0, 1.0));
0290   QVERIFY(validateEquation("1&&0", 0.0, 0.0));
0291   QVERIFY(validateEquation("0&&1", 0.0, 0.0));
0292   QVERIFY(validateEquation("0&&2", 0.0, 0.0));
0293   QVERIFY(validateEquation("3&&2", 0.0, 1.0));
0294   QVERIFY(validateEquation("1||1", 0.0, 1.0));
0295   QVERIFY(validateEquation("0||1", 0.0, 1.0));
0296   QVERIFY(validateEquation("1||0", 0.0, 1.0));
0297   QVERIFY(validateEquation("0||0", 0.0, 0.0));
0298   QVERIFY(validateEquation("2||4", 0.0, 1.0));
0299   QVERIFY(validateEquation("1||(2&&0)", 0.0, 1.0));
0300   QVERIFY(validateEquation("(1||2)&&0", 0.0, 0.0));
0301   QVERIFY(validateEquation("1||2&&0", 0.0, 1.0));
0302   QVERIFY(validateEquation("2&&0||1", 0.0, 1.0));
0303   QVERIFY(validateEquation("2&&1||0", 0.0, 1.0));
0304   QVERIFY(validateEquation("0||1&&0", 0.0, 0.0));
0305   QVERIFY(validateEquation("1.0 == (1.0 == 1.0)", 0.0, 1.0));
0306   QVERIFY(validateEquation("1.0 != (1.0 == 0.0)", 0.0, 1.0));
0307   QVERIFY(validateEquation("1.0 != (1.0 == 1.0)", 0.0, 0.0));
0308   QVERIFY(validateEquation("0.0 == (1.0 == 0.0)", 0.0, 1.0));
0309   QVERIFY(validateEquation("-1==1", 0.0, 0.0));
0310   QVERIFY(validateEquation("-1==-1", 0.0, 1.0));
0311   QVERIFY(validateEquation("1==-1", 0.0, 0.0));
0312   QVERIFY(validateEquation("1!=-1", 0.0, 1.0));
0313   QVERIFY(validateEquation("-1!=1", 0.0, 1.0));
0314   QVERIFY(validateEquation("-1!=-1", 0.0, 0.0));
0315   QVERIFY(validateEquation("!0.0", 0.0, 1.0));
0316   QVERIFY(validateEquation("!1.0", 0.0, 0.0));
0317   QVERIFY(validateEquation("!-1.0", 0.0, 0.0));
0318   QVERIFY(validateEquation("!2.0", 0.0, 0.0));
0319   QVERIFY(validateEquation("!x", INF, 0.0));
0320   QVERIFY(validateEquation("!x", _NOPOINT, 1.0));
0321   QVERIFY(validateEquation("!(1 > 2)", 0.0, 1.0));
0322   QVERIFY(validateEquation("!1.0 > -1.0", 0.0, 1.0));  // (!1.0) > -1.0
0323   QVERIFY(validateEquation("!!x", 1.0, 1.0));
0324   QVERIFY(validateEquation("!!!x", 1.0, 0.0));
0325   QVERIFY(validateEquation("!!!!x", 1.0, 1.0));
0326 
0327   // Bit operations
0328   QVERIFY(validateEquation("32&4", 0.0, 0.0));
0329   QVERIFY(validateEquation("32&4|2", 0.0, 2.0));
0330   QVERIFY(validateEquation("32|4&2", 0.0, 0.0));
0331   QVERIFY(validateEquation("32|4", 0.0, 36.0));
0332   QVERIFY(validateEquation("0&257", 0.0, 0.0));
0333   QVERIFY(validateEquation("257&0", 0.0, 0.0));
0334   QVERIFY(validateEquation("257|0", 0.0, 257.0));
0335   QVERIFY(validateEquation("0|257", 0.0, 257.0));
0336   QVERIFY(validateEquation("-1|257", 0.0, -1));
0337   QVERIFY(validateEquation("257|-1", 0.0, -1));
0338 
0339   // Scalars
0340   Kst::ScalarPtr s = Kst::kst_cast<Kst::Scalar>(_store.createObject<Kst::Scalar>());
0341   s->setValue(1.0);
0342   s->setOrphan(true);
0343   s->setDescriptiveName("test1");
0344   s = Kst::kst_cast<Kst::Scalar>(_store.createObject<Kst::Scalar>());
0345   s->setValue(0.0);
0346   s->setOrphan(true);
0347   s->setDescriptiveName("test2");
0348   s = Kst::kst_cast<Kst::Scalar>(_store.createObject<Kst::Scalar>());
0349   s->setValue(-1.0);
0350   s->setOrphan(true);
0351   s->setDescriptiveName("test3");
0352   s = Kst::kst_cast<Kst::Scalar>(_store.createObject<Kst::Scalar>());
0353   s->setValue(_NOPOINT);
0354   s->setOrphan(true);
0355   s->setDescriptiveName("test4");
0356   s = Kst::kst_cast<Kst::Scalar>(_store.createObject<Kst::Scalar>());
0357   s->setValue(INF);
0358   s->setOrphan(true);
0359   s->setDescriptiveName("test5");
0360   s = Kst::kst_cast<Kst::Scalar>(_store.createObject<Kst::Scalar>());
0361   s->setValue(-INF);
0362   s->setOrphan(true);
0363   s->setDescriptiveName("sdf");
0364 
0365   QVERIFY(validateEquation("[test1]", 0.0, 1.0));
0366   QVERIFY(validateEquation("[test4]", 0.0, _NOPOINT));
0367   QVERIFY(validateEquation("[test4] - [test4]", 0.0, _NOPOINT));
0368   QVERIFY(validateEquation("[test4] - [test5]", 0.0, _NOPOINT));
0369   QVERIFY(validateEquation("[test4]*[test5]", 0.0, _NOPOINT));
0370 
0371   QVERIFY(validateEquation("[test1 (X1)]", 0.0, 1.0));
0372   QVERIFY(validateEquation("[test4 (X4)]", 0.0, _NOPOINT));
0373   QVERIFY(validateEquation("[test4 (X4)] - [test4 (X4)]", 0.0, _NOPOINT));
0374   QVERIFY(validateEquation("[test4 (X4)] - [test5 (X5)]", 0.0, _NOPOINT));
0375   QVERIFY(validateEquation("[test4 (X4)]*[test5 (X5)]", 0.0, _NOPOINT));
0376 
0377   QVERIFY(validateEquation("[X1]", 0.0, 1.0));
0378   QVERIFY(validateEquation("[X4]", 0.0, _NOPOINT));
0379   QVERIFY(validateEquation("[X4] - [X4]", 0.0, _NOPOINT));
0380   QVERIFY(validateEquation("[X4] - [X5]", 0.0, _NOPOINT));
0381   QVERIFY(validateEquation("[X4]*[X5]", 0.0, _NOPOINT));
0382 
0383   QVERIFY(validateEquation("[sdf]", 0.0, -INF));
0384 
0385   QVERIFY(validateEquation("[=10+10]", 0.0, 20.0));
0386 
0387   // Vectors
0388   Kst::GeneratedVectorPtr gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0389   Q_ASSERT(gv);
0390   gv->changeRange(0, 1.0, 10);
0391   gv->setDescriptiveName("gvector1");
0392   gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0393   Q_ASSERT(gv);
0394   gv->changeRange(0, 1.0, 10);
0395   gv->setDescriptiveName("gvector2");
0396   gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0397   Q_ASSERT(gv);
0398   gv->changeRange(1.0, 2.0, 10);
0399   gv->setDescriptiveName("gvector3");
0400   gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0401   Q_ASSERT(gv);
0402   gv->changeRange(0, 1.0, 2);
0403   gv->setDescriptiveName("gvector4");
0404   gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0405   Q_ASSERT(gv);
0406   gv->changeRange(-1.0, 1.0, 1000);
0407   gv->setDescriptiveName("gvector5");
0408   gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0409   Q_ASSERT(gv);
0410   gv->changeRange(-1.0, 1.0, 1000);
0411   gv->setDescriptiveName("gvector6");
0412 
0413   QVERIFY(validateEquation("[gvector3] - [gvector2]", 0.0, 1.0));
0414   QVERIFY(validateEquation("[gvector3[9]]", 0.0, 2.0));
0415   QVERIFY(validateEquation("[gvector3[5+4]]", 0.0, 2.0));
0416   QVERIFY(validateEquation("[gvector3[]]", 0.0, 1.0));
0417   QVERIFY(validateEquation("2*sin([gvector6])", 0.0, -1.6829419696157930));
0418 
0419   QVERIFY(validateEquation("[gvector3 (V3)] - [gvector2 (V2)]", 0.0, 1.0));
0420   QVERIFY(validateEquation("[gvector3 (V3)[9]]", 0.0, 2.0));
0421   QVERIFY(validateEquation("[gvector3 (V3)[5+4]]", 0.0, 2.0));
0422   QVERIFY(validateEquation("[gvector3 (V3)[]]", 0.0, 1.0));
0423   QVERIFY(validateEquation("2*sin([gvector6 (V6)])", 0.0, -1.6829419696157930));
0424 
0425 
0426   QVERIFY(validateEquation("[V3] - [V2]", 0.0, 1.0));
0427   QVERIFY(validateEquation("[V3[9]]", 0.0, 2.0));
0428   QVERIFY(validateEquation("[V3[5+4]]", 0.0, 2.0));
0429   QVERIFY(validateEquation("[V3[]]", 0.0, 1.0));
0430   QVERIFY(validateEquation("2*sin([V6])", 0.0, -1.6829419696157930));
0431 
0432   // TODO: interpolation, more vector combinations
0433 
0434   // Plugins
0435   QEXPECT_FAIL("", "Plugins in equations are not implemented yet", Continue);
0436   QVERIFY(validateEquation("2*plugin(bin, [V4], 12)", 1.0, -1.9779779779779778));
0437   QEXPECT_FAIL("", "Plugins in equations are not implemented yet", Continue);
0438   QVERIFY(validateEquation("4*plugin(bin, [V4], x)", 5.0, -3.9839839839839839));
0439   QVERIFY(validateEquation("-3*plugin(bin, x, 12)", 2.0, _NOPOINT));
0440   gv = Kst::kst_cast<Kst::GeneratedVector>(_store.createObject<Kst::GeneratedVector>());
0441   Q_ASSERT(gv);
0442   gv->changeRange(0, 100, 2000);
0443   xVector = gv;
0444   QEXPECT_FAIL("", "Plugins in equations are not implemented yet", Continue);
0445   QVERIFY(validateEquation("-3*plugin(bin, x, 12)", 2.0, -0.8254127063531767));
0446   QVERIFY(validateEquation("-3*plugin(bin, y, 12)", 2.0, _NOPOINT));
0447 
0448   // TODO: more plugin tests
0449 
0450   // TODO: float notation
0451 
0452   // Combinations
0453   QVERIFY(validateEquation("1|0&&0", 0.0, 0.0));
0454   QVERIFY(validateEquation("0&&0|1", 0.0, 0.0));
0455   QVERIFY(validateEquation("0&&1|0", 0.0, 0.0));
0456   QVERIFY(validateEquation("0||1&1", 0.0, 1.0));
0457   QVERIFY(validateEquation("0||2&1", 0.0, 0.0));
0458   QVERIFY(validateEquation("2&1||0", 0.0, 0.0));
0459   QVERIFY(validateEquation("1-1||0", 0.0, 0.0));
0460   QVERIFY(validateEquation("2-2||0", 0.0, 0.0));
0461   QVERIFY(validateEquation("0||2-2", 0.0, 0.0));
0462   QVERIFY(validateEquation("8|2*2", 0.0, 12.0));
0463   QVERIFY(validateEquation("2*2|8", 0.0, 12.0));
0464 
0465   QVERIFY(validateEquation("[gvector2] > 0.0", 0.0, 0.0));
0466   QVERIFY(validateEquation("[gvector2] > -1.0", 0.0, 1.0));
0467 
0468   QVERIFY(validateEquation("[gvector2 (V2)] > 0.0", 0.0, 0.0));
0469   QVERIFY(validateEquation("[gvector2 (V2)] > -1.0", 0.0, 1.0));
0470 
0471   QVERIFY(validateEquation("[V2] > 0.0", 0.0, 0.0));
0472   QVERIFY(validateEquation("[V2] > -1.0", 0.0, 1.0));
0473 
0474   QVERIFY(validateEquation("-([gvector2]*sin([gvector2]*[gvector3])+[gvector4]*cos([gvector4]*[gvector4]))", 0.0, 0.0));
0475   QVERIFY(validateEquation("[gvector4] * -1", 0.0, 0.0));
0476 
0477   QVERIFY(validateEquation("-([gvector2 (V2)]*sin([gvector2 (V2)]*[gvector3 (V3)])+[gvector4 (V4)]*cos([gvector4 (V4)]*[gvector4 (V4)]))", 0.0, 0.0));
0478   QVERIFY(validateEquation("[gvector4 (V4)] * -1", 0.0, 0.0));
0479 
0480   QVERIFY(validateEquation("-([V2]*sin([V2]*[V3])+[V4]*cos([V4]*[V4]))", 0.0, 0.0));
0481   QVERIFY(validateEquation("[V4] * -1", 0.0, 0.0));
0482 
0483   QVERIFY(validateText("3*x", "3*x"));
0484   QVERIFY(validateText("(3*x)", "(3*x)"));
0485   QVERIFY(validateText("3*(x)", "3*x"));
0486   QVERIFY(validateText("((3*x))", "(3*x)"));
0487   QVERIFY(validateText(" ((3 * x)) ", "(3*x)"));
0488   QVERIFY(validateText(" ((3 * x)) ", "(3*x)"));
0489   QVERIFY(validateText("(-3)", "(-3)"));
0490   QVERIFY(validateText("(x)", "x"));
0491   QVERIFY(validateText("(3*(-(x+5)))", "(3*(-(x+5)))"));
0492   QVERIFY(validateText("(sin((x)))", "sin(x)"));
0493 
0494   /*  Wrap a testcase with this and run bison with -t in order to get a trace
0495    *  of the parse stack */
0496 #if 0
0497   yydebug = 1;
0498   yydebug = 0;
0499 #endif
0500   // Errors:
0501   QVERIFY(validateParserFailures(""));
0502   QVERIFY(validateParserFailures(" "));
0503   QVERIFY(validateParserFailures("\t"));
0504   QVERIFY(validateParserFailures(" \t \t"));
0505   QVERIFY(validateParserFailures("[]"));
0506   QVERIFY(validateParserFailures("[[]"));
0507   QVERIFY(validateParserFailures("[]]"));
0508   QVERIFY(validateParserFailures("]"));
0509   QVERIFY(validateParserFailures("["));
0510   QVERIFY(validateParserFailures("]["));
0511   QVERIFY(validateParserFailures("[]["));
0512   QVERIFY(validateParserFailures("foo(, 3)"));
0513   QVERIFY(validateParserFailures("foo(3,)"));
0514   QVERIFY(validateParserFailures("foo(3,,5)"));
0515   QVERIFY(validateParserFailures("foo([])"));
0516   QVERIFY(validateParserFailures("foo(4, [])"));
0517   QVERIFY(validateParserFailures("/"));
0518   QVERIFY(validateParserFailures("/2"));
0519   QEXPECT_FAIL("", "This has always failed", Continue);
0520   QVERIFY(validateParserFailures("2/"));
0521   QEXPECT_FAIL("", "This has always failed", Continue);
0522   QVERIFY(validateParserFailures("2//2"));
0523   QVERIFY(validateParserFailures("%"));
0524   QVERIFY(validateParserFailures("%2"));
0525   QEXPECT_FAIL("", "This has always failed", Continue);
0526   QVERIFY(validateParserFailures("2%"));
0527   QEXPECT_FAIL("", "This has always failed", Continue);
0528   QVERIFY(validateParserFailures("2%%2"));
0529   QVERIFY(validateParserFailures("|"));
0530   QVERIFY(validateParserFailures("||"));
0531   QVERIFY(validateParserFailures("|2"));
0532   QEXPECT_FAIL("", "This has always failed", Continue);
0533   QVERIFY(validateParserFailures("2|"));
0534   QVERIFY(validateParserFailures("||2"));
0535   QEXPECT_FAIL("", "This has always failed", Continue);
0536   QVERIFY(validateParserFailures("2||"));
0537   QVERIFY(validateParserFailures("2|||2"));
0538   QVERIFY(validateParserFailures("&"));
0539   QVERIFY(validateParserFailures("&&"));
0540   QVERIFY(validateParserFailures("&2"));
0541   QEXPECT_FAIL("", "This has always failed", Continue);
0542   QVERIFY(validateParserFailures("2&"));
0543   QVERIFY(validateParserFailures("&&2"));
0544   QEXPECT_FAIL("", "This has always failed", Continue);
0545   QVERIFY(validateParserFailures("2&&"));
0546   QVERIFY(validateParserFailures("2&&&2"));
0547   QVERIFY(validateParserFailures("*"));
0548   QVERIFY(validateParserFailures("*2"));
0549   QEXPECT_FAIL("", "This has always failed", Continue);
0550   QVERIFY(validateParserFailures("2*"));
0551   QEXPECT_FAIL("", "This has always failed", Continue);
0552   QVERIFY(validateParserFailures("2**2"));
0553   QVERIFY(validateParserFailures("^"));
0554   QVERIFY(validateParserFailures("^2"));
0555   QVERIFY(validateParserFailures("2^^2"));
0556   QVERIFY(validateParserFailures("2^"));
0557   QVERIFY(validateParserFailures("+"));
0558   QVERIFY(validateParserFailures("+2"));
0559   QEXPECT_FAIL("", "This has always failed", Continue);
0560   QVERIFY(validateParserFailures("2+"));
0561   QEXPECT_FAIL("", "This has always failed", Continue);
0562   QVERIFY(validateParserFailures("2++2"));
0563   QEXPECT_FAIL("", "This has always failed", Continue);
0564   QVERIFY(validateParserFailures("-"));
0565   QEXPECT_FAIL("", "This has always failed", Continue);
0566   QVERIFY(validateParserFailures("2-"));
0567   QEXPECT_FAIL("", "This has always failed", Continue);
0568   QVERIFY(validateParserFailures("-2-"));
0569   QVERIFY(validateParserFailures("2!"));
0570   QVERIFY(validateParserFailures("!"));
0571   QVERIFY(validateParserFailures("()"));
0572   QVERIFY(validateParserFailures("2()"));
0573   QVERIFY(validateParserFailures("()2"));
0574   QVERIFY(validateParserFailures("_"));
0575   QVERIFY(validateParserFailures("#"));
0576   QVERIFY(validateParserFailures("$"));
0577   QVERIFY(validateParserFailures(")"));
0578   QVERIFY(validateParserFailures("("));
0579   QVERIFY(validateParserFailures(")("));
0580   QEXPECT_FAIL("", "This has always failed", Continue);
0581   QVERIFY(validateParserFailures("2&|2"));
0582   QEXPECT_FAIL("", "This has always failed", Continue);
0583   QVERIFY(validateParserFailures("2&&||2"));
0584   QEXPECT_FAIL("", "This has always failed", Continue);
0585   QVERIFY(validateParserFailures("2&&+2"));
0586   QEXPECT_FAIL("", "This has always failed", Continue);
0587   QVERIFY(validateParserFailures("2+&&2"));
0588   QEXPECT_FAIL("", "This has always failed", Continue);
0589   QVERIFY(validateParserFailures("2*&&2"));
0590   QVERIFY(validateParserFailures("2&&*2"));
0591   QEXPECT_FAIL("", "This has always failed", Continue);
0592   QVERIFY(validateParserFailures("2<>2"));
0593   QEXPECT_FAIL("", "This has always failed", Continue);
0594   QVERIFY(validateParserFailures("2=<2"));
0595   QEXPECT_FAIL("", "This has always failed", Continue);
0596   QVERIFY(validateParserFailures("2=>2"));
0597   QEXPECT_FAIL("", "This has always failed", Continue);
0598   QVERIFY(validateParserFailures("2><2"));
0599   QVERIFY(validateParserFailures("<"));
0600   QVERIFY(validateParserFailures("<2"));
0601   QEXPECT_FAIL("", "This has always failed", Continue);
0602   QVERIFY(validateParserFailures("2<"));
0603   QEXPECT_FAIL("", "This has always failed", Continue);
0604   QVERIFY(validateParserFailures("2<<2"));
0605   QVERIFY(validateParserFailures(">"));
0606   QVERIFY(validateParserFailures(">2"));
0607   QEXPECT_FAIL("", "This has always failed", Continue);
0608   QVERIFY(validateParserFailures("2>"));
0609   QEXPECT_FAIL("", "This has always failed", Continue);
0610   QVERIFY(validateParserFailures("2>>2"));
0611   QVERIFY(validateParserFailures(">="));
0612   QVERIFY(validateParserFailures(">=2"));
0613   QEXPECT_FAIL("", "This has always failed", Continue);
0614   QVERIFY(validateParserFailures("2>="));
0615   QEXPECT_FAIL("", "This has always failed", Continue);
0616   QVERIFY(validateParserFailures("2>=>=2"));
0617   QVERIFY(validateParserFailures("<="));
0618   QVERIFY(validateParserFailures("<=2"));
0619   QEXPECT_FAIL("", "This has always failed", Continue);
0620   QVERIFY(validateParserFailures("2<="));
0621   QEXPECT_FAIL("", "This has always failed", Continue);
0622   QVERIFY(validateParserFailures("2<=<=2"));
0623   QEXPECT_FAIL("", "This has always failed", Continue);
0624   QVERIFY(validateParserFailures("2<==2"));
0625   QVERIFY(validateParserFailures("."));
0626   QVERIFY(validateParserFailures(".2"));
0627   QVERIFY(validateParserFailures("2."));
0628   QVERIFY(validateParserFailures(","));
0629   QVERIFY(validateParserFailures(",2"));
0630   QEXPECT_FAIL("", "This has always failed", Continue);
0631   QVERIFY(validateParserFailures("2,")); // Doesn't give a specific error - how to catch this?
0632   QVERIFY(validateParserFailures("2*sin(x"));
0633   QVERIFY(validateParserFailures("2*sin(x)()"));
0634 }
0635 
0636 #ifdef KST_USE_QTEST_MAIN
0637 QTEST_MAIN(TestEqParser)
0638 #endif
0639 
0640 // vim: ts=2 sw=2 et