File indexing completed on 2024-05-12 15:19:52
0001 /************************************************************************************* 0002 * Copyright (C) 2007 by Aleix Pol <aleixpol@kde.org> * 0003 * * 0004 * This program is free software; you can redistribute it and/or * 0005 * modify it under the terms of the GNU General Public License * 0006 * as published by the Free Software Foundation; either version 2 * 0007 * of the License, or (at your option) any later version. * 0008 * * 0009 * This program is distributed in the hope that it will be useful, * 0010 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0012 * GNU General Public License for more details. * 0013 * * 0014 * You should have received a copy of the GNU General Public License * 0015 * along with this program; if not, write to the Free Software * 0016 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA * 0017 *************************************************************************************/ 0018 0019 #include "matchingtest.h" 0020 #include <QTest> 0021 0022 #include <analitza/expression.h> 0023 #include <substituteexpression.h> 0024 #include <QSharedPointer> 0025 0026 QTEST_MAIN( MatchingTest ) 0027 0028 using namespace Analitza; 0029 0030 void MatchingTest::testCompareTrees_data() 0031 { 0032 QTest::addColumn<bool>("matches"); 0033 QTest::addColumn<QString>("pattern"); 0034 QTest::addColumn<QString>("expression"); 0035 QTest::addColumn<QStringList>("outputs"); 0036 0037 QStringList outputs = QStringList() << QStringLiteral("x") << QStringLiteral("2+2"); 0038 QStringList outputsXY = QStringList() << QStringLiteral("x") << QStringLiteral("2+2") << QStringLiteral("y") << QStringLiteral("2+3"); 0039 0040 QTest::newRow("tree") << true << "x" << "2+2" << outputs; 0041 QTest::newRow("simple") << true << "sin(x)" << "sin(2+2)" << outputs; 0042 QTest::newRow("multiple") << true << "sin(x)+sin(x)" << "sin(2+2)+sin(2+2)" << outputs; 0043 QTest::newRow("deep") << true << "cos(sin(x))" << "cos(sin(2+2))" << outputs; 0044 QTest::newRow("vector") << true << "vector{x,sin(x),x}" << "vector{2+2,sin(2+2),2+2}" << outputs; 0045 QTest::newRow("multiple_wrong") << false << "sin(x)+sin(x)" << "sin(2+2)+sin(2+3)" << outputs; 0046 QTest::newRow("multiple_vars") << true << "sin(x)+sin(y)" << "sin(2+2)+sin(2+3)" << outputsXY; 0047 QTest::newRow("diff") << true << "diff(x:x)" << "diff(x:x)" << (QStringList(QStringLiteral("x")) << QStringLiteral("x")); 0048 QTest::newRow("correct boundings") << false << "diff(x**2:x)" << "diff(x:x)" << (QStringList(QStringLiteral("x")) << QStringLiteral("x")); 0049 0050 QTest::newRow("bounded") << true << "diff(sum(p : w=a..b))" << "diff(sum(x+x:x=0..10))" << (QStringList() << 0051 QStringLiteral("p") << QStringLiteral("x+x") << QStringLiteral("w") << QStringLiteral("x") << QStringLiteral("a") << QStringLiteral("0") << QStringLiteral("b") << QStringLiteral("10")); 0052 } 0053 0054 void MatchingTest::testCompareTrees() 0055 { 0056 QFETCH(bool, matches); 0057 QFETCH(QString, pattern); 0058 QFETCH(QString, expression); 0059 QFETCH(QStringList, outputs); 0060 0061 Expression patt(pattern, false), exp(expression, false); 0062 QMap<QString, QString> outs; 0063 0064 for(QStringList::const_iterator it=outputs.constBegin(); it!=outputs.constEnd(); ++it) { 0065 QString key=*it++; 0066 outs[key]=*it; 0067 } 0068 0069 QMap<QString, const Object*> outFunc; 0070 const Object* p=patt.tree(); 0071 bool ret=p->matches(exp.tree(), &outFunc); 0072 0073 QCOMPARE(ret, matches); 0074 0075 QStringList keys=outs.keys(); 0076 foreach(const QString& key, keys) { 0077 QVERIFY(outFunc.value(key)!=nullptr); 0078 QCOMPARE(outs[key], outFunc[key]->toString()); 0079 } 0080 } 0081 0082 void MatchingTest::testSubstitutions_data() 0083 { 0084 QTest::addColumn<QString>("input"); 0085 QTest::addColumn<QString>("pattern"); 0086 QTest::addColumn<QString>("substitution"); 0087 QTest::addColumn<QString>("result"); 0088 0089 QTest::newRow("bvars") << "diff(sum(f(x+y):y=0..10):x)" << "diff(sum(x:p=a..b):w)" << "sum(diff(x:w):p=a..b)" << "sum(diff(f(x+y):x):y=0..10)"; 0090 QTest::newRow("sinsquare") << "sin(x**2)" << "sin x" << "sin(2*x)" << "sin(2*x^2)"; 0091 QTest::newRow("sindiff") << "diff(sin(cos x):x)" << "diff(sin w:x)" << "diff(w:x)*cos(w)" << "diff(cos(x):x)*cos(cos(x))"; 0092 QTest::newRow("sindiff-y") << "diff(sin(cos y):y)" << "diff(sin w:x)" << "diff(w:x)*cos(w)" << "diff(cos(y):y)*cos(cos(y))"; 0093 } 0094 0095 void MatchingTest::testSubstitutions() 0096 { 0097 QFETCH(QString, input); 0098 QFETCH(QString, pattern); 0099 QFETCH(QString, substitution); 0100 QFETCH(QString, result); 0101 0102 Expression patt(pattern, false), subs(substitution, false), in(input, false); 0103 QMap<QString, const Object*> outFunc; 0104 0105 bool ret=patt.tree()->matches(in.tree(), &outFunc); 0106 QVERIFY(ret); 0107 0108 // for(QMap<QString, const Object*>::const_iterator it=outFunc.constBegin(), itEnd=outFunc.constEnd(); it!=itEnd; ++it) { 0109 // qDebug() << "value:" << it.key() << it.value()->toString(); 0110 // } 0111 0112 SubstituteExpression substitutor; 0113 QSharedPointer<Object> substituted(substitutor.run(subs.tree(), outFunc)); 0114 0115 QCOMPARE(substituted->toString(), result); 0116 } 0117 0118 #include "moc_matchingtest.cpp"