File indexing completed on 2024-05-12 04:39:19

0001 /*
0002     SPDX-FileCopyrightText: 2017 Kevin Funk <kfunk@kde.org>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include "test_refactoring.h"
0008 
0009 #include <tests/testcore.h>
0010 #include <tests/autotestshell.h>
0011 #include <tests/testfile.h>
0012 #include <tests/testproject.h>
0013 #include <interfaces/ilanguagecontroller.h>
0014 
0015 #include "codegen/clangrefactoring.h"
0016 
0017 #include <language/duchain/duchainlock.h>
0018 #include <language/duchain/declaration.h>
0019 #include <language/interfaces/ilanguagesupport.h>
0020 
0021 #include <QTemporaryDir>
0022 #include <QLoggingCategory>
0023 #include <QTest>
0024 
0025 QTEST_MAIN(TestRefactoring)
0026 
0027 using namespace KDevelop;
0028 
0029 TestRefactoring::~TestRefactoring() = default;
0030 
0031 void TestRefactoring::initTestCase()
0032 {
0033     QLoggingCategory::setFilterRules(QStringLiteral("*.debug=false\ndefault.debug=true\nkdevelop.plugins.clang.debug=true\n"));
0034 
0035     QVERIFY(qputenv("KDEV_CLANG_DISPLAY_DIAGS", "1"));
0036 
0037     AutoTestShell::init({QStringLiteral("kdevclangsupport")});
0038 
0039     auto core = TestCore::initialize();
0040     delete core->projectController();
0041     m_projectController = new TestProjectController(core);
0042     core->setProjectController(m_projectController);
0043 }
0044 
0045 void TestRefactoring::cleanupTestCase()
0046 {
0047     TestCore::shutdown();
0048 }
0049 
0050 void TestRefactoring::testClassRename()
0051 {
0052     const QString codeBefore(QStringLiteral(R"(
0053 class Foo {
0054 public:
0055     Foo();
0056     ~Foo();
0057 };
0058 Foo::Foo() {
0059 }
0060 Foo::~Foo() {
0061 }
0062     )"));
0063 
0064     const QString codeAfter(QStringLiteral(R"(
0065 class FooNew {
0066 public:
0067     FooNew();
0068     ~FooNew();
0069 };
0070 FooNew::FooNew() {
0071 }
0072 FooNew::~FooNew() {
0073 }
0074     )"));
0075 
0076     QTemporaryDir dir;
0077     auto project = new TestProject(Path(dir.path()), this);
0078     m_projectController->addProject(project);
0079 
0080     TestFile file(codeBefore, QStringLiteral("cpp"), project, dir.path());
0081     QVERIFY(file.parseAndWait(TopDUContext::AllDeclarationsContextsAndUses));
0082 
0083     DUChainReadLocker lock;
0084 
0085     auto top = file.topContext();
0086     QVERIFY(top);
0087 
0088     auto declaration = top->localDeclarations().first();
0089     QVERIFY(declaration);
0090 
0091     const QString originalName = declaration->identifier().identifier().str();
0092     const QString newName = QStringLiteral("FooNew");
0093 
0094     QSharedPointer<BasicRefactoringCollector> collector(new BasicRefactoringCollector(declaration));
0095 
0096     // TODO: Do this without GUI?
0097     UsesWidget uses(declaration, collector);
0098     lock.unlock();
0099 
0100     for (int i = 0; i < 30000; i += 1000) {
0101         if (collector->isReady()) {
0102             break;
0103         }
0104         QTest::qWait(1000);
0105     }
0106     QVERIFY(collector->isReady());
0107 
0108     BasicRefactoring::NameAndCollector nameAndCollector{newName, collector};
0109 
0110     auto languages = ICore::self()->languageController()->languagesForUrl(file.url().toUrl());
0111     QVERIFY(!languages.isEmpty());
0112     auto clangLanguageSupport = languages.first();
0113     QVERIFY(clangLanguageSupport);
0114     auto clangRefactoring = qobject_cast<ClangRefactoring*>(clangLanguageSupport->refactoring());
0115     QVERIFY(clangRefactoring);
0116 
0117     clangRefactoring->renameCollectedDeclarations(nameAndCollector.collector.data(), newName, originalName);
0118     QCOMPARE(file.fileContents(), codeAfter);
0119 
0120     m_projectController->closeAllProjects();
0121 }
0122 
0123 #include "moc_test_refactoring.cpp"