From 098ddf11e8a59bd60eb350c56bc63f54f8338755 Mon Sep 17 00:00:00 2001 From: Christian Kandeler Date: Thu, 24 Aug 2023 14:12:32 +0200 Subject: [PATCH] CppEditor: Introduce testing infrastructure for symbol renaming Also add two example tests. Change-Id: Ia76c4d92e7643971c1f201081b3df1f77f1e89a5 Reviewed-by: Christian Stenger --- src/plugins/cppeditor/CMakeLists.txt | 1 + src/plugins/cppeditor/cppeditor.qbs | 2 + src/plugins/cppeditor/cppeditorplugin.cpp | 2 + src/plugins/cppeditor/cppfindreferences.cpp | 6 +- src/plugins/cppeditor/cppquickfix_test.h | 2 + src/plugins/cppeditor/cpprenaming_test.cpp | 146 ++++++++++++++++++++ src/plugins/cppeditor/cpprenaming_test.h | 19 +++ 7 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 src/plugins/cppeditor/cpprenaming_test.cpp create mode 100644 src/plugins/cppeditor/cpprenaming_test.h diff --git a/src/plugins/cppeditor/CMakeLists.txt b/src/plugins/cppeditor/CMakeLists.txt index 021bf0b7630..0c83b99b58f 100644 --- a/src/plugins/cppeditor/CMakeLists.txt +++ b/src/plugins/cppeditor/CMakeLists.txt @@ -129,6 +129,7 @@ extend_qtc_plugin(CppEditor cppmodelmanager_test.cpp cppmodelmanager_test.h cpppointerdeclarationformatter_test.cpp cpppointerdeclarationformatter_test.h cppquickfix_test.cpp cppquickfix_test.h + cpprenaming_test.cpp cpprenaming_test.h cppsourceprocessertesthelper.cpp cppsourceprocessertesthelper.h cppsourceprocessor_test.cpp cppsourceprocessor_test.h cpptoolstestcase.cpp cpptoolstestcase.h diff --git a/src/plugins/cppeditor/cppeditor.qbs b/src/plugins/cppeditor/cppeditor.qbs index 4e36279580a..2c0ff18dc30 100644 --- a/src/plugins/cppeditor/cppeditor.qbs +++ b/src/plugins/cppeditor/cppeditor.qbs @@ -265,6 +265,8 @@ QtcPlugin { "cpppointerdeclarationformatter_test.h", "cppquickfix_test.cpp", "cppquickfix_test.h", + "cpprenaming_test.cpp", + "cpprenaming_test.h", "cppsourceprocessor_test.cpp", "cppsourceprocessor_test.h", "cppsourceprocessertesthelper.cpp", diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index b1f69fbacf7..72d9eab85fd 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -42,6 +42,7 @@ #include "cppmodelmanager_test.h" #include "cpppointerdeclarationformatter_test.h" #include "cppquickfix_test.h" +#include "cpprenaming_test.h" #include "cppsourceprocessor_test.h" #include "cppuseselections_test.h" #include "fileandtokenactions_test.h" @@ -509,6 +510,7 @@ void CppEditorPlugin::initialize() addTest(); addTest(); addTest(); + addTest(); addTest(); #endif } diff --git a/src/plugins/cppeditor/cppfindreferences.cpp b/src/plugins/cppeditor/cppfindreferences.cpp index 78777021a7b..b933a0cde84 100644 --- a/src/plugins/cppeditor/cppfindreferences.cpp +++ b/src/plugins/cppeditor/cppfindreferences.cpp @@ -576,8 +576,10 @@ static void displayResults(SearchResult *search, item.setContainingFunctionName(result.containingFunction); item.setStyle(colorStyleForUsageType(result.tags)); item.setUseTextEditorFont(true); - if (search->supportsReplace()) - item.setSelectForReplacement(ProjectManager::projectForFile(result.path)); + if (search->supportsReplace()) { + item.setSelectForReplacement(!ProjectManager::hasProjects() + || ProjectManager::projectForFile(result.path)); + } search->addResult(item); if (parameters.prettySymbolName.isEmpty()) diff --git a/src/plugins/cppeditor/cppquickfix_test.h b/src/plugins/cppeditor/cppquickfix_test.h index ef1af4440b3..50dc29a213b 100644 --- a/src/plugins/cppeditor/cppquickfix_test.h +++ b/src/plugins/cppeditor/cppquickfix_test.h @@ -1,6 +1,8 @@ // Copyright (C) 2016 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 +#pragma once + #include "cppquickfix.h" #include "cpptoolstestcase.h" diff --git a/src/plugins/cppeditor/cpprenaming_test.cpp b/src/plugins/cppeditor/cpprenaming_test.cpp new file mode 100644 index 00000000000..d1b9a9891df --- /dev/null +++ b/src/plugins/cppeditor/cpprenaming_test.cpp @@ -0,0 +1,146 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#include "cpprenaming_test.h" + +#include "cppeditorwidget.h" +#include "cppmodelmanager.h" +#include "cppquickfix_test.h" + +#include + +#include +#include +#include + +namespace CppEditor::Internal::Tests { + +class RenamingTestRunner : public BaseQuickFixTestCase +{ +public: + RenamingTestRunner(const QList &testDocuments, const QString &replacement) + : BaseQuickFixTestCase(testDocuments, {}) + { + QVERIFY(succeededSoFar()); + const TestDocumentPtr &doc = m_documentWithMarker; + const CursorInEditor cursorInEditor(doc->m_editor->textCursor(), doc->filePath(), + doc->m_editorWidget, doc->m_editor->textDocument()); + + QEventLoop loop; + CppModelManager::globalRename(cursorInEditor, replacement, [&loop]{ loop.quit(); }); + QTimer::singleShot(10000, &loop, [&loop] { loop.exit(1); }); + QVERIFY(loop.exec() == 0); + + // Compare all files + for (const TestDocumentPtr &testDocument : std::as_const(m_testDocuments)) { + QString result = testDocument->m_editorWidget->document()->toPlainText(); + if (result != testDocument->m_expectedSource) { + qDebug() << "---" << testDocument->m_expectedSource; + qDebug() << "+++" << result; + } + QCOMPARE(result, testDocument->m_expectedSource); + + // Undo the change + for (int i = 0; i < 100; ++i) + testDocument->m_editorWidget->undo(); + result = testDocument->m_editorWidget->document()->toPlainText(); + QCOMPARE(result, testDocument->m_source); + } + } +}; + +void GlobalRenamingTest::test_data() +{ + QTest::addColumn("headers"); + QTest::addColumn("sources"); + QTest::addColumn("replacement"); + + const char testClassHeader[] = R"cpp( +/** + * \brief MyClass + */ +class MyClass { + /** \brief MyClass::MyClass */ + MyClass() {} + ~MyClass(); + /** \brief MyClass::run */ + void run(); +}; +)cpp"; + + const char testClassSource[] = R"cpp( +#include "file.h" +/** \brief MyClass::~MyClass */ +MyClass::~MyClass() {} + +void MyClass::run() {} +)cpp"; + + QByteArray origHeaderClassName(testClassHeader); + const int classOffset = origHeaderClassName.indexOf("class MyClass"); + QVERIFY(classOffset != -1); + origHeaderClassName.insert(classOffset + 6, '@'); + const QByteArray newHeaderClassName = R"cpp( +/** + * \brief MyClass + */ +class MyNewClass { + /** \brief MyClass::MyClass */ + MyNewClass() {} + ~MyNewClass(); + /** \brief MyClass::run */ + void run(); +}; +)cpp"; + const QByteArray newSourceClassName = R"cpp( +#include "file.h" +/** \brief MyClass::~MyClass */ +MyNewClass::~MyNewClass() {} + +void MyNewClass::run() {} +)cpp"; + QTest::newRow("class name") << QByteArrayList{origHeaderClassName, newHeaderClassName} + << QByteArrayList{testClassSource, newSourceClassName} + << QString("MyNewClass"); + + QByteArray origSourceMethodName(testClassSource); + const int methodOffset = origSourceMethodName.indexOf("::run()"); + QVERIFY(methodOffset != -1); + origSourceMethodName.insert(methodOffset + 2, '@'); + const QByteArray newHeaderMethodName = R"cpp( +/** + * \brief MyClass + */ +class MyClass { + /** \brief MyClass::MyClass */ + MyClass() {} + ~MyClass(); + /** \brief MyClass::run */ + void runAgain(); +}; +)cpp"; + const QByteArray newSourceMethodName = R"cpp( +#include "file.h" +/** \brief MyClass::~MyClass */ +MyClass::~MyClass() {} + +void MyClass::runAgain() {} +)cpp"; + QTest::newRow("method name") << QByteArrayList{testClassHeader, newHeaderMethodName} + << QByteArrayList{origSourceMethodName, newSourceMethodName} + << QString("runAgain"); +} + +void GlobalRenamingTest::test() +{ + QFETCH(QByteArrayList, headers); + QFETCH(QByteArrayList, sources); + QFETCH(QString, replacement); + + QList testDocuments( + {CppTestDocument::create("file.h", headers.at(0), headers.at(1)), + CppTestDocument::create("file.cpp", sources.at(0), sources.at(1))}); + RenamingTestRunner testRunner(testDocuments, replacement); +} + +} // namespace CppEditor::Internal::Tests diff --git a/src/plugins/cppeditor/cpprenaming_test.h b/src/plugins/cppeditor/cpprenaming_test.h new file mode 100644 index 00000000000..b7c651d306b --- /dev/null +++ b/src/plugins/cppeditor/cpprenaming_test.h @@ -0,0 +1,19 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + +#pragma once + +#include + +namespace CppEditor::Internal::Tests { + +class GlobalRenamingTest : public QObject +{ + Q_OBJECT + +private slots: + void test_data(); + void test(); +}; + +} // namespace CppEditor::Internal::Tests