Git commit 12391c96d33848010fe4ff9aaa59f919a3f3df4b by Kevin Funk. Committed on 30/06/2016 at 21:45. Pushed by kfunk into branch 'assistantpopup-ng'. Reinstantiate assistant unit tests CCMAIL: mail@svenbrauch.de M +6 -1 languages/clang/codegen/adaptsignatureassistant.cpp M +261 -192 languages/clang/tests/test_assistants.cpp M +7 -7 languages/clang/tests/test_assistants.h http://commits.kde.org/kdevelop/12391c96d33848010fe4ff9aaa59f919a3f3df4b diff --git a/languages/clang/codegen/adaptsignatureassistant.cpp b/language= s/clang/codegen/adaptsignatureassistant.cpp index 2083041..a403cb2 100644 --- a/languages/clang/codegen/adaptsignatureassistant.cpp +++ b/languages/clang/codegen/adaptsignatureassistant.cpp @@ -305,7 +305,12 @@ void AdaptSignatureAssistant::updateReady(const KDevel= op::IndexedString& documen emit actionsChanged(); } = -KTextEditor::Range AdaptSignatureAssistant::displayRange() const { +KTextEditor::Range AdaptSignatureAssistant::displayRange() const +{ + if (!m_document) { + return {}; + } + auto s =3D m_lastEditPosition; KTextEditor::Range ran =3D {s.line(), 0, s.line(), m_document->lineLen= gth(s.line())}; qDebug() << "display range:" << ran; diff --git a/languages/clang/tests/test_assistants.cpp b/languages/clang/te= sts/test_assistants.cpp index 7d54721..5b4d60f 100644 --- a/languages/clang/tests/test_assistants.cpp +++ b/languages/clang/tests/test_assistants.cpp @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include @@ -66,7 +67,7 @@ void TestAssistants::initTestCase() )); QVERIFY(qputenv("KDEV_DISABLE_PLUGINS", "kdevcppsupport")); QVERIFY(qputenv("KDEV_CLANG_DISPLAY_DIAGS", "1")); - AutoTestShell::init({QStringLiteral("kdevclangsupport")}); + AutoTestShell::init({QStringLiteral("kdevclangsupport"), QStringLitera= l("kdevproblemreporter")}); TestCore::initialize(); DUChain::self()->disablePersistentStorage(); Core::self()->languageController()->backgroundParser()->setDelay(0); @@ -229,7 +230,6 @@ struct StateChange Q_DECLARE_METATYPE(StateChange) Q_DECLARE_METATYPE(QList) = -/* void TestAssistants::testRenameAssistant_data() { QTest::addColumn("fileContents"); @@ -291,201 +291,259 @@ void TestAssistants::testRenameAssistant_data() << StateChange(Testbed::CppDoc, Range(0,17,0,17), "f", "abcdef= g") ) << "int foo(int abcdefg)\n { abcdefg =3D 0; return abcdefg; }"; -}*/ - -// void TestAssistants::testRenameAssistant() -// { -// QFETCH(QString, fileContents); -// Testbed testbed("", fileContents); -// -// QFETCH(QString, oldDeclarationName); -// QFETCH(QList, stateChanges); -// foreach(StateChange stateChange, stateChanges) -// { -// testbed.changeDocument(Testbed::CppDoc, stateChange.range, stat= eChange.newText); -// if (stateChange.result.isEmpty()) { -// QVERIFY(!staticAssistantsManager()->activeAssistant() || !s= taticAssistantsManager()->activeAssistant()->actions().size()); -// } else { -// QVERIFY(staticAssistantsManager()->activeAssistant() && sta= ticAssistantsManager()->activeAssistant()->actions().size()); -// RenameAction *r =3D qobject_cast(staticAssis= tantsManager()->activeAssistant()->actions().first().data()); -// QCOMPARE(r->oldDeclarationName(), oldDeclarationName); -// QCOMPARE(r->newDeclarationName(), stateChange.result); -// } -// } -// if (staticAssistantsManager()->activeAssistant() && staticAssistant= sManager()->activeAssistant()->actions().size()) { -// staticAssistantsManager()->activeAssistant()->actions().fir= st()->execute(); -// } -// QFETCH(QString, finalFileContents); -// QCOMPARE(testbed.documentText(Testbed::CppDoc), finalFileContents); -// } -// -// void TestAssistants::testRenameAssistantUndoRename() -// { -// Testbed testbed("", "int foo(int i)\n { i =3D 0; return i; }"); -// testbed.changeDocument(Testbed::CppDoc, Range(0,13,0,13), "d"); -// QVERIFY(staticAssistantsManager()->activeAssistant()); -// QVERIFY(staticAssistantsManager()->activeAssistant()->actions().siz= e() > 0); -// RenameAction *r =3D qobject_cast(staticAssistantsMan= ager()->activeAssistant()->actions().first().data()); -// QVERIFY(r); -// -// // now rename the variable back to its original identifier -// testbed.changeDocument(Testbed::CppDoc, Range(0,13,0,14), ""); -// // there should be no assistant anymore -// QVERIFY(!staticAssistantsManager()->activeAssistant()); -// } +} + +ProblemPointer findStaticAssistantProblem(const QList& pro= blems) +{ + const auto renameProblemIt =3D std::find_if(problems.cbegin(), problem= s.cend(), [](const ProblemPointer& p) { + return dynamic_cast(p.constData()); + }); + if (renameProblemIt !=3D problems.cend()) + return *renameProblemIt; + + return {}; +} + +void TestAssistants::testRenameAssistant() +{ + QFETCH(QString, fileContents); + Testbed testbed("", fileContents); + + const auto document =3D testbed.document(Testbed::CppDoc); + QVERIFY(document); + + QExplicitlySharedDataPointer assistant; + + QFETCH(QString, oldDeclarationName); + QFETCH(QList, stateChanges); + foreach(StateChange stateChange, stateChanges) + { + testbed.changeDocument(Testbed::CppDoc, stateChange.range, stateCh= ange.newText, true); + + DUChainReadLocker lock; + + auto topCtx =3D DUChain::self()->chainForDocument(document->url()); + QVERIFY(topCtx); + + const auto problem =3D findStaticAssistantProblem(topCtx->problems= ()); + if (problem) + assistant =3D problem->solutionAssistant(); + + if (stateChange.result.isEmpty()) { + QVERIFY(!assistant || !assistant->actions().size()); + } else { + QVERIFY(assistant && assistant->actions().size()); + RenameAction *r =3D qobject_cast(assistant->act= ions().first().data()); + QCOMPARE(r->oldDeclarationName(), oldDeclarationName); + QCOMPARE(r->newDeclarationName(), stateChange.result); + } + } + + if (assistant && assistant->actions().size()) { + assistant->actions().first()->execute(); + } + QFETCH(QString, finalFileContents); + QCOMPARE(testbed.documentText(Testbed::CppDoc), finalFileContents); +} + +void TestAssistants::testRenameAssistantUndoRename() +{ + Testbed testbed("", "int foo(int i)\n { i =3D 0; return i; }"); + testbed.changeDocument(Testbed::CppDoc, Range(0,13,0,13), "d", true); + + const auto document =3D testbed.document(Testbed::CppDoc); + QVERIFY(document); + + DUChainReadLocker lock; + auto topCtx =3D DUChain::self()->chainForDocument(document->url()); + QVERIFY(topCtx); + + auto firstProblem =3D findStaticAssistantProblem(topCtx->problems()); + auto assistant =3D firstProblem->solutionAssistant(); + QVERIFY(assistant); + + QVERIFY(assistant->actions().size() > 0); + RenameAction *r =3D qobject_cast(assistant->actions().f= irst().data()); + qWarning() << topCtx->problems() << assistant->actions().first().data(= ) << assistant->actions().size(); + QVERIFY(r); + + // now rename the variable back to its original identifier + testbed.changeDocument(Testbed::CppDoc, Range(0,13,0,14), ""); + // there should be no assistant anymore + QVERIFY(!assistant); +} = const QString SHOULD_ASSIST =3D "SHOULD_ASSIST"; //An assistant will be vi= sible const QString NO_ASSIST =3D "NO_ASSIST"; //No assistant visi= ble = -// void TestAssistants::testSignatureAssistant_data() -// { -// QTest::addColumn("headerContents"); -// QTest::addColumn("cppContents"); -// QTest::addColumn >("stateChanges"); -// QTest::addColumn("finalHeaderContents"); -// QTest::addColumn("finalCppContents"); -// -// QTest::newRow("change_argument_type") -// << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" -// << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new cha= r; return a + *b; }" -// << (QList() << StateChange(Testbed::HeaderDoc, Range= (1,8,1,11), "char", SHOULD_ASSIST)) -// << "class Foo {\nint bar(char a, char* b, int c =3D 10); \n};" -// << "int Foo::bar(char a, char* b, int c)\n{ a =3D c; b =3D new ch= ar; return a + *b; }"; -// -// QTest::newRow("prepend_arg_header") -// << "class Foo { void bar(int i); };" -// << "void Foo::bar(int i)\n{}" -// << (QList() << StateChange(Testbed::HeaderDoc, Range= (0, 21, 0, 21), "char c, ", SHOULD_ASSIST)) -// << "class Foo { void bar(char c, int i); };" -// << "void Foo::bar(char c, int i)\n{}"; -// -// QTest::newRow("prepend_arg_cpp") -// << "class Foo { void bar(int i); };" -// << "void Foo::bar(int i)\n{}" -// << (QList() << StateChange(Testbed::CppDoc, Range(0,= 14, 0, 14), "char c, ", SHOULD_ASSIST)) -// << "class Foo { void bar(char c, int i); };" -// << "void Foo::bar(char c, int i)\n{}"; -// -// QTest::newRow("change_default_parameter") -// << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" -// << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new c= har; return a + *b; }" -// << (QList() << StateChange(Testbed::HeaderDoc, Ran= ge(1,29,1,34), "", NO_ASSIST)) -// << "class Foo {\nint bar(int a, char* b, int c); \n};" -// << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new c= har; return a + *b; }"; -// -// QTest::newRow("change_function_type") -// << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" -// << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new c= har; return a + *b; }" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0,0,0,3), "char", SHOULD_ASSIST)) -// << "class Foo {\nchar bar(int a, char* b, int c =3D 10); \n};" -// << "char Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new = char; return a + *b; }"; -// -// QTest::newRow("swap_args_definition_side") -// << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" -// << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new c= har; return a + *b; }" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0,13,0,28), "char* b, int a,", SHOULD_ASSIST)) -// << "class Foo {\nint bar(char* b, int a, int c =3D 10); \n};" -// << "int Foo::bar(char* b, int a, int c)\n{ a =3D c; b =3D new c= har; return a + *b; }"; +void TestAssistants::testSignatureAssistant_data() +{ + QTest::addColumn("headerContents"); + QTest::addColumn("cppContents"); + QTest::addColumn >("stateChanges"); + QTest::addColumn("finalHeaderContents"); + QTest::addColumn("finalCppContents"); + + QTest::newRow("change_argument_type") + << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" + << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new char; = return a + *b; }" + << (QList() << StateChange(Testbed::HeaderDoc, Range(1,= 8,1,11), "char", SHOULD_ASSIST)) + << "class Foo {\nint bar(char a, char* b, int c =3D 10); \n};" + << "int Foo::bar(char a, char* b, int c)\n{ a =3D c; b =3D new char;= return a + *b; }"; + + QTest::newRow("prepend_arg_header") + << "class Foo { void bar(int i); };" + << "void Foo::bar(int i)\n{}" + << (QList() << StateChange(Testbed::HeaderDoc, Range(0,= 21, 0, 21), "char c, ", SHOULD_ASSIST)) + << "class Foo { void bar(char c, int i); };" + << "void Foo::bar(char c, int i)\n{}"; + + QTest::newRow("prepend_arg_cpp") + << "class Foo { void bar(int i); };" + << "void Foo::bar(int i)\n{}" + << (QList() << StateChange(Testbed::CppDoc, Range(0, 14= , 0, 14), "char c, ", SHOULD_ASSIST)) + << "class Foo { void bar(char c, int i); };" + << "void Foo::bar(char c, int i)\n{}"; + + QTest::newRow("change_default_parameter") + << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" + << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new char= ; return a + *b; }" + << (QList() << StateChange(Testbed::HeaderDoc, Range(= 1,29,1,34), "", NO_ASSIST)) + << "class Foo {\nint bar(int a, char* b, int c); \n};" + << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new char= ; return a + *b; }"; + + QTest::newRow("change_function_type") + << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" + << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new char= ; return a + *b; }" + << (QList() << StateChange(Testbed::CppDoc, Range(0,0= ,0,3), "char", SHOULD_ASSIST)) + << "class Foo {\nchar bar(int a, char* b, int c =3D 10); \n};" + << "char Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new cha= r; return a + *b; }"; + + QTest::newRow("swap_args_definition_side") + << "class Foo {\nint bar(int a, char* b, int c =3D 10); \n};" + << "int Foo::bar(int a, char* b, int c)\n{ a =3D c; b =3D new char= ; return a + *b; }" + << (QList() << StateChange(Testbed::CppDoc, Range(0,1= 3,0,28), "char* b, int a,", SHOULD_ASSIST)) + << "class Foo {\nint bar(char* b, int a, int c =3D 10); \n};" + << "int Foo::bar(char* b, int a, int c)\n{ a =3D c; b =3D new char= ; return a + *b; }"; = // see https://bugs.kde.org/show_bug.cgi?id=3D299393 // actually related to the whitespaces in the header... -// QTest::newRow("change_function_constness") -// << "class Foo {\nvoid bar(const Foo&) const;\n};" -// << "void Foo::bar(const Foo&) const\n{}" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0,25,0,31), "", SHOULD_ASSIST)) -// << "class Foo {\nvoid bar(const Foo&);\n};" -// << "void Foo::bar(const Foo&)\n{}"; -// -// // see https://bugs.kde.org/show_bug.cgi?id=3D356179 -// QTest::newRow("keep_static_cpp") -// << "class Foo { static void bar(int i); };" -// << "void Foo::bar(int i)\n{}" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0, 19, 0, 19), ", char c", SHOULD_ASSIST)) -// << "class Foo { static void bar(int i, char c); };" -// << "void Foo::bar(int i, char c)\n{}"; -// QTest::newRow("keep_static_header") -// << "class Foo { static void bar(int i); };" -// << "void Foo::bar(int i)\n{}" -// << (QList() << StateChange(Testbed::HeaderDoc, Ran= ge(0, 33, 0, 33), ", char c", SHOULD_ASSIST)) -// << "class Foo { static void bar(int i, char c); };" -// << "void Foo::bar(int i, char c)\n{}"; + QTest::newRow("change_function_constness") + << "class Foo {\nvoid bar(const Foo&) const;\n};" + << "void Foo::bar(const Foo&) const\n{}" + << (QList() << StateChange(Testbed::CppDoc, Range(0,2= 5,0,31), "", SHOULD_ASSIST)) + << "class Foo {\nvoid bar(const Foo&);\n};" + << "void Foo::bar(const Foo&)\n{}"; + + // see https://bugs.kde.org/show_bug.cgi?id=3D356179 + QTest::newRow("keep_static_cpp") + << "class Foo { static void bar(int i); };" + << "void Foo::bar(int i)\n{}" + << (QList() << StateChange(Testbed::CppDoc, Range(0, = 19, 0, 19), ", char c", SHOULD_ASSIST)) + << "class Foo { static void bar(int i, char c); };" + << "void Foo::bar(int i, char c)\n{}"; + QTest::newRow("keep_static_header") + << "class Foo { static void bar(int i); };" + << "void Foo::bar(int i)\n{}" + << (QList() << StateChange(Testbed::HeaderDoc, Range(= 0, 33, 0, 33), ", char c", SHOULD_ASSIST)) + << "class Foo { static void bar(int i, char c); };" + << "void Foo::bar(int i, char c)\n{}"; = // see https://bugs.kde.org/show_bug.cgi?id=3D356178 -// QTest::newRow("keep_default_args_cpp_before") -// << "class Foo { void bar(bool b, int i =3D 0); };" -// << "void Foo::bar(bool b, int i)\n{}" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0, 14, 0, 14), "char c, ", SHOULD_ASSIST)) -// << "class Foo { void bar(char c, bool b, int i =3D 0); };" -// << "void Foo::bar(char c, bool b, int i)\n{}"; -// QTest::newRow("keep_default_args_cpp_after") -// << "class Foo { void bar(bool b, int i =3D 0); };" -// << "void Foo::bar(bool b, int i)\n{}" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0, 27, 0, 27), ", char c", SHOULD_ASSIST)) -// << "class Foo { void bar(bool b, int i =3D 0, char c =3D {} /* = TODO */); };" -// << "void Foo::bar(bool b, int i, char c)\n{}"; -// QTest::newRow("keep_default_args_header_before") -// << "class Foo { void bar(bool b, int i =3D 0); };" -// << "void Foo::bar(bool b, int i)\n{}" -// << (QList() << StateChange(Testbed::HeaderDoc, Ran= ge(0, 29, 0, 29), "char c =3D 'A', ", SHOULD_ASSIST)) -// << "class Foo { void bar(bool b, char c =3D 'A', int i =3D 0); = };" -// << "void Foo::bar(bool b, char c, int i)\n{}"; -// QTest::newRow("keep_default_args_header_after") -// << "class Foo { void bar(bool b, int i =3D 0); };" -// << "void Foo::bar(bool b, int i)\n{}" -// << (QList() << StateChange(Testbed::HeaderDoc, Ran= ge(0, 38, 0, 38), ", char c =3D 'A'", SHOULD_ASSIST)) -// << "class Foo { void bar(bool b, int i =3D 0, char c =3D 'A'); = };" -// << "void Foo::bar(bool b, int i, char c)\n{}"; + QTest::newRow("keep_default_args_cpp_before") + << "class Foo { void bar(bool b, int i =3D 0); };" + << "void Foo::bar(bool b, int i)\n{}" + << (QList() << StateChange(Testbed::CppDoc, Range(0, = 14, 0, 14), "char c, ", SHOULD_ASSIST)) + << "class Foo { void bar(char c, bool b, int i =3D 0); };" + << "void Foo::bar(char c, bool b, int i)\n{}"; + QTest::newRow("keep_default_args_cpp_after") + << "class Foo { void bar(bool b, int i =3D 0); };" + << "void Foo::bar(bool b, int i)\n{}" + << (QList() << StateChange(Testbed::CppDoc, Range(0, = 27, 0, 27), ", char c", SHOULD_ASSIST)) + << "class Foo { void bar(bool b, int i =3D 0, char c =3D {} /* TOD= O */); };" + << "void Foo::bar(bool b, int i, char c)\n{}"; + QTest::newRow("keep_default_args_header_before") + << "class Foo { void bar(bool b, int i =3D 0); };" + << "void Foo::bar(bool b, int i)\n{}" + << (QList() << StateChange(Testbed::HeaderDoc, Range(= 0, 29, 0, 29), "char c =3D 'A', ", SHOULD_ASSIST)) + << "class Foo { void bar(bool b, char c =3D 'A', int i =3D 0); };" + << "void Foo::bar(bool b, char c, int i)\n{}"; + QTest::newRow("keep_default_args_header_after") + << "class Foo { void bar(bool b, int i =3D 0); };" + << "void Foo::bar(bool b, int i)\n{}" + << (QList() << StateChange(Testbed::HeaderDoc, Range(= 0, 38, 0, 38), ", char c =3D 'A'", SHOULD_ASSIST)) + << "class Foo { void bar(bool b, int i =3D 0, char c =3D 'A'); };" + << "void Foo::bar(bool b, int i, char c)\n{}"; = // see https://bugs.kde.org/show_bug.cgi?id=3D355356 -// QTest::newRow("no_retval_on_ctor") -// << "class Foo { Foo(); };" -// << "Foo::Foo()\n{}" -// << (QList() << StateChange(Testbed::HeaderDoc, Ran= ge(0, 16, 0, 16), "char c", SHOULD_ASSIST)) -// << "class Foo { Foo(char c); };" -// << "Foo::Foo(char c)\n{}"; -// -// // see https://bugs.kde.org/show_bug.cgi?id=3D298511 -// QTest::newRow("change_return_type_header") -// << "struct Foo { int bar(); };" -// << "int Foo::bar()\n{}" -// << (QList() << StateChange(Testbed::HeaderDoc, Ran= ge(0, 13, 0, 16), "char", SHOULD_ASSIST)) -// << "struct Foo { char bar(); };" -// << "char Foo::bar()\n{}"; -// QTest::newRow("change_return_type_impl") -// << "struct Foo { int bar(); };" -// << "int Foo::bar()\n{}" -// << (QList() << StateChange(Testbed::CppDoc, Range(= 0, 0, 0, 3), "char", SHOULD_ASSIST)) -// << "struct Foo { char bar(); };" -// << "char Foo::bar()\n{}"; -// } -// -// void TestAssistants::testSignatureAssistant() -// { -// QFETCH(QString, headerContents); -// QFETCH(QString, cppContents); -// Testbed testbed(headerContents, cppContents); -// -// QFETCH(QList, stateChanges); -// foreach (StateChange stateChange, stateChanges) -// { -// testbed.changeDocument(stateChange.document, stateChange.range,= stateChange.newText, true); -// -// if (stateChange.result =3D=3D SHOULD_ASSIST) { -// QEXPECT_FAIL("change_function_type", "Clang sees that retur= n type of out-of-line definition differs from that in the declaration and w= on't parse the code...", Abort); -// QEXPECT_FAIL("change_return_type_impl", "Clang sees that re= turn type of out-of-line definition differs from that in the declaration an= d won't include the function's AST and thus we never get updated about the = new return type...", Abort); -// QVERIFY(staticAssistantsManager()->activeAssistant() && !st= aticAssistantsManager()->activeAssistant()->actions().isEmpty()); -// } else { -// QVERIFY(!staticAssistantsManager()->activeAssistant() || st= aticAssistantsManager()->activeAssistant()->actions().isEmpty()); -// } -// } -// if (staticAssistantsManager()->activeAssistant() && !staticAssistan= tsManager()->activeAssistant()->actions().isEmpty()) -// staticAssistantsManager()->activeAssistant()->actions().first()= ->execute(); -// -// QFETCH(QString, finalHeaderContents); -// QFETCH(QString, finalCppContents); -// QCOMPARE(testbed.documentText(Testbed::HeaderDoc), finalHeaderConte= nts); -// QCOMPARE(testbed.documentText(Testbed::CppDoc), finalCppContents); -// } + QTest::newRow("no_retval_on_ctor") + << "class Foo { Foo(); };" + << "Foo::Foo()\n{}" + << (QList() << StateChange(Testbed::HeaderDoc, Range(= 0, 16, 0, 16), "char c", SHOULD_ASSIST)) + << "class Foo { Foo(char c); };" + << "Foo::Foo(char c)\n{}"; + + // see https://bugs.kde.org/show_bug.cgi?id=3D298511 + QTest::newRow("change_return_type_header") + << "struct Foo { int bar(); };" + << "int Foo::bar()\n{}" + << (QList() << StateChange(Testbed::HeaderDoc, Range(= 0, 13, 0, 16), "char", SHOULD_ASSIST)) + << "struct Foo { char bar(); };" + << "char Foo::bar()\n{}"; + QTest::newRow("change_return_type_impl") + << "struct Foo { int bar(); };" + << "int Foo::bar()\n{}" + << (QList() << StateChange(Testbed::CppDoc, Range(0, = 0, 0, 3), "char", SHOULD_ASSIST)) + << "struct Foo { char bar(); };" + << "char Foo::bar()\n{}"; +} + +void TestAssistants::testSignatureAssistant() +{ + QFETCH(QString, headerContents); + QFETCH(QString, cppContents); + Testbed testbed(headerContents, cppContents); + + QExplicitlySharedDataPointer assistant; + + QFETCH(QList, stateChanges); + foreach (StateChange stateChange, stateChanges) + { + testbed.changeDocument(stateChange.document, stateChange.range, st= ateChange.newText, true); + + const auto document =3D testbed.document(stateChange.document); + QVERIFY(document); + + DUChainReadLocker lock; + + auto topCtx =3D DUChain::self()->chainForDocument(document->url()); + QVERIFY(topCtx); + + const auto problem =3D findStaticAssistantProblem(topCtx->problems= ()); + if (problem) { + assistant =3D problem->solutionAssistant(); + } + + if (stateChange.result =3D=3D SHOULD_ASSIST) { + QEXPECT_FAIL("change_function_type", "Clang sees that return t= ype of out-of-line definition differs from that in the declaration and won'= t parse the code...", Abort); + QEXPECT_FAIL("change_return_type_impl", "Clang sees that retur= n type of out-of-line definition differs from that in the declaration and w= on't include the function's AST and thus we never get updated about the new= return type...", Abort); + QVERIFY(assistant && !assistant->actions().isEmpty()); + } else { + QVERIFY(!assistant || assistant->actions().isEmpty()); + } + } + + DUChainReadLocker lock; + + // FIXME: + if (assistant && !assistant->actions().isEmpty()) + assistant->actions().first()->execute(); + + QFETCH(QString, finalHeaderContents); + QFETCH(QString, finalCppContents); + QCOMPARE(testbed.documentText(Testbed::HeaderDoc), finalHeaderContents= ); + QCOMPARE(testbed.documentText(Testbed::CppDoc), finalCppContents); +} = enum UnknownDeclarationActions { @@ -495,7 +553,7 @@ enum UnknownDeclarationActions }; = Q_DECLARE_METATYPE(UnknownDeclarationActions) -/* + void TestAssistants::testUnknownDeclarationAssistant_data() { QTest::addColumn("headerContents"); @@ -520,16 +578,27 @@ void TestAssistants::testUnknownDeclarationAssistant() = static const auto cppContents =3D QStringLiteral("%1\nvoid f_u_n_c_t_i= _o_n() {\n}"); Testbed testbed(headerContents, cppContents.arg(globalText), Testbed::= NoAutoInclude); - const int line =3D testbed.document(Testbed::CppDoc)->lines() - 1; + const auto document =3D testbed.document(Testbed::CppDoc); + QVERIFY(document); + const int line =3D document->lines() - 1; testbed.changeDocument(Testbed::CppDoc, Range(line, 0, line, 0), funct= ionText, true); = + DUChainReadLocker lock; + + auto topCtx =3D DUChain::self()->chainForDocument(document->url()); + QVERIFY(topCtx); + + const auto problems =3D topCtx->problems(); + if (actions =3D=3D NoUnknownDeclaration) { - QVERIFY(!staticAssistantsManager()->activeAssistant()); + QVERIFY(!problems.isEmpty()); return; } = - QVERIFY(staticAssistantsManager()->activeAssistant()); - const auto assistantActions =3D staticAssistantsManager()->activeAssis= tant()->actions(); + auto firstProblem =3D problems.first(); + auto assistant =3D firstProblem->solutionAssistant(); + QVERIFY(assistant); + const auto assistantActions =3D assistant->actions(); QStringList actionDescriptions; for (auto action: assistantActions) { actionDescriptions << action->description(); @@ -550,7 +619,7 @@ void TestAssistants::testUnknownDeclarationAssistant() const bool hasMissingInclude =3D actionDescriptions.contains(descr= iption); QCOMPARE(hasMissingInclude, static_cast(actions & MissingInc= lude)); } -}*/ +} = void TestAssistants::testMoveIntoSource() { diff --git a/languages/clang/tests/test_assistants.h b/languages/clang/test= s/test_assistants.h index 9315e16..88cd679 100644 --- a/languages/clang/tests/test_assistants.h +++ b/languages/clang/tests/test_assistants.h @@ -29,13 +29,13 @@ private slots: void initTestCase(); void cleanupTestCase(); = -// void testRenameAssistant_data(); -// void testRenameAssistant(); -// void testRenameAssistantUndoRename(); -// void testSignatureAssistant_data(); -// void testSignatureAssistant(); -// void testUnknownDeclarationAssistant_data(); -// void testUnknownDeclarationAssistant(); + void testRenameAssistant_data(); + void testRenameAssistant(); + void testRenameAssistantUndoRename(); + void testSignatureAssistant_data(); + void testSignatureAssistant(); + void testUnknownDeclarationAssistant_data(); + void testUnknownDeclarationAssistant(); = void testMoveIntoSource_data(); void testMoveIntoSource();