26 #include <QCoreApplication>
27 #include <QMessageLogger>
42 #include "../vmisc/vmath.h"
57 : QObject(parent), m_vTestFun()
78 const QChar &decimal,
const QChar &thousand )
83 if ( a_szExpr.size() <= 2 || ( a_szExpr.at(0) !=
'0' || a_szExpr.at(1) !=
'x' ) )
90 std::wstring a_szExprStd = a_szExpr.mid(2).toStdWString();
93 stringstream_type::pos_type nPos(0);
95 ss >> std::hex >> iVal;
98 if (nPos==
static_cast<stringstream_type::pos_type
>(0))
103 *a_iPos +=
static_cast<int>(2 + nPos);
104 *a_fVal =
static_cast<qreal
>(iVal);
112 qWarning() <<
"testing member functions...";
115 qreal afVal[3] = {1, 2, 3};
144 qWarning() <<
"TestInterface passed";
148 qWarning() <<
"\n TestInterface failed with " << iStat <<
" errors";
158 qWarning() <<
"testing string arguments...";
160 iStat +=
EqnTest (
"valueof(\"\")", 123,
true );
161 iStat +=
EqnTest (
"valueof(\"aaa\")+valueof(\"bbb\") ", 246,
true );
162 iStat +=
EqnTest (
"2*(valueof(\"aaa\")-23)+valueof(\"bbb\")", 323,
true );
164 iStat +=
EqnTest (
"a*(atof(\"10\")-b)", 8,
true );
165 iStat +=
EqnTest (
"a-(atof(\"10\")*b)", -19,
true );
167 iStat +=
EqnTest (
"strfun1(\"100\")", 100,
true );
168 iStat +=
EqnTest (
"strfun2(\"100\";1)", 101,
true );
169 iStat +=
EqnTest (
"strfun3(\"99\";1;2)", 102,
true );
173 qWarning() <<
"TestStrArg passed";
177 qWarning() <<
"\n TestStrArg failed with " << iStat <<
" errors";
187 qWarning() <<
"testing bulkmode...";
189 #define EQN_TEST_BULK(EXPR, R1, R2, R3, R4, PASS) \
191 double res[] = { R1, R2, R3, R4 }; \
192 iStat += EqnTestBulk(EXPR, res, (PASS)); \
211 qWarning() <<
"passed";
215 qWarning() <<
"\n failed with " << iStat <<
" errors";
225 qWarning() <<
"testing binary operators...";
230 iStat +=
EqnTest (
"a++b", 3,
true );
231 iStat +=
EqnTest (
"a ++ b", 3,
true );
232 iStat +=
EqnTest (
"1++2", 3,
true );
233 iStat +=
EqnTest (
"1 ++ 2", 3,
true );
234 iStat +=
EqnTest (
"a add b", 3,
true );
235 iStat +=
EqnTest (
"1 add 2", 3,
true );
236 iStat +=
EqnTest (
"a<b", 1,
true );
237 iStat +=
EqnTest (
"b>a", 1,
true );
238 iStat +=
EqnTest (
"a>a", 0,
true );
239 iStat +=
EqnTest (
"a<a", 0,
true );
240 iStat +=
EqnTest (
"a>a", 0,
true );
241 iStat +=
EqnTest (
"a<=a", 1,
true );
242 iStat +=
EqnTest (
"a<=b", 1,
true );
243 iStat +=
EqnTest (
"b<=a", 0,
true );
244 iStat +=
EqnTest (
"a>=a", 1,
true );
245 iStat +=
EqnTest (
"b>=a", 1,
true );
246 iStat +=
EqnTest (
"a>=b", 0,
true );
249 iStat +=
EqnTest (
"1 && 1", 1,
true );
250 iStat +=
EqnTest (
"1 && 0", 0,
true );
251 iStat +=
EqnTest (
"(a<b) && (b>a)", 1,
true );
252 iStat +=
EqnTest (
"(a<b) && (a>b)", 0,
true );
255 iStat +=
EqnTest (
"12 & 255", 12,
true );
256 iStat +=
EqnTest (
"12 & 0", 0,
true );
257 iStat +=
EqnTest (
"12&255", 12,
true );
258 iStat +=
EqnTest (
"12&0", 0,
true );
261 iStat +=
EqnTest (
"a = b", 2,
true );
262 iStat +=
EqnTest (
"a = sin(b)", 0.909297,
true );
263 iStat +=
EqnTest (
"a = 1+sin(b)", 1.909297,
true );
264 iStat +=
EqnTest (
"(a=b)*2", 4,
true );
265 iStat +=
EqnTest (
"2*(a=b)", 4,
true );
266 iStat +=
EqnTest (
"2*(a=b+1)", 6,
true );
267 iStat +=
EqnTest (
"(a=b+1)*2", 6,
true );
268 iStat +=
EqnTest (
"a=c; a*10", 30,
true);
270 iStat +=
EqnTest (
"2^2^3", 256,
true );
271 iStat +=
EqnTest (
"1/2/3", 1.0 / 6.0,
true );
274 iStat +=
EqnTest (
"3+4*2/(1-5)^2^3", 3.0001220703125,
true );
278 qWarning() <<
"TestBinOprt passed";
282 qWarning() <<
"\n TestBinOprt failed with " << iStat <<
" errors";
295 qWarning() <<
"testing name restriction enforcement...";
299 #define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG) \
301 QmuParserTester::c_iCount++; \
304 p.Define##DOMAIN(EXPR, ARG); \
306 catch (QmuParserError &) \
308 iErr = static_cast<int>(FAIL); \
387 #undef PARSER_THROWCHECK
391 qWarning() <<
"TestNames passed";
395 qWarning() <<
"\n TestNames failed with " << iStat <<
" errors";
405 qWarning() <<
"testing syntax engine...";
413 iStat +=
EqnTest (
"(1+ 2*a)", 3,
true );
414 iStat +=
EqnTest (
"sqrt((4))", 2,
true );
415 iStat +=
EqnTest (
"sqrt((2)+2)", 2,
true );
416 iStat +=
EqnTest (
"sqrt(2+(2))", 2,
true );
417 iStat +=
EqnTest (
"sqrt(a+(3))", 2,
true );
418 iStat +=
EqnTest (
"sqrt((3)+a)", 2,
true );
419 iStat +=
EqnTest (
"order(1;2)", 1,
true );
420 iStat +=
EqnTest (
"(2+", 0,
false );
421 iStat +=
EqnTest (
"2++4", 0,
false );
422 iStat +=
EqnTest (
"2+-4", 0,
false );
423 iStat +=
EqnTest (
"(2+)", 0,
false );
424 iStat +=
EqnTest (
"--2", 0,
false );
425 iStat +=
EqnTest (
"ksdfj", 0,
false );
426 iStat +=
EqnTest (
"()", 0,
false );
427 iStat +=
EqnTest (
"5+()", 0,
false );
428 iStat +=
EqnTest (
"sin(cos)", 0,
false );
429 iStat +=
EqnTest (
"5t6", 0,
false );
430 iStat +=
EqnTest (
"5 t 6", 0,
false );
431 iStat +=
EqnTest (
"8*", 0,
false );
432 iStat +=
EqnTest (
";3", 0,
false );
433 iStat +=
EqnTest (
"3;5", 0,
false );
434 iStat +=
EqnTest (
"sin(8;8)", 0,
false );
435 iStat +=
EqnTest (
"(7,8)", 0,
false );
436 iStat +=
EqnTest (
"sin)", 0,
false );
437 iStat +=
EqnTest (
"a)", 0,
false );
438 iStat +=
EqnTest (
"pi)", 0,
false );
439 iStat +=
EqnTest (
"sin(())", 0,
false );
440 iStat +=
EqnTest (
"sin()", 0,
false );
444 qWarning() <<
"TestSyntax passed";
448 qWarning() <<
"\n TestSyntax failed with " << iStat <<
" errors";
458 qWarning() <<
"testing variable/constant detection...";
465 iStat +=
EqnTest (
"const", 1,
true );
466 iStat +=
EqnTest (
"const1", 2,
true );
467 iStat +=
EqnTest (
"const2", 3,
true );
468 iStat +=
EqnTest (
"2*const", 2,
true );
469 iStat +=
EqnTest (
"2*const1", 4,
true );
470 iStat +=
EqnTest (
"2*const2", 6,
true );
471 iStat +=
EqnTest (
"2*const+1", 3,
true );
472 iStat +=
EqnTest (
"2*const1+1", 5,
true );
473 iStat +=
EqnTest (
"2*const2+1", 7,
true );
474 iStat +=
EqnTest (
"const", 0,
false );
475 iStat +=
EqnTest (
"const1", 0,
false );
476 iStat +=
EqnTest (
"const2", 0,
false );
479 iStat +=
EqnTest (
"a", 1,
true );
480 iStat +=
EqnTest (
"aa", 2,
true );
481 iStat +=
EqnTest (
"2*a", 2,
true );
482 iStat +=
EqnTest (
"2*aa", 4,
true );
483 iStat +=
EqnTest (
"2*a-1", 1,
true );
484 iStat +=
EqnTest (
"2*aa-1", 3,
true );
487 iStat +=
EqnTest (
"0xff", 255,
true );
488 iStat +=
EqnTest (
"0x97 + 0xff", 406,
true );
495 qreal vVarVal[] = { 1, 2, 3, 4, 5};
506 int iCount =
static_cast<int>(UsedVar.size());
514 if ( p.
GetVar().size() != 5 )
519 qmu::varmap_type::const_iterator item = UsedVar.begin();
520 for ( idx = 0; item != UsedVar.end(); ++item )
522 if ( &vVarVal[idx++] != item->second )
529 p.
SetExpr (
"undef1+undef2+undef3" );
531 iCount =
static_cast<int>(UsedVar.size());
539 if ( p.
GetVar().size() != 5 )
544 for ( item = UsedVar.begin(); item != UsedVar.end(); ++item )
546 if ( item->second !=
nullptr )
555 iCount =
static_cast<int>(UsedVar.size());
560 item = UsedVar.begin();
561 for ( idx = 0; item != UsedVar.end(); ++item )
563 if ( &vVarVal[idx++] != item->second )
577 qWarning() <<
"TestVarConst passed";
581 qWarning() <<
"\n TestVarConst failed with " << iStat <<
" errors";
591 qWarning() <<
"testing multiarg functions...";
594 iStat +=
EqnTest (
"1;2;3", 3,
true );
595 iStat +=
EqnTest (
"a;b;c", 3,
true );
596 iStat +=
EqnTest (
"a=10;b=20;c=a*b", 200,
true );
597 iStat +=
EqnTest (
"1;\n2;\n3", 3,
true );
598 iStat +=
EqnTest (
"a;\nb;\nc", 3,
true );
599 iStat +=
EqnTest (
"a=10;\nb=20;\nc=a*b", 200,
true );
600 iStat +=
EqnTest (
"1;\r\n2;\r\n3", 3,
true );
601 iStat +=
EqnTest (
"a;\r\nb;\r\nc", 3,
true );
602 iStat +=
EqnTest (
"a=10;\r\nb=20;\r\nc=a*b", 200,
true );
605 iStat +=
EqnTest (
"f1of1(1)", 1,
true );
606 iStat +=
EqnTest (
"f1of2(1; 2)", 1,
true );
607 iStat +=
EqnTest (
"f2of2(1; 2)", 2,
true );
608 iStat +=
EqnTest (
"f1of3(1; 2; 3)", 1,
true );
609 iStat +=
EqnTest (
"f2of3(1; 2; 3)", 2,
true );
610 iStat +=
EqnTest (
"f3of3(1; 2; 3)", 3,
true );
611 iStat +=
EqnTest (
"f1of4(1; 2; 3; 4)", 1,
true );
612 iStat +=
EqnTest (
"f2of4(1; 2; 3; 4)", 2,
true );
613 iStat +=
EqnTest (
"f3of4(1; 2; 3; 4)", 3,
true );
614 iStat +=
EqnTest (
"f4of4(1; 2; 3; 4)", 4,
true );
615 iStat +=
EqnTest (
"f1of5(1; 2; 3; 4; 5)", 1,
true );
616 iStat +=
EqnTest (
"f2of5(1; 2; 3; 4; 5)", 2,
true );
617 iStat +=
EqnTest (
"f3of5(1; 2; 3; 4; 5)", 3,
true );
618 iStat +=
EqnTest (
"f4of5(1; 2; 3; 4; 5)", 4,
true );
619 iStat +=
EqnTest (
"f5of5(1; 2; 3; 4; 5)", 5,
true );
621 iStat +=
EqnTest (
"1+ping()", 11,
true );
622 iStat +=
EqnTest (
"ping()+1", 11,
true );
623 iStat +=
EqnTest (
"2*ping()", 20,
true );
624 iStat +=
EqnTest (
"ping()*2", 20,
true );
625 iStat +=
EqnTest (
"ping(1;2)", 0,
false );
626 iStat +=
EqnTest (
"1+ping(1;2)", 0,
false );
627 iStat +=
EqnTest (
"f1of1(1;2)", 0,
false );
628 iStat +=
EqnTest (
"f1of1()", 0,
false );
629 iStat +=
EqnTest (
"f1of2(1; 2; 3)", 0,
false );
630 iStat +=
EqnTest (
"f1of2(1)", 0,
false );
631 iStat +=
EqnTest (
"f1of3(1; 2; 3; 4)", 0,
false );
632 iStat +=
EqnTest (
"f1of3(1)", 0,
false );
633 iStat +=
EqnTest (
"f1of4(1; 2; 3; 4; 5)", 0,
false );
634 iStat +=
EqnTest (
"f1of4(1)", 0,
false );
635 iStat +=
EqnTest (
"(1;2;3)", 0,
false );
636 iStat +=
EqnTest (
"1;2;3", 0,
false );
637 iStat +=
EqnTest (
"(1*a;2;3)", 0,
false );
638 iStat +=
EqnTest (
"1;2*a;3", 0,
false );
641 iStat +=
EqnTest (
"min(a; 1)", 1,
true );
642 iStat +=
EqnTest (
"min(3*2; 1)", 1,
true );
643 iStat +=
EqnTest (
"min(3*2; 1)", 6,
false );
644 iStat +=
EqnTest (
"firstArg(2;3;4)", 2,
true );
645 iStat +=
EqnTest (
"lastArg(2;3;4)", 4,
true );
646 iStat +=
EqnTest (
"min(3*a+1; 1)", 1,
true );
647 iStat +=
EqnTest (
"max(3*a+1; 1)", 4,
true );
648 iStat +=
EqnTest (
"max(3*a+1; 1)*2", 8,
true );
649 iStat +=
EqnTest (
"2*max(3*a+1; 1)+2", 10,
true );
652 iStat +=
EqnTest (
"sum(a)", 1,
true );
653 iStat +=
EqnTest (
"sum(1;2;3)", 6,
true );
654 iStat +=
EqnTest (
"sum(a;b;c)", 6,
true );
655 iStat +=
EqnTest (
"sum(1;-max(1;2);3)*2", 4,
true );
656 iStat +=
EqnTest (
"2*sum(1;2;3)", 12,
true );
657 iStat +=
EqnTest (
"2*sum(1;2;3)+2", 14,
true );
658 iStat +=
EqnTest (
"2*sum(-1;2;3)+2", 10,
true );
659 iStat +=
EqnTest (
"2*sum(-1;2;-(-a))+2", 6,
true );
660 iStat +=
EqnTest (
"2*sum(-1;10;-a)+2", 18,
true );
661 iStat +=
EqnTest (
"2*sum(1;2;3)*2", 24,
true );
662 iStat +=
EqnTest (
"sum(1;-max(1;2);3)*2", 4,
true );
663 iStat +=
EqnTest (
"sum(1*3; 4; a+2)", 10,
true );
664 iStat +=
EqnTest (
"sum(1*3; 2*sum(1;2;2); a+2)", 16,
true );
665 iStat +=
EqnTest (
"sum(1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;2)", 24,
true );
668 iStat +=
EqnTest (
"sum()", 0,
false );
669 iStat +=
EqnTest (
"sum(;)", 0,
false );
670 iStat +=
EqnTest (
"sum(1;2;)", 0,
false );
671 iStat +=
EqnTest (
"sum(;1;2)", 0,
false );
675 qWarning() <<
"TestMultiArg passed";
679 qWarning() <<
"\n TestMultiArg failed with " << iStat <<
" errors";
690 qWarning() <<
"testing infix operators...";
692 iStat +=
EqnTest (
"-1", -1,
true );
693 iStat +=
EqnTest (
"-(-1)", 1,
true );
694 iStat +=
EqnTest (
"-(-1)*2", 2,
true );
695 iStat +=
EqnTest (
"-(-2)*sqrt(4)", 4,
true );
696 iStat +=
EqnTest (
"-_pi", -M_PI,
true );
697 iStat +=
EqnTest (
"-a", -1,
true );
698 iStat +=
EqnTest (
"-(a)", -1,
true );
699 iStat +=
EqnTest (
"-(-a)", 1,
true );
700 iStat +=
EqnTest (
"-(-a)*2", 2,
true );
701 iStat +=
EqnTest (
"-(8)", -8,
true );
702 iStat +=
EqnTest (
"-8", -8,
true );
703 iStat +=
EqnTest (
"-(2+1)", -3,
true );
704 iStat +=
EqnTest (
"-(f1of1(1+2*3)+1*2)", -9,
true );
705 iStat +=
EqnTest (
"-(-f1of1(1+2*3)+1*2)", 5,
true );
706 iStat +=
EqnTest (
"-sin(8)", -0.989358,
true );
707 iStat +=
EqnTest (
"3-(-a)", 4,
true );
708 iStat +=
EqnTest (
"3--a", 4,
true );
709 iStat +=
EqnTest (
"-1*3", -3,
true );
712 iStat +=
EqnTest (
"~2#", 8,
true );
713 iStat +=
EqnTest (
"~f1of1(2)#", 8,
true );
714 iStat +=
EqnTest (
"~(b)#", 8,
true );
715 iStat +=
EqnTest (
"(~b)#", 12,
true );
716 iStat +=
EqnTest (
"~(2#)", 8,
true );
717 iStat +=
EqnTest (
"~(f1of1(2)#)", 8,
true );
719 iStat +=
EqnTest (
"-2^2", -4,
true );
720 iStat +=
EqnTest (
"-(a+b)^2", -9,
true );
721 iStat +=
EqnTest (
"(-3)^2", 9,
true );
722 iStat +=
EqnTest (
"-(-2^2)", 4,
true );
723 iStat +=
EqnTest (
"3+-3^2", -6,
true );
726 iStat +=
EqnTest (
"-2'", -4,
true );
727 iStat +=
EqnTest (
"-(1+1)'", -4,
true );
728 iStat +=
EqnTest (
"2+-(1+1)'", -2,
true );
729 iStat +=
EqnTest (
"2+-2'", -2,
true );
732 iStat +=
EqnTest (
"$2^2", 4,
true );
733 iStat +=
EqnTest (
"$(a+b)^2", 9,
true );
734 iStat +=
EqnTest (
"($3)^2", 9,
true );
735 iStat +=
EqnTest (
"$($2^2)", -4,
true );
736 iStat +=
EqnTest (
"3+$3^2", 12,
true );
739 iStat +=
EqnTest (
"~ 123", 123 + 2,
true );
740 iStat +=
EqnTest (
"~~ 123", 123 + 2,
true );
744 qWarning() <<
"TestInfixOprt passed";
748 qWarning() <<
"\n TestInfixOprt failed with " << iStat <<
" errors";
759 qWarning() <<
"testing postfix operators...";
762 iStat +=
EqnTest (
"3{m}+5", 5.003,
true );
763 iStat +=
EqnTest (
"1000{m}", 1,
true );
764 iStat +=
EqnTest (
"1000 {m}", 1,
true );
765 iStat +=
EqnTest (
"(a){m}", 1e-3,
true );
766 iStat +=
EqnTest (
"a{m}", 1e-3,
true );
767 iStat +=
EqnTest (
"a {m}", 1e-3,
true );
768 iStat +=
EqnTest (
"-(a){m}", -1e-3,
true );
769 iStat +=
EqnTest (
"-2{m}", -2e-3,
true );
770 iStat +=
EqnTest (
"-2 {m}", -2e-3,
true );
771 iStat +=
EqnTest (
"f1of1(1000){m}", 1,
true );
772 iStat +=
EqnTest (
"-f1of1(1000){m}", -1,
true );
773 iStat +=
EqnTest (
"-f1of1(-1000){m}", 1,
true );
774 iStat +=
EqnTest (
"f4of4(0;0;0;1000){m}", 1,
true );
775 iStat +=
EqnTest (
"2+(a*1000){m}", 3,
true );
778 iStat +=
EqnTest (
"2*3000meg+2", 2 * 3e9 + 2,
true );
781 iStat +=
EqnTest (
"1000{m}", 0.1,
false );
782 iStat +=
EqnTest (
"(a){m}", 2,
false );
800 qWarning() <<
"TestPostFix passed";
804 qWarning() <<
"\n TestPostFix failed with " << iStat <<
" errors";
814 qWarning() <<
"testing expression samples...";
819 iStat +=
EqnTest (
"2*b*5", 20,
true );
820 iStat +=
EqnTest (
"2*b*5 + 4*b", 28,
true );
821 iStat +=
EqnTest (
"2*a/3", 2.0 / 3.0,
true );
824 iStat +=
EqnTest (
"b--3", b - (-3),
true );
825 iStat +=
EqnTest (
"b-3", b - 3,
true );
826 iStat +=
EqnTest (
"3-b", 3 - b,
true );
827 iStat +=
EqnTest (
"3+b", b + 3,
true );
828 iStat +=
EqnTest (
"b+3", b + 3,
true );
829 iStat +=
EqnTest (
"b*3+2", b * 3 + 2,
true );
830 iStat +=
EqnTest (
"3*b+2", b * 3 + 2,
true );
831 iStat +=
EqnTest (
"2+b*3", b * 3 + 2,
true );
832 iStat +=
EqnTest (
"2+3*b", b * 3 + 2,
true );
833 iStat +=
EqnTest (
"b+3*b", b + 3 * b,
true );
834 iStat +=
EqnTest (
"3*b+b", b + 3 * b,
true );
836 iStat +=
EqnTest (
"2+b*3+b", 2 + b * 3 + b,
true );
837 iStat +=
EqnTest (
"b+2+b*3", b + 2 + b * 3,
true );
839 iStat +=
EqnTest (
"(2*b+1)*4", ( 2 * b + 1 ) * 4,
true );
840 iStat +=
EqnTest (
"4*(2*b+1)", ( 2 * b + 1 ) * 4,
true );
842 iStat +=
EqnTest (
"1+2+3", 6,
true );
845 iStat +=
EqnTest (
"1+2-3*4/5^6", 2.99923,
true );
846 iStat +=
EqnTest (
"1^2/3*4-5+6", 2.33333333,
true );
847 iStat +=
EqnTest (
"1+2*3", 7,
true );
848 iStat +=
EqnTest (
"1+2*3", 7,
true );
849 iStat +=
EqnTest (
"(1+2)*3", 9,
true );
850 iStat +=
EqnTest (
"(1+2)*(-3)", -9,
true );
851 iStat +=
EqnTest (
"2/4", 0.5,
true );
853 iStat +=
EqnTest (
"exp(ln(7))", 7,
true );
854 iStat +=
EqnTest (
"e^ln(7)", 7,
true );
855 iStat +=
EqnTest (
"e^(ln(7))", 7,
true );
856 iStat +=
EqnTest (
"(e^(ln(7)))", 7,
true );
857 iStat +=
EqnTest (
"1-(e^(ln(7)))", -6,
true );
858 iStat +=
EqnTest (
"2*(e^(ln(7)))", 14,
true );
859 iStat +=
EqnTest (
"10^log(5)", 5,
true );
860 iStat +=
EqnTest (
"10^log10(5)", 5,
true );
861 iStat +=
EqnTest (
"2^log2(4)", 4,
true );
862 iStat +=
EqnTest (
"-(sin(0)+1)", -1,
true );
863 iStat +=
EqnTest (
"-(2^1.1)", -2.14354692,
true );
865 iStat +=
EqnTest (
"(cos(2.41)/b)", -0.372056,
true );
866 iStat +=
EqnTest (
"(1*(2*(3*(4*(5*(6*(a+b)))))))", 2160,
true );
867 iStat +=
EqnTest (
"(1*(2*(3*(4*(5*(6*(7*(a+b))))))))", 15120,
true );
868 iStat +=
EqnTest (
"(a/((((b+(((e*(((((pi*((((3.45*((pi+a)+pi))+b)+b)*a))+0.68)+e)+a)/a))+a)+b))+b)*a)-pi))",
873 "(((-9))-e/(((((((pi-(((-7)+(-3)/4/e))))/(((-5))-2)-((pi+(-0))*(sqrt((e+e))*(-8))*(((-pi)+(-pi)-(-9)*(6*5))"
874 "/(-e)-e))/2)/((((sqrt(2/(-e)+6)-(4-2))+((5/(-2))/(1*(-pi)+3))/8)*pi*((pi/((-2)/(-6)*1*(-1))*(-6)+(-e)))))/"
875 "((e+(-2)+(-e)*((((-3)*9+(-e)))+(-9)))))))-((((e-7+(((5/pi-(3/1+pi)))))/e)/(-5))/(sqrt((((((1+(-7))))+((((-"
876 "e)*(-e)))-8))*(-5)/((-e)))*(-6)-((((((-2)-(-9)-(-e)-1)/3))))/(sqrt((8+(e-((-6))+(9*(-9))))*(((3+2-8))*(7+6"
877 "+(-5))+((0/(-e)*(-pi))+7)))+(((((-e)/e/e)+((-6)*5)*e+(3+(-5)/pi))))+pi))/sqrt((((9))+((((pi))-8+2))+pi))/e"
878 "*4)*((-5)/(((-pi))*(sqrt(e)))))-(((((((-e)*(e)-pi))/4+(pi)*(-9)))))))+(-pi)", -12.23016549,
true );
882 "(atan(sin((((((((((((((((pi/cos((a/((((0.53-b)-pi)*e)/b))))+2.51)+a)-0.54)/0.98)+b)*b)+e)/a)+b)+a)+b)+pi)/e"
883 ")+a)))*2.77)", -2.16995656,
true );
886 iStat +=
EqnTest (
"1+2-3*4/5^6*(2*(1-5+(3*7^9)*(4+6*7-3)))+12", -7995810.09926,
true );
890 qWarning() <<
"TestExpression passed";
894 qWarning() <<
"\n TestExpression failed with " << iStat <<
" errors";
904 qWarning() <<
"testing if-then-else operator...";
918 iStat +=
EqnTest (
"1 ? 128 : 255", 128,
true );
919 iStat +=
EqnTest (
"1<2 ? 128 : 255", 128,
true );
920 iStat +=
EqnTest (
"a<b ? 128 : 255", 128,
true );
921 iStat +=
EqnTest (
"(a<b) ? 128 : 255", 128,
true );
922 iStat +=
EqnTest (
"(1) ? 10 : 11", 10,
true );
923 iStat +=
EqnTest (
"(0) ? 10 : 11", 11,
true );
924 iStat +=
EqnTest (
"(1) ? a+b : c+d", 3,
true );
925 iStat +=
EqnTest (
"(0) ? a+b : c+d", 1,
true );
926 iStat +=
EqnTest (
"(1) ? 0 : 1", 0,
true );
927 iStat +=
EqnTest (
"(0) ? 0 : 1", 1,
true );
928 iStat +=
EqnTest (
"(a<b) ? 10 : 11", 10,
true );
929 iStat +=
EqnTest (
"(a>b) ? 10 : 11", 11,
true );
930 iStat +=
EqnTest (
"(a<b) ? c : d", 3,
true );
931 iStat +=
EqnTest (
"(a>b) ? c : d", -2,
true );
933 iStat +=
EqnTest (
"(a>b) ? 1 : 0", 0,
true );
934 iStat +=
EqnTest (
"((a>b) ? 1 : 0) ? 1 : 2", 2,
true );
935 iStat +=
EqnTest (
"((a>b) ? 1 : 0) ? 1 : sum((a>b) ? 1 : 2)", 2,
true );
936 iStat +=
EqnTest (
"((a>b) ? 0 : 1) ? 1 : sum((a>b) ? 1 : 2)", 1,
true );
938 iStat +=
EqnTest (
"sum((a>b) ? 1 : 2)", 2,
true );
939 iStat +=
EqnTest (
"sum((1) ? 1 : 2)", 1,
true );
940 iStat +=
EqnTest (
"sum((a>b) ? 1 : 2; 100)", 102,
true );
941 iStat +=
EqnTest (
"sum((1) ? 1 : 2; 100)", 101,
true );
942 iStat +=
EqnTest (
"sum(3; (a>b) ? 3 : 10)", 13,
true );
943 iStat +=
EqnTest (
"sum(3; (a<b) ? 3 : 10)", 6,
true );
944 iStat +=
EqnTest (
"10*sum(3; (a>b) ? 3 : 10)", 130,
true );
945 iStat +=
EqnTest (
"10*sum(3; (a<b) ? 3 : 10)", 60,
true );
946 iStat +=
EqnTest (
"sum(3; (a>b) ? 3 : 10)*10", 130,
true );
947 iStat +=
EqnTest (
"sum(3; (a<b) ? 3 : 10)*10", 60,
true );
948 iStat +=
EqnTest (
"(a<b) ? sum(3; (a<b) ? 3 : 10)*10 : 99", 60,
true );
949 iStat +=
EqnTest (
"(a>b) ? sum(3; (a<b) ? 3 : 10)*10 : 99", 99,
true );
950 iStat +=
EqnTest (
"(a<b) ? sum(3; (a<b) ? 3 : 10;10;20)*10 : 99", 360,
true );
951 iStat +=
EqnTest (
"(a>b) ? sum(3; (a<b) ? 3 : 10;10;20)*10 : 99", 99,
true );
952 iStat +=
EqnTest (
"(a>b) ? sum(3; (a<b) ? 3 : 10;10;20)*10 : sum(3; (a<b) ? 3 : 10)*10", 60,
true );
955 iStat +=
EqnTest (
"(a<b)&&(a<b) ? 128 : 255", 128,
true );
956 iStat +=
EqnTest (
"(a>b)&&(a<b) ? 128 : 255", 255,
true );
957 iStat +=
EqnTest (
"(1<2)&&(1<2) ? 128 : 255", 128,
true );
958 iStat +=
EqnTest (
"(1>2)&&(1<2) ? 128 : 255", 255,
true );
959 iStat +=
EqnTest (
"((1<2)&&(1<2)) ? 128 : 255", 128,
true );
960 iStat +=
EqnTest (
"((1>2)&&(1<2)) ? 128 : 255", 255,
true );
961 iStat +=
EqnTest (
"((a<b)&&(a<b)) ? 128 : 255", 128,
true );
962 iStat +=
EqnTest (
"((a>b)&&(a<b)) ? 128 : 255", 255,
true );
964 iStat +=
EqnTest (
"1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 255,
true );
965 iStat +=
EqnTest (
"1>0 ? 1>2 ? 128 : 255 :(1>0 ? 32 : 64)", 255,
true );
966 iStat +=
EqnTest (
"1>0 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 128,
true );
967 iStat +=
EqnTest (
"1>0 ? 1>0 ? 128 : 255 :(1>2 ? 32 : 64)", 128,
true );
968 iStat +=
EqnTest (
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 64", 32,
true );
969 iStat +=
EqnTest (
"1>2 ? 1>0 ? 128 : 255 : 1>2 ? 32 : 64", 64,
true );
970 iStat +=
EqnTest (
"1>0 ? 50 : 1>0 ? 128 : 255", 50,
true );
971 iStat +=
EqnTest (
"1>0 ? 50 : (1>0 ? 128 : 255)", 50,
true );
972 iStat +=
EqnTest (
"1>0 ? 1>0 ? 128 : 255 : 50", 128,
true );
973 iStat +=
EqnTest (
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 : 1>2 ? 64 : 16", 32,
true );
974 iStat +=
EqnTest (
"1>2 ? 1>2 ? 128 : 255 : 1>0 ? 32 :(1>2 ? 64 : 16)", 32,
true );
975 iStat +=
EqnTest (
"1>0 ? 1>2 ? 128 : 255 : 1>0 ? 32 :1>2 ? 64 : 16", 255,
true );
976 iStat +=
EqnTest (
"1>0 ? 1>2 ? 128 : 255 : (1>0 ? 32 :1>2 ? 64 : 16)", 255,
true );
977 iStat +=
EqnTest (
"1 ? 0 ? 128 : 255 : 1 ? 32 : 64", 255,
true );
980 iStat +=
EqnTest (
"a= 0 ? 128 : 255; a", 255,
true );
981 iStat +=
EqnTest (
"a=((a>b)&&(a<b)) ? 128 : 255; a", 255,
true );
982 iStat +=
EqnTest (
"c=(a<b)&&(a<b) ? 128 : 255; c", 128,
true );
983 iStat +=
EqnTest (
"0 ? a=a+1 : 666; a", 1,
true );
984 iStat +=
EqnTest (
"1?a=10:a=20; a", 10,
true );
985 iStat +=
EqnTest (
"0?a=10:a=20; a", 20,
true );
986 iStat +=
EqnTest (
"0?a=sum(3;4):10; a", 1,
true );
988 iStat +=
EqnTest (
"a=1?b=1?3:4:5; a", 3,
true );
989 iStat +=
EqnTest (
"a=1?b=1?3:4:5; b", 3,
true );
990 iStat +=
EqnTest (
"a=0?b=1?3:4:5; a", 5,
true );
991 iStat +=
EqnTest (
"a=0?b=1?3:4:5; b", 2,
true );
993 iStat +=
EqnTest (
"a=1?5:b=1?3:4; a", 5,
true );
994 iStat +=
EqnTest (
"a=1?5:b=1?3:4; b", 2,
true );
995 iStat +=
EqnTest (
"a=0?5:b=1?3:4; a", 3,
true );
996 iStat +=
EqnTest (
"a=0?5:b=1?3:4; b", 3,
true );
1000 qWarning() <<
"TestIfThenElse passed";
1004 qWarning() <<
"\n TestIfThenElse failed with " << iStat <<
" errors";
1014 qWarning() <<
"testing error codes...";
1029 #if defined(MUP_MATH_EXCEPTIONS)
1053 iStat +=
ThrowTest (
"valueof(\"xxx\")", 999,
false );
1061 iStat +=
ThrowTest (
"valueof(\"\\\"abc\\\"\")", 999,
false );
1098 qWarning() <<
"TestException passed";
1102 qWarning() <<
"\n TestException failed with " << iStat <<
" errors";
1119 qWarning() <<
"-----------------------------------------------------------";
1120 qWarning() <<
"Running test suite:\n";
1125 for (
int i = 0; i <
m_vTestFun.size(); ++i )
1132 qWarning() <<
"\n" << e.
GetMsg();
1137 catch ( std::exception &e )
1139 qWarning() << e.what();
1145 qWarning() <<
"Internal error";
1156 qWarning() <<
"Test failed with " << iStat
1160 QCoreApplication::exit(iStat);
1163 qWarning() <<
"Done.";
1164 qWarning() <<
"-----------------------------------------------------------";
1175 qreal fVal[] = {1, 1, 1};
1194 if ( a_bFail ==
false || ( a_bFail ==
true && a_iErrc != e.
GetCode() ) )
1196 qWarning() <<
"\n " <<
"Expression: " << a_str <<
" Code:" << e.
GetCode() <<
"(" << e.
GetMsg() <<
")"
1197 <<
" Expected:" << a_iErrc;
1200 return ( a_iErrc == e.
GetCode() ) ? 0 : 1;
1204 bool bRet ( ( a_bFail ==
false ) ? 0 : 1 );
1208 <<
"Expression: " << a_str
1209 <<
" did evaluate; Expected error:" << a_iErrc;
1225 qreal fVal[2] = { -999, -999 };
1243 if ( fabs ( a_fVar1 - fVal[0] ) > 0.0000000001 )
1245 throw std::runtime_error (
"incorrect result (first pass)" );
1248 if ( fabs ( a_fVar2 - fVal[1] ) > 0.0000000001 )
1250 throw std::runtime_error (
"incorrect result (second pass)" );
1255 qWarning() <<
"\n fail: " << a_str <<
" (" << e.
GetMsg() <<
")";
1258 catch ( std::exception &e )
1260 qWarning() <<
"\n fail: " << a_str <<
" (" << e.what() <<
")";
1265 qWarning() <<
"\n fail: " << a_str <<
" (unexpected exception)";
1283 qreal fVal[5] = { -999, -998, -997, -996, -995};
1287 std::unique_ptr<QmuParser> p1;
1296 p1->
DefineConst (
"pi",
static_cast<qreal
>(M_PI) );
1297 p1->DefineConst (
"e",
static_cast<qreal
>(M_E) );
1298 p1->DefineConst (
"const", 1 );
1299 p1->DefineConst (
"const1", 2 );
1300 p1->DefineConst (
"const2", 3 );
1302 qreal vVarVal[] = { 1, 2, 3, -2};
1303 p1->DefineVar (
"a", &vVarVal[0] );
1304 p1->DefineVar (
"aa", &vVarVal[1] );
1305 p1->DefineVar (
"b", &vVarVal[1] );
1306 p1->DefineVar (
"c", &vVarVal[2] );
1307 p1->DefineVar (
"d", &vVarVal[3] );
1313 p1->DefineFun (
"ping",
Ping );
1314 p1->DefineFun (
"f1of1",
f1of1 );
1315 p1->DefineFun (
"f1of2",
f1of2 );
1316 p1->DefineFun (
"f2of2",
f2of2 );
1317 p1->DefineFun (
"f1of3",
f1of3 );
1318 p1->DefineFun (
"f2of3",
f2of3 );
1319 p1->DefineFun (
"f3of3",
f3of3 );
1320 p1->DefineFun (
"f1of4",
f1of4 );
1321 p1->DefineFun (
"f2of4",
f2of4 );
1322 p1->DefineFun (
"f3of4",
f3of4 );
1323 p1->DefineFun (
"f4of4",
f4of4 );
1324 p1->DefineFun (
"f1of5",
f1of5 );
1325 p1->DefineFun (
"f2of5",
f2of5 );
1326 p1->DefineFun (
"f3of5",
f3of5 );
1327 p1->DefineFun (
"f4of5",
f4of5 );
1328 p1->DefineFun (
"f5of5",
f5of5 );
1331 p1->DefineOprt (
"add",
add, 0 );
1332 p1->DefineOprt (
"++",
add, 0 );
1336 p1->DefineFun (
"min",
Min );
1337 p1->DefineFun (
"max",
Max );
1338 p1->DefineFun (
"sum",
Sum );
1339 p1->DefineFun (
"valueof",
ValueOf );
1341 p1->DefineFun (
"strfun1",
StrFun1 );
1342 p1->DefineFun (
"strfun2",
StrFun2 );
1343 p1->DefineFun (
"strfun3",
StrFun3 );
1344 p1->DefineFun (
"lastArg",
LastArg );
1345 p1->DefineFun (
"firstArg",
FirstArg );
1346 p1->DefineFun (
"order",
FirstArg );
1351 p1->DefineInfixOprt (
"$",
sign,
prPOW + 1 );
1352 p1->DefineInfixOprt (
"~",
plus2 );
1353 p1->DefineInfixOprt (
"~~",
plus2 );
1354 p1->DefinePostfixOprt (
"{m}",
Milli );
1355 p1->DefinePostfixOprt (
"{M}",
Mega );
1356 p1->DefinePostfixOprt (
"m",
Milli );
1357 p1->DefinePostfixOprt (
"meg",
Mega );
1358 p1->DefinePostfixOprt (
"#",
times3 );
1359 p1->DefinePostfixOprt (
"'",
sqr );
1360 p1->SetExpr ( a_str );
1364 fVal[0] = p1->Eval();
1365 fVal[1] = p1->Eval();
1376 vParser.push_back ( * ( p1.get() ) );
1381 p1.reset (
nullptr );
1383 fVal[2] = p2.
Eval();
1390 fVal[3] = p3.
Eval();
1395 qreal *v = p2.
Eval ( nNum );
1396 fVal[4] = v[nNum - 1];
1398 catch ( std::exception &e )
1400 qWarning() <<
"\n " << e.what() <<
"\n";
1404 bool bCloseEnough (
true );
1405 for (
unsigned i = 0; i <
sizeof ( fVal ) /
sizeof ( qreal ); ++i )
1407 bCloseEnough &= ( fabs ( a_fRes - fVal[i] ) <= fabs ( fVal[i] * 0.00001 ) );
1413 QT_WARNING_DISABLE_MSVC(4127)
1414 if (std::numeric_limits<qreal>::has_infinity)
1418 std::numeric_limits<qreal>::infinity()) );
1422 iRet = ( ( bCloseEnough && a_fPass ) || ( bCloseEnough ==
false && a_fPass ==
false) ) ? 0 : 1;
1427 qWarning() <<
"\n fail: " << a_str
1428 <<
" (incorrect result; expected: " << a_fRes
1429 <<
" ;calculated: " << fVal[0] <<
","
1444 qWarning() <<
"\n fail: " << a_str <<
" (copy construction)";
1448 qWarning() <<
"\n fail: " << a_str <<
" (" << e.
GetMsg() <<
")";
1453 catch ( std::exception &e )
1455 qWarning() <<
"\n fail: " << a_str <<
" (" << e.what() <<
")";
1460 qWarning() <<
"\n fail: " << a_str <<
" (unexpected exception)";
1478 double vVariableA[] = { 1, 2, 3, 4 };
1479 double vVariableB[] = { 2, 2, 2, 2 };
1480 double vVariableC[] = { 3, 3, 3, 3 };
1481 double vResults[] = { 0, 0, 0, 0 };
1491 p.
Eval(vResults, nBulkSize);
1493 bool bCloseEnough(
true);
1494 for (
int i = 0; i < nBulkSize; ++i)
1496 bCloseEnough &= (fabs(a_fRes[i] - vResults[i]) <= fabs(a_fRes[i] * 0.00001));
1499 iRet = ((bCloseEnough && a_fPass) || (!bCloseEnough && !a_fPass)) ? 0 : 1;
1502 qWarning() <<
"\n fail: " << a_str <<
" (incorrect result; expected: {" << a_fRes[0] <<
","
1503 << a_fRes[1] <<
"," << a_fRes[2] <<
"," << a_fRes[3] <<
"}" <<
" ;calculated: " << vResults[0]
1504 <<
"," << vResults[1] <<
"," << vResults[2] <<
"," << vResults[3] <<
"}";
1511 qWarning() <<
"\n fail: " << e.
GetExpr() <<
" : " << e.
GetMsg();
1517 qWarning() <<
"\n fail: " << a_str <<
" (unexpected exception)";
1530 qWarning() <<
"Test failed (internal error in test class)";
1531 while ( getchar() ==
false);
1532 QCoreApplication::exit ( -1 );
void RemoveVar(const QString &a_strVarName)
Remove a variable from internal storage.
void EnableOptimizer(bool a_bIsOn=true)
Enable or disable the formula optimization feature.
void DefineFun(const QString &a_strName, T a_pFun, bool a_bAllowOpt=true)
Define a parser function without arguments.
void DefineVar(const QString &a_sName, qreal *a_pVar)
Add a user defined variable.
void EnableBuiltInOprt(bool a_bIsOn=true)
Enable or disable the built in binary operators.
void ClearConst()
Clear all user defined constants.
const varmap_type & GetVar() const
Return a map containing the used variables only.
void DefinePostfixOprt(const QString &a_sFun, fun_type1 a_pFun, bool a_bAllowOpt=true)
Add a user defined operator.
const varmap_type & GetUsedVar() const
Return a map containing the used variables only.
void SetExpr(const QString &a_sExpr)
Set the formula.
void ClearPostfixOprt()
Clear all user defined postfix operators.
qreal Eval() const
Calculate the result.
void DefineConst(const QString &a_sName, qreal a_fVal)
Add a user defined constant.
Error class of the parser.
EErrorCodes GetCode() const
Return the error code.
const QString & GetMsg() const
Returns the message string for this error.
const QString & GetToken() const
Return string related with this token (if available).
const QString & GetExpr() const
gets the expression related tp this error.
Mathematical expressions parser.
static qreal ValueOf(const QString &)
static qreal land(qreal v1, qreal v2)
QmuParserTester(QObject *parent=nullptr)
static qreal f3of5(qreal, qreal, qreal v, qreal, qreal)
static qreal f2of2(qreal, qreal v)
static qreal f2of3(qreal, qreal v, qreal)
static qreal StrToFloat(const QString &a_szMsg)
static qreal f1of2(qreal v, qreal)
static void Abort()
Internal error in test class Test is going to be aborted.
static qreal f4of4(qreal, qreal, qreal, qreal v)
static int EqnTest(const QString &a_str, double a_fRes, bool a_fPass)
Evaluate a tet expression.
static qreal f4of5(qreal, qreal, qreal, qreal v, qreal)
static qreal Mega(qreal a_fVal)
static int ThrowTest(const QString &a_str, int a_iErrc, bool a_bFail=true)
int TestNames()
Check muParser name restriction enforcement.
static qreal f1of4(qreal v, qreal, qreal, qreal)
static qreal f2of5(qreal, qreal v, qreal, qreal, qreal)
static qreal f3of4(qreal, qreal, qreal v, qreal)
static qreal add(qreal v1, qreal v2)
static qreal StrFun3(const QString &v1, qreal v2, qreal v3)
static qreal sign(qreal v)
static qreal Sum(const qreal *a_afArg, int a_iArgc)
static qreal f2of4(qreal, qreal v, qreal, qreal)
static qreal f1of1(qreal v)
static qreal StrFun1(const QString &v1)
static int EqnTestWithVarChange(const QString &a_str, double a_fRes1, double a_fVar1, double a_fRes2, double a_fVar2)
Evaluate a tet expression.
static qreal f3of3(qreal, qreal, qreal v)
static qreal sqr(qreal v1)
static qreal f1of5(qreal v, qreal, qreal, qreal, qreal)
static qreal Min(qreal a_fVal1, qreal a_fVal2)
static qreal Max(qreal a_fVal1, qreal a_fVal2)
void AddTest(testfun_type a_pFun)
static qreal f5of5(qreal, qreal, qreal, qreal, qreal v)
static qreal LastArg(const qreal *a_afArg, int a_iArgc)
static qreal f1of3(qreal v, qreal, qreal)
static qreal plus2(qreal v1)
QVector< testfun_type > m_vTestFun
static qreal Milli(qreal a_fVal)
static qreal FirstArg(const qreal *a_afArg, int a_iArgc)
static int IsHexVal(const QString &a_szExpr, int *a_iPos, qreal *a_fVal, const QLocale &locale, const QChar &decimal, const QChar &thousand)
static qreal StrFun2(const QString &v1, qreal v2)
static qreal times3(qreal v1)
static int EqnTestBulk(const QString &a_str, double a_fRes[4], bool a_fPass)
Test an expression in Bulk Mode.
Namespace for mathematical applications.
@ ecDOMAIN_ERROR
catch division by zero, sqrt(-1), log(0) (currently unused)
@ ecTOO_FEW_PARAMS
Too few function parameters. (Example: "ite(1<2;2)")
@ ecMISSING_PARENS
Missing parens. (Example: "3*sin(3")
@ ecUNEXPECTED_OPERATOR
Unexpected binary operator found.
@ ecOPRT_TYPE_CONFLICT
binary operators may only be applied to value items of the same type
@ ecUNEXPECTED_EOF
Unexpected end of formula. (Example: "2+sin(")
@ ecSTRING_EXPECTED
A string function has been called with a different type of argument.
@ ecVAL_EXPECTED
A numerical function has been called with a non value type of argument.
@ ecUNEXPECTED_FUN
Unexpected function found. (Example: "sin(8)cos(9)")
@ ecUNASSIGNABLE_TOKEN
Token cant be identified.
@ ecSTR_RESULT
result is a string
@ ecTOO_MANY_PARAMS
Too many function parameters.
@ ecUNEXPECTED_PARENS
Unexpected Parenthesis, opening or closing.
@ ecUNEXPECTED_CONDITIONAL
@ ecUNEXPECTED_VAL
An unexpected value token has been found.
@ ecUNTERMINATED_STRING
unterminated string constant. (Example: "3*valueof("hello)")
@ ecDIV_BY_ZERO
Division by zero (currently unused)
std::basic_stringstream< char_type, std::char_traits< char_type >, std::allocator< char_type > > stringstream_type
Typedef for easily using stringstream that respect the parser stringtype.
@ prPOW
power operator priority (highest)
std::map< QString, qreal * > varmap_type
Type used for storing variables.
QT_WARNING_POP static Q_REQUIRED_RESULT bool QmuFuzzyComparePossibleNulls(double p1, double p2)
Definition of the standard floating point parser.
This file defines the error class used by the parser.
#define EQN_TEST_BULK(EXPR, R1, R2, R3, R4, PASS)
#define PARSER_THROWCHECK(DOMAIN, FAIL, EXPR, ARG)
This file contains the parser test class.