diff --git a/src/backends/julia/testjulia.cpp b/src/backends/julia/testjulia.cpp index 4f379b00..ea6bc878 100644 --- a/src/backends/julia/testjulia.cpp +++ b/src/backends/julia/testjulia.cpp @@ -1,310 +1,310 @@ /* * 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. * * --- * Copyright (C) 2016 Ivan Lakhtanov */ #include "testjulia.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "textresult.h" #include "imageresult.h" #include "defaultvariablemodel.h" #include "completionobject.h" QString TestJulia::backendName() { return QLatin1String("julia"); } void TestJulia::testOneLine() { Cantor::Expression *e = evalExp(QLatin1String("2 + 3")); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Done); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QCOMPARE(e->result()->data().toString(), QLatin1String("5")); QVERIFY(e->errorMessage().isEmpty()); } void TestJulia::testOneLineWithPrint() { Cantor::Expression *e = evalExp(QLatin1String("print(2 + 3)")); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Done); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QCOMPARE(e->result()->data().toString(), QLatin1String("5")); QVERIFY(e->errorMessage().isEmpty()); } void TestJulia::testException() { Cantor::Expression *e = evalExp(QLatin1String("sqrt(-1)")); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Error); QVERIFY(e->result()); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QVERIFY( !e->errorMessage().isEmpty() && e->errorMessage().contains(QLatin1String( "sqrt will only return a complex result if called with a " "complex argument." )) ); } void TestJulia::testSyntaxError() { Cantor::Expression *e = evalExp(QLatin1String("for i = 1:10\nprint(i)")); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Error); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QVERIFY( !e->errorMessage().isEmpty() && e->errorMessage().contains(QLatin1String( "syntax: incomplete: \"for\" at none:1 requires end" )) ); } void TestJulia::testMultilineCode() { Cantor::Expression *e = evalExp(QLatin1String( "q = 0; # comment\n" "# sdfsdf\n" "for i = 1:10\n" " global q\n" " q += i\n" "end\n" "print(q)" )); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Done); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QCOMPARE(e->result()->data().toString(), QLatin1String("55")); QVERIFY(e->errorMessage().isEmpty()); } void TestJulia::testPartialResultOnException() { Cantor::Expression *e = evalExp(QLatin1String( "for i = 1:5\n" " print(i)\n" "end\n" "sqrt(-1)\n" )); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Error); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QCOMPARE(e->result()->data().toString(), QLatin1String("12345")); QVERIFY( !e->errorMessage().isEmpty() && e->errorMessage().contains(QLatin1String( "sqrt will only return a complex result if called with a " "complex argument." )) ); } void TestJulia::testInlinePlot() { Cantor::Expression *e = evalExp(QLatin1String( "import GR\n" "GR.plot([-1, -0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75, 1], sin)" )); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Done); QVERIFY(e->result()->type() == Cantor::ImageResult::Type); } void TestJulia::testInlinePlotWithExceptionAndPartialResult() { Cantor::Expression *e = evalExp(QLatin1String( "import GR\n" "print(\"gonna plot\")\n" "sqrt(-1)\n" "GR.plot([-1, -0.75, -0.5, -0.25, 0, 0.25, 0.5, 0.75, 1], sin)\n" )); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Error); QVERIFY(e->result()->type() == Cantor::TextResult::Type); QCOMPARE(e->result()->data().toString(), QLatin1String("gonna plot")); QVERIFY( !e->errorMessage().isEmpty() && e->errorMessage().contains(QLatin1String( "sqrt will only return a complex result if called with a " "complex argument." )) ); } void TestJulia::testAddVariablesFromCode() { evalExp(QLatin1String("a = 0; b = 1; c = 2; d = 3\n")); auto variableModel = session()->variableModel(); QStringList variableNames = QString::fromLatin1("a b c d").split(QLatin1String(" ")); for (int i = 0; i < variableNames.size(); i++) { QModelIndexList matchedVariables = variableModel->match( variableModel->index(0, 0), Qt::DisplayRole, QVariant::fromValue(variableNames[i]), -1, Qt::MatchExactly ); QCOMPARE(matchedVariables.size(), 1); auto match = matchedVariables[0]; auto valueIndex = variableModel->index(match.row(), match.column() + 1); QVERIFY( valueIndex.data(Qt::DisplayRole) == QVariant::fromValue(QString::number(i)) ); } } void TestJulia::testAddVariablesFromManager() { Cantor::DefaultVariableModel* variableModel = session()->variableModel(); QStringList variableNames = QString::fromLatin1("a b c d").split(QLatin1String(" ")); for (int i = 0; i < variableNames.size(); i++) { variableModel->addVariable(variableNames[i], QString::number(i)); QModelIndexList matchedVariables = variableModel->match( variableModel->index(0, 0), Qt::DisplayRole, QVariant::fromValue(variableNames[i]), -1, Qt::MatchExactly ); QCOMPARE(matchedVariables.size(), 1); auto match = matchedVariables[0]; auto valueIndex = variableModel->index(match.row(), match.column() + 1); QVERIFY( valueIndex.data(Qt::DisplayRole) == QVariant::fromValue(QString::number(i)) ); } } void TestJulia::testRemoveVariables() { Cantor::DefaultVariableModel* variableModel = session()->variableModel(); QStringList variableNames = QString::fromLatin1("a b c d").split(QLatin1String(" ")); for (int i = 0; i < variableNames.size(); i++) { variableModel->addVariable(variableNames[i], QString::number(i)); } for (int i = 0; i < variableNames.size(); i += 2) { variableModel->removeVariable(variableNames[i]); } for (int i = 0; i < variableNames.size(); i++) { QModelIndexList matchedVariables = variableModel->match( variableModel->index(0, 0), Qt::DisplayRole, QVariant::fromValue(variableNames[i]), -1, Qt::MatchExactly ); if (i % 2 == 0) { QVERIFY(matchedVariables.isEmpty()); } else { QCOMPARE(matchedVariables.size(), 1); auto match = matchedVariables[0]; auto valueIndex = variableModel->index(match.row(), match.column() + 1); QVERIFY( valueIndex.data(Qt::DisplayRole) == QVariant::fromValue(QString::number(i)) ); } } } void TestJulia::testAutoCompletion() { auto prefix = QLatin1String("ex"); auto completionObject = session()->completionFor(prefix); waitForSignal(completionObject, SIGNAL(fetchingDone())); auto completions = completionObject->completions(); QStringList completionsToCheck; completionsToCheck << QLatin1String("exit"); completionsToCheck << QLatin1String("exponent"); completionsToCheck << QLatin1String("exp"); for (auto completion : completionsToCheck) { QVERIFY(completions.contains(completion)); } for (auto completion : completions) { QVERIFY(completion.startsWith(prefix)); } } void TestJulia::testComplexAutocompletion() { auto prefix = QLatin1String("Base.Ma"); auto completionObject = session()->completionFor(prefix); waitForSignal(completionObject, SIGNAL(fetchingDone())); auto completions = completionObject->completions(); QStringList completionsToCheck; completionsToCheck << QLatin1String("Base.MainInclude"); completionsToCheck << QLatin1String("Base.Math"); completionsToCheck << QLatin1String("Base.Matrix"); for (auto completion : completionsToCheck) { QVERIFY(completions.contains(completion)); } for (auto completion : completions) { QVERIFY(completion.startsWith(prefix)); } } void TestJulia::testExpressionQueue() { Cantor::Expression* e1=session()->evaluateExpression(QLatin1String("0+1")); Cantor::Expression* e2=session()->evaluateExpression(QLatin1String("1+1")); QVERIFY(session()->status() == Cantor::Session::Running); Cantor::Expression* e3=evalExp(QLatin1String("1+2")); QVERIFY(e1!=nullptr); QVERIFY(e2!=nullptr); QVERIFY(e3!=nullptr); QVERIFY(e1->result()); QVERIFY(e2->result()); QVERIFY(e3->result()); - QCOMPARE(cleanOutput(e1->result()->toHtml()), QLatin1String("1")); - QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("2")); - QCOMPARE(cleanOutput(e3->result()->toHtml()), QLatin1String("3")); + QCOMPARE(cleanOutput(e1->result()->data().toString()), QLatin1String("1")); + QCOMPARE(cleanOutput(e2->result()->data().toString()), QLatin1String("2")); + QCOMPARE(cleanOutput(e3->result()->data().toString()), QLatin1String("3")); } QTEST_MAIN(TestJulia) diff --git a/src/backends/lua/testlua.cpp b/src/backends/lua/testlua.cpp index f7d6e3ca..e5e1d085 100644 --- a/src/backends/lua/testlua.cpp +++ b/src/backends/lua/testlua.cpp @@ -1,113 +1,113 @@ /* 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. --- Copyright (C) 2018 Nikita Sirgienko */ #include "testlua.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "imageresult.h" #include "epsresult.h" #include "luaexpression.h" #include QString TestLua::backendName() { return QLatin1String("lua"); } void TestLua::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("print(2+2)\n") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String("4") ); + QCOMPARE( cleanOutput( e->result()->data().toString() ), QLatin1String("4") ); } void TestLua::testMultilineCommand() { Cantor::Expression* e=evalExp( QLatin1String("print(4+4); print(2-1)") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput(e->result()->toHtml()), QLatin1String("8\n1") ); + QCOMPARE( cleanOutput(e->result()->data().toString()), QLatin1String("8\n1") ); } void TestLua::testVariableDefinition() { Cantor::Expression* e=evalExp( QLatin1String("num = 42; print(num)") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput(e->result()->toHtml()), QLatin1String("42") ); + QCOMPARE( cleanOutput(e->result()->data().toString()), QLatin1String("42") ); } void TestLua::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*+.") ); QVERIFY( e!=nullptr ); QCOMPARE( e->status(), Cantor::Expression::Error ); } void TestLua::testIfElseCondition() { QSKIP("Skip, until problem with multiline input for lua backends not will be solved"); QLatin1String cmd( "if 12 > 50 then" " print('true')" "else" " print('false')" "end"); Cantor::Expression* e=evalExp(cmd); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput(e->result()->toHtml()), QLatin1String("false") ); + QCOMPARE( cleanOutput(e->result()->data().toString()), QLatin1String("false") ); } void TestLua::testForLoop() { QSKIP("Skip, until problem with multiline input for lua backends not will be solved"); QLatin1String cmd( "karlSum = 0""\n" "for i = 1, 100 do""\n" " karlSum = karlSum + i""\n" "end""\n" "print(karlSum)"); Cantor::Expression* e=evalExp(cmd); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput(e->result()->toHtml()), QLatin1String("5050") ); + QCOMPARE( cleanOutput(e->result()->data().toString()), QLatin1String("5050") ); } QTEST_MAIN( TestLua ) diff --git a/src/backends/maxima/maximasyntaxhelpobject.cpp b/src/backends/maxima/maximasyntaxhelpobject.cpp index f9b6c831..3ff6c381 100644 --- a/src/backends/maxima/maximasyntaxhelpobject.cpp +++ b/src/backends/maxima/maximasyntaxhelpobject.cpp @@ -1,118 +1,118 @@ /* 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. --- Copyright (C) 2009-2012 Alexander Rieder */ #include "maximasyntaxhelpobject.h" #include "maximakeywords.h" #include "maximasession.h" #include "maximaexpression.h" #include "result.h" #include MaximaSyntaxHelpObject::MaximaSyntaxHelpObject(const QString& cmd, MaximaSession* session) : Cantor::SyntaxHelpObject(cmd, session) { m_expression=nullptr; } void MaximaSyntaxHelpObject::fetchInformation() { bool isValid=false; for (const QString& func : MaximaKeywords::instance()->functions()) { if(command()==func) { isValid=true; break; } } if(isValid) { if (session()->status() != Cantor::Session::Disable) { if (m_expression) return; //use the lisp command, instead of directly calling the //maxima function "describe" to avoid generating a new //output label that would mess up history QString cmd=QLatin1String(":lisp(cl-info::info-exact \"%1\")"); m_expression=session()->evaluateExpression(cmd.arg(command()), Cantor::Expression::FinishingBehavior::DoNotDelete, true); connect(m_expression, &Cantor::Expression::statusChanged, this, &MaximaSyntaxHelpObject::expressionChangedStatus); } else // We can't get function's detailed description, because session not login yet, so do nothing emit done(); }else { qDebug()<<"invalid syntax request"; emit done(); } } void MaximaSyntaxHelpObject::expressionChangedStatus(Cantor::Expression::Status status) { switch(status) { case Cantor::Expression::Done: { qDebug()<<"expr done"; - QString text=m_expression->result()->toHtml(); + QString text=m_expression->result()->data().toString(); QStringList lines=text.split(QLatin1Char('\n')); QString syntax; for (QString line : lines) { if(line.endsWith(QLatin1Char('\r'))) line.chop(1); if(line.startsWith(QLatin1String("-- Function:"))) { line.remove(QLatin1String("-- Function:")); line.remove(QLatin1String("
")); } syntax+=line; qDebug() << "line: " << line; } setHtml(QLatin1String("

")+syntax+QLatin1String("

")); emit done(); m_expression->deleteLater(); m_expression=nullptr; break; } case Cantor::Expression::Error: { qWarning() << "syntax object error" << m_expression->result()->toHtml(); emit done(); m_expression->deleteLater(); m_expression=nullptr; break; } default: break; } } diff --git a/src/backends/maxima/testmaxima.cpp b/src/backends/maxima/testmaxima.cpp index 73876ceb..6713ca83 100644 --- a/src/backends/maxima/testmaxima.cpp +++ b/src/backends/maxima/testmaxima.cpp @@ -1,297 +1,298 @@ /* 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. --- Copyright (C) 2009 Alexander Rieder */ #include "testmaxima.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" +#include "textresult.h" #include "imageresult.h" #include "epsresult.h" #include "syntaxhelpobject.h" #include "defaultvariablemodel.h" #include #include QString TestMaxima::backendName() { return QLatin1String("maxima"); } void TestMaxima::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String("4") ); + QCOMPARE( cleanOutput( e->result()->data().toString() ), QLatin1String("4") ); } void TestMaxima::testMultilineCommand() { Cantor::Expression* e = evalExp( QLatin1String("2+2;3+3") ); QVERIFY(e != nullptr); QVERIFY(e->results().size() == 2); - QString result = e->results().at(0)->toHtml(); - QCOMPARE(result, QLatin1String("4")); - - result = e->results().at(1)->toHtml(); - QCOMPARE(result, QLatin1String("6")); + QCOMPARE(e->results().at(0)->data().toString(), QLatin1String("4")); + QCOMPARE(e->results().at(1)->data().toString(), QLatin1String("6")); } //WARNING: for this test to work, Integration of Plots must be enabled //and CantorLib must be compiled with EPS-support void TestMaxima::testPlot() { if(QStandardPaths::findExecutable(QLatin1String("gnuplot")).isNull()) { QSKIP("gnuplot not found, maxima needs it for plotting", SkipSingle); } Cantor::Expression* e=evalExp( QLatin1String("plot2d(sin(x), [x, -10,10])") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); if(e->result()->type()!= Cantor::EpsResult::Type) { waitForSignal(e, SIGNAL(gotResult())); } #ifdef WITH_EPS QCOMPARE( e->result()->type(), (int)Cantor::EpsResult::Type ); #else QCOMPARE( e->result()->type(), (int)Cantor::ImageResult::Type ); #endif QVERIFY( !e->result()->data().isNull() ); QVERIFY( e->errorMessage().isNull() ); } void TestMaxima::testPlotWithAnotherTextResults() { if(QStandardPaths::findExecutable(QLatin1String("gnuplot")).isNull()) { QSKIP("gnuplot not found, maxima needs it for plotting", SkipSingle); } Cantor::Expression* e=evalExp( QLatin1String( "2*2; \n" "plot2d(sin(x), [x, -10,10]); \n" "4*4;" )); + if (e->results().at(1)->type() == Cantor::TextResult::Type) + waitForSignal(e, SIGNAL(resultReplaced)); + QVERIFY( e!=nullptr ); QVERIFY( e->errorMessage().isNull() ); QCOMPARE(e->results().size(), 3); - QCOMPARE(e->results()[0]->toHtml(), QLatin1String("4")); + QCOMPARE(e->results().at(0)->data().toString(), QLatin1String("4")); #ifdef WITH_EPS - QCOMPARE( e->results()[1]->type(), (int)Cantor::EpsResult::Type ); + QCOMPARE( e->results().at(1)->type(), (int)Cantor::EpsResult::Type ); #else - QCOMPARE( e->results()[1]->type(), (int)Cantor::ImageResult::Type ); + QCOMPARE( e->results().at(1)->type(), (int)Cantor::ImageResult::Type ); #endif - QVERIFY( !e->results()[1]->data().isNull() ); + QVERIFY( !e->results().at(1)->data().isNull() ); - QCOMPARE(e->results()[2]->toHtml(), QLatin1String("16")); + QCOMPARE(e->results().at(2)->data().toString(), QLatin1String("16")); } void TestMaxima::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*(") ); QVERIFY( e!=nullptr ); QVERIFY( e->status()==Cantor::Expression::Error ); } void TestMaxima::testExprNumbering() { Cantor::Expression* e=evalExp( QLatin1String("kill(labels)") ); //first reset the labels e=evalExp( QLatin1String("2+2") ); QVERIFY( e!=nullptr ); int id=e->id(); QCOMPARE( id, 1 ); e=evalExp( QString::fromLatin1("%o%1+1" ).arg( id ) ); QVERIFY( e != nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String( "5" ) ); + QCOMPARE( cleanOutput( e->result()->data().toString() ), QLatin1String( "5" ) ); } void TestMaxima::testCommandQueue() { //only wait for the last Expression to return, so the queue gets //actually filled Cantor::Expression* e1=session()->evaluateExpression(QLatin1String("0+1")); Cantor::Expression* e2=session()->evaluateExpression(QLatin1String("1+1")); Cantor::Expression* e3=evalExp(QLatin1String("1+2")); QVERIFY(e1!=nullptr); QVERIFY(e2!=nullptr); QVERIFY(e3!=nullptr); QVERIFY(e1->result()); QVERIFY(e2->result()); QVERIFY(e3->result()); - QCOMPARE(cleanOutput(e1->result()->toHtml()), QLatin1String("1")); - QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("2")); - QCOMPARE(cleanOutput(e3->result()->toHtml()), QLatin1String("3")); + QCOMPARE(cleanOutput(e1->result()->data().toString()), QLatin1String("1")); + QCOMPARE(cleanOutput(e2->result()->data().toString()), QLatin1String("2")); + QCOMPARE(cleanOutput(e3->result()->data().toString()), QLatin1String("3")); } void TestMaxima::testSimpleExpressionWithComment() { Cantor::Expression* e=evalExp(QLatin1String("/*this is a comment*/2+2")); QVERIFY(e!=nullptr); QVERIFY(e->result()!=nullptr); - QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("4")); + QCOMPARE(cleanOutput(e->result()->data().toString()), QLatin1String("4")); } void TestMaxima::testCommentExpression() { Cantor::Expression* e=evalExp(QLatin1String("/*this is a comment*/")); QVERIFY(e!=nullptr); - QVERIFY(e->result()==nullptr||e->result()->toHtml().isEmpty()); + QVERIFY(e->result()==nullptr||e->result()->data().toString().isEmpty()); } void TestMaxima::testNestedComment() { Cantor::Expression* e=evalExp(QLatin1String("/*/*this is still a comment*/*/2+2/*still/*a*/comment*//**/")); QVERIFY(e!=nullptr); QVERIFY(e->result()!=nullptr); - QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("4")); + QCOMPARE(cleanOutput(e->result()->data().toString()), QLatin1String("4")); } void TestMaxima::testUnmatchedComment() { Cantor::Expression* e=evalExp(QLatin1String("/*this comment doesn't end here!")); QVERIFY(e!=nullptr); QVERIFY(e->result()==nullptr); QVERIFY(e->status()==Cantor::Expression::Error); } void TestMaxima::testInvalidAssignment() { Cantor::Expression* e=evalExp(QLatin1String("0:a")); QVERIFY(e!=nullptr); //QVERIFY(e->result()==0); //QVERIFY(e->status()==Cantor::Expression::Error); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); //make sure we didn't screw up the session Cantor::Expression* e2=evalExp(QLatin1String("2+2")); QVERIFY(e2!=nullptr); QVERIFY(e2->result()!=nullptr); - QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("4")); + QCOMPARE(cleanOutput(e2->result()->data().toString()), QLatin1String("4")); } void TestMaxima::testInformationRequest() { Cantor::Expression* e=session()->evaluateExpression(QLatin1String("integrate(x^n,x)")); QVERIFY(e!=nullptr); waitForSignal(e, SIGNAL(needsAdditionalInformation(QString))); e->addInformation(QLatin1String("N")); waitForSignal(e, SIGNAL(statusChanged(Cantor::Expression::Status))); QVERIFY(e->result()!=nullptr); - QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("x^(n+1)/(n+1)")); + QCOMPARE(cleanOutput(e->result()->data().toString()), QLatin1String("x^(n+1)/(n+1)")); } void TestMaxima::testSyntaxHelp() { Cantor::SyntaxHelpObject* help = session()->syntaxHelpFor(QLatin1String("simplify_sum")); help->fetchSyntaxHelp(); waitForSignal(help, SIGNAL(done())); qWarning()<toHtml(); QVERIFY(help->toHtml().contains(QLatin1String("simplify_sum"))); } void TestMaxima::testHelpRequest() { //execute "??print" Cantor::Expression* e = session()->evaluateExpression(QLatin1String("??print")); QVERIFY(e != nullptr); //help result will be shown, but maxima still expects further input waitForSignal(e, SIGNAL(needsAdditionalInformation(QString))); QVERIFY(e->status() != Cantor::Expression::Done); //ask for help for the first flag of the print command e->addInformation(QLatin1String("0")); //no further input is required, we're done waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QVERIFY(e->status() == Cantor::Expression::Done); } void TestMaxima::testVariableModel() { QAbstractItemModel* model = session()->variableModel(); QVERIFY(model != nullptr); Cantor::Expression* e1=evalExp(QLatin1String("a: 15")); Cantor::Expression* e2=evalExp(QLatin1String("a: 15; b: \"Hello, world!\"")); Cantor::Expression* e3=evalExp(QLatin1String("l: [1,2,3]")); QVERIFY(e1!=nullptr); QVERIFY(e2!=nullptr); QVERIFY(e3!=nullptr); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QCOMPARE(3, model->rowCount()); QVariant name = model->index(0,0).data(); QCOMPARE(name.toString(),QLatin1String("a")); QVariant value = model->index(0,1).data(); QCOMPARE(value.toString(),QLatin1String("15")); QVariant name1 = model->index(1,0).data(); QCOMPARE(name1.toString(),QLatin1String("b")); QVariant value1 = model->index(1,1).data(); QCOMPARE(value1.toString(),QLatin1String("\"Hello, world!\"")); QVariant name2 = model->index(2,0).data(); QCOMPARE(name2.toString(),QLatin1String("l")); QVariant value2 = model->index(2,1).data(); QCOMPARE(value2.toString(),QLatin1String("[1,2,3]")); } QTEST_MAIN( TestMaxima ) diff --git a/src/backends/octave/octavecompletionobject.cpp b/src/backends/octave/octavecompletionobject.cpp index f42bf6c9..1092614c 100644 --- a/src/backends/octave/octavecompletionobject.cpp +++ b/src/backends/octave/octavecompletionobject.cpp @@ -1,164 +1,164 @@ /* Copyright (C) 2010 Miha Čančula 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 "octavecompletionobject.h" #include "octavekeywords.h" #include "session.h" #include "result.h" #include OctaveCompletionObject::OctaveCompletionObject(const QString& command, int index, Cantor::Session* parent): CompletionObject(parent) { setLine(command, index); m_expression = nullptr; } void OctaveCompletionObject::fetchCompletions() { if (session()->status() == Cantor::Session::Disable) { QStringList allCompletions; allCompletions << OctaveKeywords::instance()->functions(); allCompletions << OctaveKeywords::instance()->keywords(); setCompletions(allCompletions); emit fetchingDone(); } else { if (m_expression) return; qDebug() << "Fetching completions for" << command(); QString expr = QString::fromLatin1("completion_matches('%1')").arg(command()); m_expression = session()->evaluateExpression(expr,Cantor::Expression::FinishingBehavior::DoNotDelete, true); connect(m_expression, &Cantor::Expression::statusChanged, this, &OctaveCompletionObject::extractCompletions); } } void OctaveCompletionObject::extractCompletions(Cantor::Expression::Status status) { if (!m_expression) return; switch(status) { case Cantor::Expression::Done: { Cantor::Result* result = m_expression->result(); if (result) { - QString res = result->toHtml(); - QStringList completions = res.split(QLatin1String("
\n"), QString::SkipEmptyParts); + QString res = result->data().toString(); + QStringList completions = res.split(QLatin1String("\n"), QString::SkipEmptyParts); qDebug() << "Adding" << completions.size() << "completions"; setCompletions( completions ); } m_expression->deleteLater(); m_expression = nullptr; emit fetchingDone(); break; } case Cantor::Expression::Interrupted: case Cantor::Expression::Error: { qDebug() << "fetching expression finished with status" << (status == Cantor::Expression::Error? "Error" : "Interrupted"); m_expression->deleteLater(); m_expression=nullptr; emit fetchingDone(); break; } default: break; } } void OctaveCompletionObject::fetchIdentifierType() { if (session()->status() == Cantor::Session::Disable) { qDebug() << "Fetching type of " << identifier(); if (OctaveKeywords::instance()->keywords().contains(identifier())) emit fetchingTypeDone(KeywordType); else if (OctaveKeywords::instance()->functions().contains(identifier())) emit fetchingTypeDone(FunctionType); else emit fetchingTypeDone(UnknownType); } else { if (m_expression) return; qDebug() << "Fetching type of " << identifier(); QString expr = QString::fromLatin1("__cantor_tmp__ = [exist('%1'), iskeyword('%1')], clear __cantor_tmp__").arg(identifier()); m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); connect(m_expression, &Cantor::Expression::statusChanged, this, &OctaveCompletionObject::extractIdentifierType); } } void OctaveCompletionObject::extractIdentifierType(Cantor::Expression::Status status) { if (!m_expression) return; switch(status) { case Cantor::Expression::Error: qDebug() << "Error with OctaveCompletionObject" << m_expression->errorMessage(); emit fetchingTypeDone(UnknownType); break; case Cantor::Expression::Interrupted: qDebug() << "OctaveCompletionObject was interrupted"; emit fetchingTypeDone(UnknownType); break; case Cantor::Expression::Done: if (m_expression->result()) { QString res = m_expression->result()->data().toString(); // Remove '__cantor_tmp__ = \n' from result string // size("__cantor_tmp__ = \n") == 18 res.remove(0,18); const QStringList& ints = res.split(QLatin1String(" "), QString::SkipEmptyParts); if (ints.size() != 2) emit fetchingTypeDone(UnknownType); else if (ints[1].toInt() == 1) emit fetchingTypeDone(KeywordType); else if (ints[0].toInt() == 1) emit fetchingTypeDone(VariableType); else if (ints[0].toInt() == 5 || ints[0].toInt() == 103) emit fetchingTypeDone(FunctionType); else emit fetchingTypeDone(UnknownType); } break; default: return; } m_expression->deleteLater(); m_expression = nullptr; return; } diff --git a/src/backends/octave/octavesyntaxhelpobject.cpp b/src/backends/octave/octavesyntaxhelpobject.cpp index c74be188..0042b2cc 100644 --- a/src/backends/octave/octavesyntaxhelpobject.cpp +++ b/src/backends/octave/octavesyntaxhelpobject.cpp @@ -1,61 +1,61 @@ /* Copyright (C) 2010 Miha Čančula 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 "octavesyntaxhelpobject.h" #include "session.h" #include "result.h" #include OctaveSyntaxHelpObject::OctaveSyntaxHelpObject(const QString& command, Cantor::Session* session): SyntaxHelpObject(command, session), m_expression(nullptr) { } void OctaveSyntaxHelpObject::fetchInformation() { if (session()->status() != Cantor::Session::Disable) { qDebug() << "Fetching syntax help for" << command(); QString expr = QString::fromLatin1("help('%1')").arg(command()); m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); connect(m_expression, &Cantor::Expression::statusChanged, this, &OctaveSyntaxHelpObject::fetchingDone); } else emit done(); } void OctaveSyntaxHelpObject::fetchingDone() { if (!m_expression || m_expression->status() != Cantor::Expression::Done) { return; } Cantor::Result* result = m_expression->result(); if (result) { - QString res = result->toHtml(); - res.remove(QLatin1String("
")); - res.remove(0, res.indexOf(QLatin1String("--"))); - setHtml(QLatin1Char(' ') + res.trimmed()); + QString res = result->toHtml(); + res.remove(QLatin1String("
")); + res.remove(0, res.indexOf(QLatin1String("--"))); + setHtml(QLatin1Char(' ') + res.trimmed()); } m_expression->deleteLater(); emit done(); } diff --git a/src/backends/octave/testoctave.cpp b/src/backends/octave/testoctave.cpp index 5a975fec..491a3262 100644 --- a/src/backends/octave/testoctave.cpp +++ b/src/backends/octave/testoctave.cpp @@ -1,241 +1,241 @@ /* 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. --- Copyright (C) 2009 Alexander Rieder */ #include "testoctave.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "imageresult.h" #include "textresult.h" #include "epsresult.h" #include "completionobject.h" #include "defaultvariablemodel.h" #include "octaveexpression.h" #include QString TestOctave::backendName() { return QLatin1String("octave"); } void TestOctave::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( cleanOutput( e->result()->toHtml() ), QLatin1String("ans = 4") ); + QCOMPARE( cleanOutput( e->result()->data().toString() ), QLatin1String("ans = 4") ); } void TestOctave::testMultilineCommand() { Cantor::Expression* e=evalExp( QLatin1String("a = 2+2, b = 3+3") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QString result=e->result()->toHtml(); + QString result=e->result()->data().toString(); QCOMPARE( cleanOutput(result ), QLatin1String("a = 4\nb = 6") ); } void TestOctave::testCommandQueue() { Cantor::Expression* e1=session()->evaluateExpression(QLatin1String("0+1")); Cantor::Expression* e2=session()->evaluateExpression(QLatin1String("1+1")); Cantor::Expression* e3=evalExp(QLatin1String("1+2")); QVERIFY(e1!=nullptr); QVERIFY(e2!=nullptr); QVERIFY(e3!=nullptr); QVERIFY(e1->result()); QVERIFY(e2->result()); QVERIFY(e3->result()); - QCOMPARE(cleanOutput(e1->result()->toHtml()), QLatin1String("ans = 1")); - QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("ans = 2")); - QCOMPARE(cleanOutput(e3->result()->toHtml()), QLatin1String("ans = 3")); + QCOMPARE(cleanOutput(e1->result()->data().toString()), QLatin1String("ans = 1")); + QCOMPARE(cleanOutput(e2->result()->data().toString()), QLatin1String("ans = 2")); + QCOMPARE(cleanOutput(e3->result()->data().toString()), QLatin1String("ans = 3")); } void TestOctave::testVariableDefinition() { Cantor::Expression* e = evalExp(QLatin1String("testvar = 1")); QVERIFY(e != nullptr); QVERIFY(e->result() != nullptr); - QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("testvar = 1")); + QCOMPARE(cleanOutput(e->result()->data().toString()), QLatin1String("testvar = 1")); } void TestOctave::testMatrixDefinition() { Cantor::Expression* e = evalExp(QLatin1String( "M = [1, 2, 3;"\ " 4, 5, 6;"\ " 7, 8, 9;]" )); QVERIFY(e != nullptr); QVERIFY(e->result() != nullptr); QCOMPARE(e->result()->type(), (int) Cantor::TextResult::Type); Cantor::TextResult* result = static_cast(e->result()); QCOMPARE(result->plain(), QLatin1String( "M =\n"\ "\n" " 1 2 3\n"\ " 4 5 6\n"\ " 7 8 9" )); } void TestOctave::testSimpleExpressionWithComment() { Cantor::Expression* e = evalExp(QLatin1String("s = 1234 #This is comment")); QVERIFY(e != nullptr); QVERIFY(e->result() != nullptr); - QCOMPARE(cleanOutput(e->result()->toHtml()), QLatin1String("s = 1234")); + QCOMPARE(cleanOutput(e->result()->data().toString()), QLatin1String("s = 1234")); } void TestOctave::testCommentExpression() { Cantor::Expression* e = evalExp(QLatin1String("#Only comment")); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Status::Done); QCOMPARE(e->results().size(), 0); } void TestOctave::testMultilineCommandWithComment() { Cantor::Expression* e = evalExp(QLatin1String( "a = 2+4 \n" "6/2 % comment\n" "q = 'Str' # comment\n" "b = 4" )); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Status::Done); QVERIFY(e->result() != nullptr); Cantor::TextResult* result = static_cast(e->result()); QVERIFY(result != nullptr); QCOMPARE(cleanOutput(result->plain()), QLatin1String( "a = 6\n" "ans = 3\n" "q = Str\n" "b = 4" )); } void TestOctave::testCompletion() { Cantor::CompletionObject* help = session()->completionFor(QLatin1String("as"), 2); waitForSignal(help, SIGNAL(fetchingDone())); // Checks some completions for this request (but not all) // This correct for Octave 4.2.2 at least (and another versions, I think) const QStringList& completions = help->completions(); qDebug() << completions; QVERIFY(completions.contains(QLatin1String("asin"))); QVERIFY(completions.contains(QLatin1String("asctime"))); QVERIFY(completions.contains(QLatin1String("asec"))); QVERIFY(completions.contains(QLatin1String("assert"))); } void TestOctave::testVariablesCreatingFromCode() { QAbstractItemModel* model = session()->variableModel(); QVERIFY(model != nullptr); evalExp(QLatin1String("clear();")); Cantor::Expression* e=evalExp(QLatin1String("a = 15; b = 'S';")); QVERIFY(e!=nullptr); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QCOMPARE(2, model->rowCount()); QCOMPARE(model->index(0,0).data().toString(), QLatin1String("a")); QCOMPARE(model->index(0,1).data().toString(), QLatin1String(" 15")); QCOMPARE(model->index(1,0).data().toString(), QLatin1String("b")); QCOMPARE(model->index(1,1).data().toString(), QLatin1String("S")); } void TestOctave::testVariableCleanupAfterRestart() { Cantor::DefaultVariableModel* model = session()->variableModel(); QVERIFY(model != nullptr); evalExp(QLatin1String("clear();")); Cantor::Expression* e=evalExp(QLatin1String("a = 15; b = 'S';")); QVERIFY(e!=nullptr); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QCOMPARE(2, static_cast(model)->rowCount()); session()->logout(); session()->login(); QCOMPARE(0, static_cast(model)->rowCount()); } void TestOctave::testPlot() { Cantor::Expression* e=evalExp( QLatin1String("cantor_plot2d('sin(x)', 'x', -10,10);") ); int cnt=0; //give some time to create the image, but at most 5sec while(e->result()==nullptr||e->result()->type()!=OctavePlotResult::Type ) { QTest::qWait(250); cnt+=250; if(cnt>5000) break; } QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); QCOMPARE( e->result()->type(), (int) OctavePlotResult::Type ); QVERIFY( !e->result()->data().isNull() ); } void TestOctave::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*+.") ); QVERIFY( e!=nullptr ); QCOMPARE( e->status(), Cantor::Expression::Error ); } QTEST_MAIN( TestOctave ) diff --git a/src/backends/python/pythoncompletionobject.cpp b/src/backends/python/pythoncompletionobject.cpp index c08d1d90..388e36ad 100644 --- a/src/backends/python/pythoncompletionobject.cpp +++ b/src/backends/python/pythoncompletionobject.cpp @@ -1,170 +1,169 @@ /* 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. --- Copyright (C) 2013 Filipe Saraiva */ #include "pythoncompletionobject.h" #include #include "result.h" #include "pythonsession.h" #include "pythonkeywords.h" PythonCompletionObject::PythonCompletionObject(const QString& command, int index, PythonSession* session) : Cantor::CompletionObject(session), m_expression(nullptr) { setLine(command, index); } void PythonCompletionObject::fetchCompletions() { if (session()->status() == Cantor::Session::Disable) { QStringList allCompletions; allCompletions << PythonKeywords::instance()->variables(); allCompletions << PythonKeywords::instance()->functions(); allCompletions << PythonKeywords::instance()->keywords(); setCompletions(allCompletions); emit fetchingDone(); } else { if (m_expression) return; qDebug() << "run fetchCompletions"; const QString& expr = QString::fromLatin1( "from __main__ import __dict__;" "import rlcompleter;" "print('|'.join(rlcompleter.Completer(__dict__).global_matches('%1')+rlcompleter.Completer(__dict__).attr_matches('%1')))" ).arg(command()); m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); // TODO: Python exec the expression before connect, so manualy run handler. Uncomment the connection after removing DBus // connect(m_expression, &Cantor::Expression::statusChanged, this, &PythonCompletionObject::extractCompletions); extractCompletions(m_expression->status()); } } void PythonCompletionObject::fetchIdentifierType() { if (session()->status() == Cantor::Session::Disable) { if (qBinaryFind(PythonKeywords::instance()->functions().begin(), PythonKeywords::instance()->functions().end(), identifier()) != PythonKeywords::instance()->functions().end()) emit fetchingTypeDone(FunctionType); else if (qBinaryFind(PythonKeywords::instance()->keywords().begin(), PythonKeywords::instance()->keywords().end(), identifier()) != PythonKeywords::instance()->keywords().end()) emit fetchingTypeDone(KeywordType); else emit fetchingTypeDone(VariableType); } else { if (m_expression) return; const QString& expr = QString::fromLatin1("callable(%1)").arg(identifier()); m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); // TODO: Python exec the expression before connect, so manualy run handler. Uncomment the connection after removing DBus // connect(m_expression, &Cantor::Expression::statusChanged, this, &PythonCompletionObject::extractIdentifierType); extractIdentifierType(m_expression->status()); } } void PythonCompletionObject::extractCompletions(Cantor::Expression::Status status) { if (!m_expression) return; switch(status) { case Cantor::Expression::Error: qDebug() << "Error with PythonCompletionObject" << (m_expression->result() ? m_expression->result()->toHtml() : QLatin1String("extractCompletions")); break; case Cantor::Expression::Interrupted: qDebug() << "PythonCompletionObject was interrupted"; break; case Cantor::Expression::Done: if (m_expression->result()) - setCompletions(m_expression->result()->toHtml().remove(QLatin1Char('(')).split(QLatin1Char('|'))); + setCompletions(m_expression->result()->data().toString().remove(QLatin1Char('(')).split(QLatin1Char('|'))); break; default: return; } m_expression->deleteLater(); m_expression = nullptr; emit fetchingDone(); } void PythonCompletionObject::extractIdentifierType(Cantor::Expression::Status status) { if (!m_expression) return; switch(status) { case Cantor::Expression::Error: if (m_expression->errorMessage().contains(QLatin1String("SyntaxError: invalid syntax"))) emit fetchingTypeDone(KeywordType); else qDebug() << "Error with PythonCompletionObject" << (m_expression->result() ? m_expression->result()->toHtml() : QLatin1String("extractIdentifierType")); break; case Cantor::Expression::Interrupted: qDebug() << "PythonCompletionObject was interrupted"; break; case Cantor::Expression::Done: if (m_expression->result()) { - if (m_expression->result()) - { - if (m_expression->result()->toHtml() == QLatin1String("True")) - emit fetchingTypeDone(FunctionType); - else - emit fetchingTypeDone(VariableType); - } + if (m_expression->result()->data().toString() == QLatin1String("True")) + emit fetchingTypeDone(FunctionType); + else + emit fetchingTypeDone(VariableType); } + else + emit fetchingTypeDone(UnknownType); break; default: return; } m_expression->deleteLater(); m_expression = nullptr; } bool PythonCompletionObject::mayIdentifierContain(QChar c) const { return c.isLetter() || c.isDigit() || c == QLatin1Char('_') || c == QLatin1Char('%') || c == QLatin1Char('$') || c == QLatin1Char('.'); } bool PythonCompletionObject::mayIdentifierBeginWith(QChar c) const { return c.isLetter() || c == QLatin1Char('_') || c == QLatin1Char('%') || c == QLatin1Char('$'); } diff --git a/src/backends/python2/testpython2.cpp b/src/backends/python2/testpython2.cpp index 1488bebd..c9b024c2 100644 --- a/src/backends/python2/testpython2.cpp +++ b/src/backends/python2/testpython2.cpp @@ -1,151 +1,147 @@ /* 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. --- Copyright (C) 2013 Tuukka Verho */ #include "testpython2.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "defaultvariablemodel.h" QString TestPython2::backendName() { return QLatin1String("python2"); } void TestPython2::testImportNumpy() { Cantor::Expression* e = evalExp(QLatin1String("import numpy")); QVERIFY(e != nullptr); QCOMPARE(e->status(), Cantor::Expression::Done); } void TestPython2::testCodeWithComments() { { Cantor::Expression* e = evalExp(QLatin1String("#comment\n1+2")); QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } { Cantor::Expression* e = evalExp(QLatin1String(" #comment\n1+2")); QVERIFY(e != nullptr); QVERIFY(e->result()->data().toString() == QLatin1String("3")); } } void TestPython2::testSimpleCode() { Cantor::Expression* e=evalExp( QLatin1String("2+2")); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QString result=e->result()->toHtml(); - - QCOMPARE( cleanOutput(result ), QLatin1String("4") ); + QCOMPARE( cleanOutput(e->result()->data().toString()), QLatin1String("4") ); } void TestPython2::testMultilineCode() { Cantor::Expression* e=evalExp(QLatin1String( "a = 2+2\n" "b = 3+3\n" "print a,b" )); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QString result=e->result()->toHtml(); - - QCOMPARE( cleanOutput(result ), QLatin1String("4 6") ); + QCOMPARE( cleanOutput(e->result()->data().toString()), QLatin1String("4 6") ); evalExp(QLatin1String("del a; del b")); } void TestPython2::testVariablesCreatingFromCode() { QAbstractItemModel* model = session()->variableModel(); QVERIFY(model != nullptr); Cantor::Expression* e=evalExp(QLatin1String("a = 15; b = 'S';")); QVERIFY(e!=nullptr); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QCOMPARE(2, model->rowCount()); QCOMPARE(model->index(0,0).data().toString(), QLatin1String("a")); QCOMPARE(model->index(0,1).data().toString(), QLatin1String("15")); QCOMPARE(model->index(1,0).data().toString(), QLatin1String("b")); QCOMPARE(model->index(1,1).data().toString(), QLatin1String("'S'")); evalExp(QLatin1String("del a; del b")); } void TestPython2::testVariableCleanupAfterRestart() { Cantor::DefaultVariableModel* model = session()->variableModel(); QVERIFY(model != nullptr); Cantor::Expression* e=evalExp(QLatin1String("a = 15; b = 'S';")); QVERIFY(e!=nullptr); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QCOMPARE(2, static_cast(model)->rowCount()); session()->logout(); session()->login(); QCOMPARE(0, static_cast(model)->rowCount()); } void TestPython2::testDictVariable() { Cantor::DefaultVariableModel* model = session()->variableModel(); QVERIFY(model != nullptr); Cantor::Expression* e=evalExp(QLatin1String("d = {'value': 33}")); QVERIFY(e!=nullptr); if(session()->status()==Cantor::Session::Running) waitForSignal(session(), SIGNAL(statusChanged(Cantor::Session::Status))); QCOMPARE(1, static_cast(model)->rowCount()); QCOMPARE(model->index(0,0).data().toString(), QLatin1String("d")); QCOMPARE(model->index(0,1).data().toString(), QLatin1String("{'value': 33}")); evalExp(QLatin1String("del d")); } QTEST_MAIN(TestPython2) diff --git a/src/backends/sage/sagecompletionobject.cpp b/src/backends/sage/sagecompletionobject.cpp index 28e96d7e..fa16fe90 100644 --- a/src/backends/sage/sagecompletionobject.cpp +++ b/src/backends/sage/sagecompletionobject.cpp @@ -1,235 +1,234 @@ /* 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. --- Copyright (C) 2009 Alexander Rieder */ #include "sagecompletionobject.h" #include "sagesession.h" #include "sagekeywords.h" #include "textresult.h" #include #include SageCompletionObject::SageCompletionObject(const QString& command, int index, SageSession* session) : Cantor::CompletionObject(session) { setLine(command, index); m_expression=nullptr; } SageCompletionObject::~SageCompletionObject() { if(m_expression) { m_expression->interrupt(); m_expression->deleteLater(); } } void SageCompletionObject::fetchCompletions() { if (session()->status() == Cantor::Session::Disable) { QStringList allCompletions; allCompletions << SageKeywords::instance()->keywords(); allCompletions << SageKeywords::instance()->functions(); allCompletions << SageKeywords::instance()->variables(); setCompletions(allCompletions); emit fetchingDone(); } else { if (m_expression) return; //cache the value of the "_" variable into __hist_tmp__, so we can restore the previous result //after complete() was evaluated const QString& cmd = QLatin1String("__hist_tmp__=_; __CANTOR_IPYTHON_SHELL__.complete(\"")+command()+QLatin1String("\");_=__hist_tmp__"); m_expression=session()->evaluateExpression(cmd, Cantor::Expression::FinishingBehavior::DoNotDelete, true); connect(m_expression, &Cantor::Expression::gotResult, this, &SageCompletionObject::extractCompletions); } } void SageCompletionObject::extractCompletions() { SageSession* s=qobject_cast(session()); if(s&&s->sageVersion()result(); m_expression->deleteLater(); m_expression=nullptr; if(!res || !(res->type()==Cantor::TextResult::Type)) { qDebug()<<"something went wrong fetching tab completion"; fetchingDone(); return; } //the result looks like "['comp1', 'comp2']" parse it //for sage version 5.7 this looks like //('s1', ['comp1','comp2']) where s1 is the string we called complete with - QString txt=res->toHtml().trimmed(); - txt.remove(QLatin1String("
")); + QString txt=res->data().toString().trimmed(); txt=txt.mid(txt.indexOf(command())+command().length()+2).trimmed(); txt=txt.mid(1); //remove [ txt.chop(2); //remove ] qDebug()<<"completion string: "<keywords(); setCompletions(completions); emit fetchingDone(); } void SageCompletionObject::extractCompletionsLegacy() { Cantor::Result* res=m_expression->result(); m_expression->deleteLater(); m_expression=nullptr; if(!res || !(res->type()==Cantor::TextResult::Type)) { qDebug()<<"something went wrong fetching tab completion"; fetchingDone(); return; } //the result looks like "['comp1', 'comp2']" parse it - QString txt=res->toHtml().trimmed(); + QString txt=res->data().toString().trimmed(); txt=txt.mid(1); //remove [ txt.chop(1); //remove ] QStringList tmp=txt.split(QLatin1Char(',')); QStringList completions; foreach(QString c, tmp) // krazy:exclude=foreach { c=c.trimmed(); c.chop(1); completions<keywords(); setCompletions(completions); emit fetchingDone(); } void SageCompletionObject::fetchIdentifierType() { if (SageKeywords::instance()->keywords().contains(identifier())) { emit fetchingTypeDone(KeywordType); return; } if (session()->status() == Cantor::Session::Disable) { if (SageKeywords::instance()->functions().contains(identifier())) emit fetchingTypeDone(FunctionType); else if (SageKeywords::instance()->variables().contains(identifier())) emit fetchingTypeDone(VariableType); else emit fetchingTypeDone(UnknownType); } else { if (m_expression) return; QString expr = QString::fromLatin1("__cantor_internal__ = _; type(%1); _ = __cantor_internal__").arg(identifier()); m_expression = session()->evaluateExpression(expr, Cantor::Expression::FinishingBehavior::DoNotDelete, true); connect(m_expression, &Cantor::Expression::statusChanged, this, &SageCompletionObject::extractIdentifierType); } } void SageCompletionObject::extractIdentifierType(Cantor::Expression::Status status) { if (!m_expression) return; switch(status) { case Cantor::Expression::Error: qDebug() << "Error with SageCompletionObject" << m_expression->errorMessage(); emit fetchingTypeDone(UnknownType); break; case Cantor::Expression::Interrupted: qDebug() << "SageCompletionObject was interrupted"; emit fetchingTypeDone(UnknownType); break; case Cantor::Expression::Done: { Cantor::Result* result = m_expression->result(); if (result) { - QString res = result->toHtml(); + QString res = result->data().toString(); if (res.contains(QLatin1String("function")) || res.contains(QLatin1String("method"))) emit fetchingTypeDone(FunctionType); else emit fetchingTypeDone(VariableType); } else emit fetchingTypeDone(UnknownType); break; } default: return; } m_expression->deleteLater(); m_expression = nullptr; return; } bool SageCompletionObject::mayIdentifierContain(QChar c) const { return c.isLetter() || c.isDigit() || c == QLatin1Char('_') || c == QLatin1Char('.'); } bool SageCompletionObject::mayIdentifierBeginWith(QChar c) const { return c.isLetter() || c.isDigit() || c == QLatin1Char('_'); } diff --git a/src/backends/sage/testsage.cpp b/src/backends/sage/testsage.cpp index 0bec6eac..0303bbee 100644 --- a/src/backends/sage/testsage.cpp +++ b/src/backends/sage/testsage.cpp @@ -1,124 +1,124 @@ /* 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. --- Copyright (C) 2009 Alexander Rieder */ #include "testsage.h" #include "session.h" #include "backend.h" #include "expression.h" #include "result.h" #include "imageresult.h" #include "textresult.h" #include QString TestSage::backendName() { return QLatin1String("sage"); } void TestSage::testSimpleCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( e->result()->toHtml(), QLatin1String(("4")) ); + QCOMPARE( e->result()->data().toString(), QLatin1String(("4")) ); } void TestSage::testCommandQueue() { //only wait for the last Expression to return, so the queue gets //actually filled Cantor::Expression* e1=session()->evaluateExpression(QLatin1String("0+1")); Cantor::Expression* e2=session()->evaluateExpression(QLatin1String("1+1")); Cantor::Expression* e3=evalExp(QLatin1String("1+2")); QVERIFY(e1!=nullptr); QVERIFY(e2!=nullptr); QVERIFY(e3!=nullptr); QVERIFY(e1->result()); QVERIFY(e2->result()); QVERIFY(e3->result()); - QCOMPARE(cleanOutput(e1->result()->toHtml()), QLatin1String("1")); - QCOMPARE(cleanOutput(e2->result()->toHtml()), QLatin1String("2")); - QCOMPARE(cleanOutput(e3->result()->toHtml()), QLatin1String("3")); + QCOMPARE(cleanOutput(e1->result()->data().toString()), QLatin1String("1")); + QCOMPARE(cleanOutput(e2->result()->data().toString()), QLatin1String("2")); + QCOMPARE(cleanOutput(e3->result()->data().toString()), QLatin1String("3")); } void TestSage::testMultilineCommand() { Cantor::Expression* e=evalExp( QLatin1String("2+2 \n simplify(1 - x + x)") ); QVERIFY( e!=nullptr ); QVERIFY( e->result()!=nullptr ); - QCOMPARE( e->result()->toHtml(), QLatin1String("4
\n1") ); + QCOMPARE( e->result()->data().toString(), QLatin1String("4\n1") ); } void TestSage::testDefineFunction() { const char* cmd="def func1(param) : \n" \ " return param*param\n\n"; Cantor::Expression* e1=evalExp( QLatin1String(cmd) ); QVERIFY( e1!=nullptr ); Cantor::Expression* e2=evalExp( QLatin1String("func1(2)") ); QVERIFY( e2!=nullptr ); QVERIFY( e2->result()!=nullptr ); - QCOMPARE( e2->result()->toHtml(), QLatin1String("4") ); + QCOMPARE( e2->result()->data().toString(), QLatin1String("4") ); } void TestSage::testPlot() { Cantor::Expression* e=evalExp( QLatin1String("plot(sin(x))") ); QVERIFY( e!=nullptr ); QCOMPARE( e->results().size(), 2); QVERIFY( e->results()[0]->type() == Cantor::TextResult::Type); QCOMPARE( e->results()[0]->data().toString(), QLatin1String("Launched png viewer for Graphics object consisting of 1 graphics primitive")); QVERIFY( e->results()[1]->type() == Cantor::ImageResult::Type); QVERIFY( !e->results()[1]->data().isNull() ); } void TestSage::testInvalidSyntax() { Cantor::Expression* e=evalExp( QLatin1String("2+2*(") ); QVERIFY( e!=nullptr ); QVERIFY( e->errorMessage()== QLatin1String("Syntax Error") ); } void TestSage::testNoOutput() { Cantor::Expression* e=evalExp( QLatin1String("f(x)=x^2+3*x+2\nf(0)") ); QVERIFY( e!=nullptr ); QVERIFY( e->result() != nullptr ); - QCOMPARE( e->result()->toHtml(), QLatin1String("2") ); + QCOMPARE( e->result()->data().toString(), QLatin1String("2") ); } QTEST_MAIN( TestSage )