/************************************************************************************* * Copyright (C) 2007 by Aleix Pol * * * * This program is free software; you can redistribute it and/or * * modify it under the terms of the GNU General Public License * * as published by the Free Software Foundation; either version 2 * * of the License, or (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * *************************************************************************************/ #include "exptest.h" #include "explexer.h" #include "expressionparser.h" #include QTEST_KDEMAIN_CORE( ExpTest ) ExpTest::ExpTest(QObject *parent) : QObject(parent) {} ExpTest::~ExpTest() {} Q_DECLARE_METATYPE(QList) void ExpTest::initTestCase() {} void ExpTest::cleanupTestCase() {} void ExpTest::testSimple_data() { QTest::addColumn("input"); QTest::addColumn("output"); QTest::newRow("1 value") << "1" << "1"; QTest::newRow("addition") << "1+2" << "12"; QTest::newRow("equality") << "1=2" << "12"; QTest::newRow("substraction") << "2-3" << "23"; QTest::newRow("unary minus alone") << "-3" << "3"; QTest::newRow("x*unary minus") << "x*(-3)" << "x" "3"; QTest::newRow("unary minus*x") << "-3*x" << "" "3x"; QTest::newRow("assignation") << "x:=2+3" << "x2" "3"; QTest::newRow("simple expression") << "2+1-3" << "" "213"; QTest::newRow("times") << "1*2" << "12"; QTest::newRow("power") << "1^2" << "12"; QTest::newRow("power") << "1**2"<< "12"; QTest::newRow("times") << "1/2" << "12"; QTest::newRow("priority") << "2+3*5" << "2" "35"; QTest::newRow("function") << "func(x, y)" << "func" "xy"; QTest::newRow("function_np") << "sin 1/x" << "1x"; QTest::newRow("block") << "blk{x, y}" << "xy"; QTest::newRow("sum") << "sum(x : x=1..10)" << "" "x10" "1x"; QTest::newRow("x*sum") << "x*sum(x : x=1..10)" << "xx" "101x"; QTest::newRow("piecewise") << "piecewise{x?a, ?b}" << "ax" "b"; QTest::newRow("piecewise2") << "piecewise{?b}" << "b"; QTest::newRow("piecewise2") << "fib:=n->piecewise { eq(n,0)?0, eq(n,1)?1, ?fib(n-1)+fib(n-2) }" << "fibn0n01n1fibn1fibn2"; QTest::newRow("lambda") << "f:=x->(3)" << "fx3"; QTest::newRow("lambda2") << "f:=(x, y)->(x+y)" << "fxyxy"; QTest::newRow("lambda3") << "g:=y->y" << "gyy"; QTest::newRow("unary minus") << "1*(-2)" << "1" "2"; QTest::newRow("bounds and !limit") << "func(x:x)" << "func" "xx"; QTest::newRow("bounds and limit") << "func(x+y : x=0..1)" << "func" "x10" "xy"; QTest::newRow("bounds and limit") << "card(vector { x, y, z })" << "xyz"; QTest::newRow("lambda call") << "(x->x+2)(2)" << "xx22"; QTest::newRow("union") << "union(list{1}, list {2})" << "12"; QTest::newRow("list") << "list{}" << ""; } void ExpTest::testSimple() { QFETCH(QString, input); QFETCH(QString, output); ExpLexer lex(input); ExpressionParser parser; bool corr=parser.parse(&lex); if(!parser.error().isEmpty()) qDebug() << ">>> " << parser.mathML() << "errors:" << parser.error(); QVERIFY(corr); QVERIFY(parser.error().isEmpty()); QCOMPARE(parser.mathML(), output); } void ExpTest::testExp_data() { QTest::addColumn("input"); QTest::addColumn("output"); QString fourX="xxxx"; //FIXME: Repetition not supported // QTest::newRow("simple expression") << "x+x+x+x" << fourX; QTest::newRow("composed expression") << QString::fromUtf8("2²") << "22"; QTest::newRow("plus operator in plus() form") << "plus(x,x,x,x)" << fourX; QTest::newRow("sum") << "x*sum(x : x=1..10)" << "x" "x10" "1x"; QTest::newRow("lol") << "times((x),(y))" << "xy"; QTest::newRow("lol1") << "times((x),(y),((z)))" << "xyz"; QTest::newRow("notimes") << "2x" << "2x"; // QTest::newRow("notimes_sin") << "2(sin x)" << // "2x"; // QTest::newRow("notimes_sin") << "2sin(x)" << // "2x"; } void ExpTest::testExp() { QFETCH(QString, input); QFETCH(QString, output); ExpLexer lex(input); ExpressionParser parser; bool corr=parser.parse(&lex); if(!parser.error().isEmpty()) qDebug() << "errors:" << parser.error(); QVERIFY(parser.error().isEmpty() && corr); QCOMPARE(parser.mathML(), output); } void ExpTest::testLength_data() { QTest::addColumn("input"); QTest::addColumn >("lengths"); QList lengths; lengths << 1 << 1 << 1 << 1 << 1; QTest::newRow("simple addition") << "2+2+2" << lengths; lengths.clear(); lengths << 1 << 0 << 1; QTest::newRow("power with utf composition") << QString::fromUtf8("2²") << lengths; lengths.clear(); lengths << 1; QTest::newRow("utf composed variable") << QString::fromUtf8("ç") << lengths; lengths.clear(); lengths << 1 << 1; QTest::newRow("no times operator") << QString::fromUtf8("2x") << lengths; } void ExpTest::testLength() { QFETCH(QString, input); QFETCH(QList, lengths); ExpLexer lex=ExpLexer(input); int current=0; while(lex.lex()!=0/*EOF*/) { QVERIFY(lex.current.type>0); QCOMPARE((int) lengths[current], (int) lex.current.len); current++; } } void ExpTest::testCorrection_data() { QTest::addColumn("input"); QTest::addColumn("correct"); QTest::newRow("stack killing") << "k+++k" << false; QTest::newRow("more stack killing") << "k-++k" << false; QTest::newRow("omartinez bug") << "piecewise { gt(x,23)?a }" << true; QTest::newRow("wrong coma") << "2+2," << false; QTest::newRow("wrong token") << "q-<" << false; } void ExpTest::testCorrection() { QFETCH(QString, input); QFETCH(bool, correct); ExpLexer lex(input); ExpressionParser parser; bool corr=parser.parse(&lex); QCOMPARE(corr, correct); QCOMPARE(parser.error().isEmpty(), correct); } #include "exptest.moc"