File indexing completed on 2024-05-12 15:19:53
0001 /************************************************************************************* 0002 * Copyright (C) 2010 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 "typechecktest.h" 0020 0021 #include <QTest> 0022 #include <cmath> 0023 #include "expression.h" 0024 #include <expressiontypechecker.h> 0025 #include <analyzer.h> 0026 0027 QTEST_MAIN( TypeCheckTest ) 0028 0029 using namespace Analitza; 0030 0031 TypeCheckTest::TypeCheckTest(QObject* parent) 0032 : QObject(parent) 0033 , v(new Analitza::Variables) 0034 { 0035 v->modify(QStringLiteral("fnum"), Expression(QStringLiteral("x->3"))); 0036 v->modify(QStringLiteral("fplus"), Expression(QStringLiteral("x->x+x"))); 0037 v->modify(QStringLiteral("tovector"), Expression(QStringLiteral("x->vector{x,x}"))); 0038 v->modify(QStringLiteral("fnull"), Expression(QStringLiteral("x->x"))); 0039 v->modify(QStringLiteral("number"), Expression(QStringLiteral("3"))); 0040 v->modify(QStringLiteral("fwrong"), Expression(QStringLiteral("x->piecewise { 1>2 ? fwrong(x), ?fwrong(x+1) }"))); 0041 // v->modify("frec", Expression("x->piecewise { 3>3? frec(x-1), ? 1}")); 0042 v->modify(QStringLiteral("frec"), Expression(QStringLiteral("x->piecewise { frec(cos(x))>3? 2, ? 1}"))); 0043 v->modify(QStringLiteral("fact"), Expression(QStringLiteral("n->piecewise { n=1?1, ? n*fact(n-1) }"))); 0044 v->modify(QStringLiteral("golambda"), Expression(QStringLiteral("(func, param)->func(param)"))); 0045 v->modify(QStringLiteral("gonum"), Expression(QStringLiteral("func->func(1, 2)"))); // (num -> num -> a) -> a 0046 v->modify(QStringLiteral("valid"), Expression(QStringLiteral("a->true"))); // (num -> num -> a) -> a 0047 0048 v->modify(QStringLiteral("fib"), Expression(QStringLiteral("n->piecewise { eq(n,0)?0, eq(n,1)?1, ?fib(n-1)+fib(n-2) }"))); 0049 v->modify(QStringLiteral("fv"), Expression(QStringLiteral("vector{x->sin(x), x->cos(x)}"))); 0050 v->modify(QStringLiteral("rtail"), Expression(QStringLiteral("(elems,i)->piecewise { card(elems)>=i ? union(list{elems[i]}, rtail(elems, i+1)), ? list{} }"))); 0051 v->modify(QStringLiteral("tail"), Expression(QStringLiteral("elems->rtail(elems,1)"))); 0052 v->modify(QStringLiteral("foldr"), Expression(QStringLiteral("(f,z,elems)->piecewise {card(elems)=0 ? z, ? f(elems[1], foldr(f, z, tail(elems))) }"))); 0053 v->modify(QStringLiteral("foldl"), Expression(QStringLiteral("(f,z,xs)->piecewise{ card(xs)<=0? z, ? foldl(f, f(z, xs[1]), tail(xs)) }"))); 0054 v->modify(QStringLiteral("twoargs"), Expression(QStringLiteral("(x,y)->sin(x)+y"))); 0055 } 0056 0057 TypeCheckTest::~TypeCheckTest() 0058 { 0059 delete v; 0060 } 0061 0062 void TypeCheckTest::testConstruction_data() 0063 { 0064 QTest::addColumn<QString>("input"); 0065 QTest::addColumn<QString>("output"); 0066 0067 QTest::newRow("addition") << "2+4" << "num"; 0068 QTest::newRow("tovector") << "tovector" << "a -> <a,2>"; 0069 QTest::newRow("vectorcall") << "tovector(3)" << "<num,2>"; 0070 QTest::newRow("list+vector") << "list{tovector(3)}" << "[<num,2>]"; 0071 QTest::newRow("additionvec") << "vector{2,2}+vector{2,2}" << "<num,2>"; 0072 QTest::newRow("sum") << "sum(x : x=1..3)" << "num"; 0073 QTest::newRow("sumvec") << "sum(vector{x,x} : x=1..3)" << "<num,2>"; 0074 QTest::newRow("sumvec2") << "sum(x : x=vector{1,1}..vector{3,3})" << "<num,2>"; 0075 QTest::newRow("vector") << "vector {2,2}" << "<num,2>"; 0076 QTest::newRow("list") << "list {2,2}" << "[num]"; 0077 QTest::newRow("direct") << "(x->x)(3)" << "num"; 0078 QTest::newRow("lambda") << "fnum" << "a -> num"; 0079 QTest::newRow("call") << "fnum(3)" << "num"; 0080 QTest::newRow("plus") << "fplus" << "(num -> num) | (<num,-1> -> <num,-1>) | ({num,-1x-2} -> {num,-1x-2})"; 0081 QTest::newRow("call plus") << "fplus(3)" << "num"; 0082 QTest::newRow("call plus vect") << "fplus(vector{3})" << "<num,1>"; 0083 QTest::newRow("vec to vec") << "tovector(vector{3})" << "<<num,1>,2>"; 0084 QTest::newRow("piecewise") << "piecewise { number=3? 3, ?2 }" << "num"; 0085 QTest::newRow("selector") << "selector(2, vector{3, 3})" << "num"; 0086 QTest::newRow("selector1") << "selector(2, vector{vector{3}, vector{3}})" << "<num,1>"; 0087 QTest::newRow("selectorlist") << "selector(2, list{3, 3})" << "num"; 0088 0089 QTest::newRow("rec") << "frec" << "num -> num"; 0090 QTest::newRow("infinite") << "piecewise { 2=3? frec(3), ? 3}" << "num"; 0091 QTest::newRow("infinite_1") << "piecewise { 2=3? 3, ? frec(3)}" << "num"; 0092 QTest::newRow("fact") << "fact(4)" << "num"; 0093 QTest::newRow("factdef") << "fact" << "num -> num"; 0094 QTest::newRow("deriv") << "(diff(x:x))(2)" << "num"; 0095 QTest::newRow("derivdiff") << "diff(x:x)" << "num -> num"; 0096 0097 QTest::newRow("infer_unary") << "n->cos(n)" << "num -> num"; 0098 QTest::newRow("infer") << "n->n=1" << "num -> bool"; 0099 QTest::newRow("siplambda") << "func->func(2)" << "(num -> a) -> a"; 0100 QTest::newRow("numlambda") << "(func, x)->cos(func(x))" << "(a -> num) -> a -> num"; 0101 QTest::newRow("golambda") << "golambda" << "(a -> b) -> a -> b"; 0102 QTest::newRow("golambda1") << "golambda(x->x, 1)" << "num"; 0103 QTest::newRow("golambda2") << "golambda(x->x, vector{1})" << "<num,1>"; 0104 QTest::newRow("golambda3") << "golambda(x->list{x}, 1)" << "[num]"; 0105 QTest::newRow("golambda4") << "golambda(x->list{x}, vector{1})" << "[<num,1>]"; 0106 0107 QTest::newRow("fib") << "fib" << "num -> num"; 0108 QTest::newRow("equation") << "x+cos(x)" << "num"; 0109 // QTest::newRow("long") << "(c, c1, c2, t1, t2)->(t2-t1)/(c2-c1)a(c-c1)+t1" << "num -> num -> num -> num -> num -> num"; 0110 QTest::newRow("selec_call") << "(selector(1, fv))(1)" << "num"; 0111 QTest::newRow("selec") << "selector(1, fv)" << "num -> num"; 0112 0113 QTest::newRow("piece") << "x->piecewise { gt(x,0) ? x, ? x+1 }" << "num -> num"; 0114 QTest::newRow("parametric") << "t->vector{t,t^2}" << "(num -> <num,2>) | ({num,-1x-1} -> <{num,-1x-1},2>)"; 0115 QTest::newRow("somelist") << "t->list{t,t^2}" << "(num -> [num]) | ({num,-1x-1} -> [{num,-1x-1}])"; 0116 QTest::newRow("x->piece") << "x->piecewise { gt(x,0) ? selector(1, vector{x, 1/x})," 0117 "? selector(2, vector{x, 1/x} ) }" << "num -> num"; 0118 QTest::newRow("div") << "v->selector(1, v)/selector(2, v)" << "(<num,-1> -> num) | (<<num,-1>,-1> -> <num,-1>) | ([num] -> num) | ([<num,-1>] -> <num,-1>) | ({num,-2x-1} -> <num,-1>)"; 0119 0120 QTest::newRow("selec_cos") << "v->cos(selector(1, v))" << "(<num,-1> -> num) | ([num] -> num)"; 0121 QTest::newRow("shadowed_param") << "fv->cos(fv)" << "num -> num"; 0122 QTest::newRow("eq") << "x->eq(1,x)" << "num -> bool"; 0123 QTest::newRow("list@sum") << "v->sum(i^2 : i@v)" << "([num] -> num) | (<num,-1> -> num) | ({num,-3x-2} -> num) | ([{num,-1x-1}] -> {num,-1x-1}) | (<{num,-1x-1},-1> -> {num,-1x-1}) | ({{num,-1x-1},-3x-2} -> {num,-1x-1})"; 0124 0125 QTest::newRow("bounded sum_up") << "n->sum(x : x=n..0)" << "num -> num"; 0126 QTest::newRow("bounded sum_down") << "n->sum(x : x=0..n)" << "num -> num"; 0127 QTest::newRow("exists") << "exists(l : l@list{true,false,false})" << "bool"; 0128 QTest::newRow("existslambda") << "x->sum(l : l@list{true,x,false})" << "bool -> bool"; 0129 0130 QTest::newRow("unknown") << "w" << "a"; 0131 0132 QTest::newRow("gonum") << "gonum((x,y)->x*y)" << "num"; 0133 0134 QTest::newRow("selec_cond") << "xs->piecewise {card(xs)=0? xs}" << "([a] -> [a]) | (<a,-1> -> <a,-1>)"; 0135 QTest::newRow("justlambda") << "(f,e)->f(f(e))" << "(a -> a) -> a -> a"; 0136 0137 QTest::newRow("tail") << "ptail:=(elems,i)->piecewise { card(elems)>=i ? union(list{elems[i]}, ptail(elems, i+1)), ? list{} }" 0138 << "(<a,-1> -> num -> [a]) | ([a] -> num -> [a])"; 0139 QTest::newRow("tail1") << "(elems,i)->list{elems[i]}" << "(<a,-1> -> num -> [a]) | ([a] -> num -> [a]) | ({a,-2x-1} -> num -> [<a,-1>])"; 0140 QTest::newRow("tailp") << "(elems,i)->piecewise{ card(elems)>=i ? list{elems[i]}, ? list{}}" << "(<a,-1> -> num -> [a]) | ([a] -> num -> [a])"; 0141 QTest::newRow("tail3") << "(elems,i)->union(list{elems[i]}, list{})" << "(<a,-1> -> num -> [a]) | ([a] -> num -> [a]) | ({b,-2x-1} -> num -> [<b,-1>])"; 0142 QTest::newRow("tail4") << "ptail:=(elems,i)->union(list{elems[i]}, ptail(elems, i))" << "(<a,-1> -> num -> [a]) | ([a] -> num -> [a]) | ({b,-2x-1} -> num -> [<b,-1>])"; 0143 // QTest::newRow("tail5") << "(elems,i)->list{list{elems[i]}, ptail(elems, i)}" << "(<a,-1> -> num -> [a]) | ([a] -> num -> [a])"; 0144 QTest::newRow("tail6") << "tail" << "(<a,-1> -> [a]) | ([a] -> [a])"; 0145 0146 QTest::newRow("pe") << "vector{x->x, x->x+2}" << "<(num -> num),2>"; 0147 QTest::newRow("ana") << "f:=o->vector { x->x+o, x->x*o }" << "(num -> <(num -> num),2>) | (<num,-1> -> <(<num,-1> -> <num,-1>),2>) | ({num,-1x-2} -> <({num,-1x-2} -> {num,-1x-2}),2>)"; 0148 QTest::newRow("pp") << "(x,f)->list{ f(x), cos(x) }" << "num -> (num -> num) -> [num]"; 0149 QTest::newRow("pp1") << "(x,f)->list{ cos(x), f(x) }" << "num -> (num -> num) -> [num]"; 0150 0151 QTest::newRow("foldl") << "foldl" 0152 << "((a -> b -> a) -> a -> <b,-1> -> a) | ((a -> b -> a) -> a -> [b] -> a)"; 0153 // QTest::newRow("foldl1") << "foldl1:=(f,z,xs)->piecewise{ card(xs)>0? foldl1(f, f(z, xs[1]), tail(xs)), ? z }" 0154 // << "((a -> b -> a) -> a -> <b,-1> -> a) | ((a -> b -> a) -> a -> [b] -> a)"; 0155 QTest::newRow("foldl2") << "foldl2:=(f,z,xs)->piecewise{ card(xs)>0? foldl2(f, f(z, xs[1]), tail(xs)), ? cos(z) }" 0156 << "((num -> a -> num) -> num -> <a,-1> -> num) | ((num -> a -> num) -> num -> [a] -> num)"; 0157 QTest::newRow("foldl3") << "foldl3:=(f,z,xs)->foldl3(f, f(z, xs[1]), tail(xs))" << "((a -> b -> a) -> a -> <b,-1> -> c) | ((a -> b -> a) -> a -> [b] -> c)"; 0158 0159 QTest::newRow("foldr") << "(f,z,elems)->piecewise {card(elems)=0 ? z, ? f(elems[1], foldr(f, z, tail(elems))) }" 0160 << "((a -> b -> b) -> b -> <a,-1> -> b) | ((a -> b -> b) -> b -> [a] -> b)"; 0161 QTest::newRow("foldr_call") << "foldr" 0162 << "((a -> b -> b) -> b -> <a,-1> -> b) | ((a -> b -> b) -> b -> [a] -> b)"; 0163 QTest::newRow("foldr1") << "foldr1:=(f,elems)->piecewise {card(elems)=1 ? elems[1], ? f(elems[1], foldr1(f, elems)) }" 0164 << "((a -> a -> a) -> <a,-1> -> a) | ((a -> a -> a) -> [a] -> a)"; 0165 QTest::newRow("foldr11") << "(f,elems)->f(elems[1], f(elems[2], elems[3]))" << "((a -> a -> a) -> <a,-1> -> a) | ((a -> a -> a) -> [a] -> a) | ((<b,-1> -> <b,-1> -> <b,-1>) -> {b,-2x-1} -> a)"; 0166 QTest::newRow("foldr2") << "(f,elems)->f(elems[1], elems[2])" << "((a -> a -> b) -> <a,-1> -> b) | ((a -> a -> b) -> [a] -> b) | ((<a,-1> -> <a,-1> -> b) -> {a,-2x-1} -> b)"; 0167 QTest::newRow("foldr3") << "(f,elems)->f(elems[1])" << "((a -> b) -> <a,-1> -> b) | ((a -> b) -> [a] -> b) | ((<a,-1> -> b) -> {a,-2x-1} -> b)"; 0168 QTest::newRow("foldr4") << "(f,elems)->f(cos(elems[1]))" << "((num -> a) -> <num,-1> -> a) | ((num -> a) -> [num] -> a)"; 0169 QTest::newRow("foldr5") << "(f,elems)->f(f(elems[1]))" << "((a -> a) -> <a,-1> -> a) | ((a -> a) -> [a] -> a) | ((<b,-1> -> <b,-1>) -> {b,-2x-1} -> a)"; 0170 QTest::newRow("foldr6") << "(f,elems)->piecewise {card(elems)=1 ? cos(elems[1]), ? f(elems) }" 0171 << "((<num,-1> -> num) -> <num,-1> -> num) | (([num] -> num) -> [num] -> num)"; 0172 0173 QTest::newRow("filter") << "(condition,elems)->foldr((v,pred)->piecewise{ condition(v) ? union(list{v}, pred), ? pred }, list{}, elems)" 0174 << "((a -> bool) -> <a,-1> -> [a]) | ((a -> bool) -> [a] -> [a])"; 0175 0176 QTest::newRow("arg") << "c->arctan(c[2]/c[1])" << "(<num,-1> -> num) | ([num] -> num)"; 0177 QTest::newRow("rect") << "v->v[1]*cos(v[2])" << "(<num,-1> -> num) | ([num] -> num)"; 0178 QTest::newRow("crash") << "u->(v->vector { v[2] })((v->vector { v[2] })(u))" << "(<a,1> -> <a,1>) | ([a] -> <a,1>) | ({a,-2x1} -> <<a,1>,1>)"; 0179 0180 QTest::newRow("scopes") << "or((x->list{}=x)(list{}), (x->x=0)(0))" << "bool"; 0181 0182 QTest::newRow("unify") << "t->vector { 1, times(2, 3, t) }" << "num -> <num,2>"; 0183 0184 QTest::newRow("nary") << "l->and(l=3, l=3, l=3)" << "num -> bool"; 0185 QTest::newRow("nary1") << "l->and(valid(l), l=3, l=3)" << "num -> bool"; 0186 QTest::newRow("nary2") << "l->and(l=3, l=3, valid(l))" << "num -> bool"; 0187 0188 QTest::newRow("matrix") << "matrix { matrixrow { 1 } }" << "{num,1x1}"; 0189 QTest::newRow("matrix2r") << "matrix { matrixrow { 1 }, matrixrow { 2 } }" << "{num,2x1}"; 0190 QTest::newRow("matrix2c") << "matrix { matrixrow { 1, 2 } }" << "{num,1x2}"; 0191 QTest::newRow("matrix+") << "matrix { matrixrow { 1 }, matrixrow { 2 } }+matrix { matrixrow { 1 }, matrixrow { 2 } }" << "{num,2x1}"; 0192 QTest::newRow("matrix_selector0") << "selector(1, matrix { matrixrow { 1 }, matrixrow { 2 } })" << "<num,1>"; 0193 QTest::newRow("matrix_selector1") << "selector(1, selector(1, matrix { matrixrow { 1 }, matrixrow { 2 } }))" << "num"; 0194 QTest::newRow("matrix_transpose") << "transpose( matrix { matrixrow { 1, 2 } })" << "{num,2x1}"; 0195 } 0196 0197 void TypeCheckTest::testConstruction() 0198 { 0199 QFETCH(QString, input); 0200 QFETCH(QString, output); 0201 0202 Expression e(input); 0203 if(!e.isCorrect()) qDebug() << "errors: " << e.error(); 0204 QVERIFY(e.isCorrect()); 0205 ExpressionTypeChecker t(v); 0206 0207 ExpressionType type=t.check(e); 0208 if(!t.isCorrect()) qDebug() << "errors: " << t.errors(); 0209 0210 QVERIFY(t.isCorrect()); 0211 QCOMPARE(type.simplifyStars().toString(), output); 0212 } 0213 0214 void TypeCheckTest::testUncorrection() 0215 { 0216 QFETCH(QString, input); 0217 0218 Expression e(input); 0219 if(!e.isCorrect()) 0220 qDebug() << "wrong exp:" << e.error(); 0221 QVERIFY(e.isCorrect()); 0222 ExpressionTypeChecker t(v); 0223 0224 ExpressionType result=t.check(e); 0225 0226 if(t.isCorrect()) 0227 qDebug() << "wrong type:" << result.toString(); 0228 QVERIFY(!t.isCorrect()); 0229 // QVERIFY(!t.errors().isEmpty()); 0230 } 0231 0232 void TypeCheckTest::testUncorrection_data() 0233 { 0234 QTest::addColumn<QString>("input"); 0235 QTest::addColumn<QString>("output"); 0236 0237 QTest::newRow("consistency vector") << "vector{2, list{2}}"; 0238 QTest::newRow("consistency list") << "list{2, list{2}}"; 0239 0240 QTest::newRow("piecewise result") << "piecewise { 2=3? 3, ?vector{2} }"; 0241 QTest::newRow("piecewise condit") << "piecewise { vector{3}? 3, ?2 }"; 0242 0243 QTest::newRow("no operator") << "list { 2,2 }+list{2}"; 0244 QTest::newRow("diff vectors") << "vector { 2,2 }+vector { 2 }"; 0245 QTest::newRow("diff types") << "list { 2,2 }+vector { 2 }"; 0246 QTest::newRow("wrong call") << "(x->x+x)(list{3})"; 0247 QTest::newRow("wrong call2") << "fplus(list{3})"; 0248 QTest::newRow("wrong call3") << "(x(x^2))^2"; 0249 QTest::newRow("wrong bounds") << "sum(x : x=1..vector{3,3})"; 0250 QTest::newRow("bounds2") << "sum(x:x@2)"; 0251 QTest::newRow("number call") << "number(3)"; 0252 QTest::newRow("wrong param count") << "golambda(2)"; 0253 QTest::newRow("unresolved operation") << "selector(2,2)"; 0254 0255 QTest::newRow("charvsreal") << "union(\"lalala\", list{1,2,3})"; 0256 QTest::newRow("boolvsreal") << "or(true, false)+2"; 0257 QTest::newRow("argscount") << "f:=(x,y)->f(x)"; 0258 0259 QTest::newRow("twoargs") << "(x->x(3))((x,y)->x+y)"; 0260 QTest::newRow("times") << "x(x+1)"; 0261 QTest::newRow("unify") << "min(2, 3, list{})"; 0262 0263 //TODO: Add invalid recursive call 0264 } 0265 0266 Q_DECLARE_METATYPE(ExpressionType) 0267 0268 void TypeCheckTest::testReduction() 0269 { 0270 QFETCH(ExpressionType, type); 0271 QFETCH(ExpressionType, reduced); 0272 QFETCH(bool, correct); 0273 0274 QCOMPARE(type.canReduceTo(reduced), correct); 0275 } 0276 0277 ExpressionType s(int stars) { return ExpressionType(ExpressionType::Any, stars); } 0278 ExpressionType vec(const ExpressionType& c, int size) { return ExpressionType(ExpressionType::Vector, c, size); } 0279 ExpressionType list(const ExpressionType& c) { return ExpressionType(ExpressionType::List, c); } 0280 ExpressionType val=ExpressionType(ExpressionType::Value); 0281 0282 void TypeCheckTest::testReduction_data() 0283 { 0284 QTest::addColumn<ExpressionType>("type"); 0285 QTest::addColumn<ExpressionType>("reduced"); 0286 QTest::addColumn<bool>("correct"); 0287 0288 ExpressionType lambdaStarStar(ExpressionType::Lambda); // a -> a 0289 lambdaStarStar.addParameter(s(1)).addParameter(s(1)); 0290 0291 ExpressionType lambdaNumVector2(ExpressionType::Lambda); // num -> <num, 2> 0292 lambdaNumVector2.addParameter(val).addParameter(vec(val, 2)); 0293 0294 QTest::newRow("sss") << lambdaStarStar << lambdaNumVector2 << false; 0295 } 0296 0297 class FooCommand : public Analitza::FunctionDefinition 0298 { 0299 virtual Expression operator()(const QList< Expression >&) override 0300 { 0301 return Expression(QStringLiteral("matrix { matrixrow { 8, 9, 0},matrixrow { 7, 5, 3},matrixrow { 1, 2, 10}}")); 0302 } 0303 }; 0304 0305 void TypeCheckTest::testVariadic() 0306 { 0307 QFETCH(QString, expression); 0308 QFETCH(ExpressionType, type); 0309 0310 Analyzer a(v); 0311 a.builtinMethods()->insertFunction(QStringLiteral("foocommand"), type, new FooCommand); 0312 0313 a.setExpression(Expression(expression)); 0314 0315 if (a.type() != type.returnValue()) 0316 qDebug() << a.type().toString() << type.toString(); 0317 QCOMPARE(a.type(), type.returnValue()); 0318 0319 if(!a.isCorrect()) 0320 qDebug() << "wrong exp:" << a.errors(); 0321 QVERIFY(a.isCorrect()); 0322 0323 Expression result = a.calculate(); 0324 0325 if(!a.isCorrect() || !result.isCorrect()) 0326 qDebug() << "errors in calc:" << a.errors() << result.error(); 0327 QVERIFY(result.isCorrect()); 0328 } 0329 0330 void TypeCheckTest::testVariadic_data() 0331 { 0332 QTest::addColumn<QString>("expression"); 0333 QTest::addColumn<ExpressionType>("type"); 0334 0335 ExpressionType vtype = ExpressionType(ExpressionType::Lambda) 0336 .addParameter(ExpressionType(ExpressionType::Any)) 0337 .addParameter(ExpressionType(ExpressionType::Matrix, ExpressionType(ExpressionType::Vector, ExpressionType(ExpressionType::Value), -2), -1)); 0338 0339 QTest::newRow("f1type_alt_1param_ok") << "foocommand(3)" << vtype; 0340 QTest::newRow("f2type_alt_2params_ok") << "foocommand(3,44)" << vtype; 0341 QTest::newRow("f3type_alt_3params_ok") << "foocommand(list{5,6,2},44,vector{3,5})" << vtype; 0342 } 0343 0344 #include "moc_typechecktest.cpp"