From 8b86fe239bd67100984bc63d40e2ea38a08045ea Mon Sep 17 00:00:00 2001 From: hjk Date: Fri, 19 Jan 2024 13:32:14 +0100 Subject: [PATCH] ClangcodeModel: Move test creation closer to tested code Change-Id: Ifb6771673aa8639d2ee23d1f34b1ff821000e348 Reviewed-by: Jarek Kobus Reviewed-by: --- .../clangcodemodel/clangcodemodelplugin.cpp | 20 +- .../test/activationsequenceprocessortest.cpp | 38 ++- .../test/activationsequenceprocessortest.h | 31 +- .../clangcodemodel/test/clangdtests.cpp | 295 +++++++++++++++--- src/plugins/clangcodemodel/test/clangdtests.h | 204 +----------- .../clangcodemodel/test/clangfixittest.cpp | 36 ++- .../clangcodemodel/test/clangfixittest.h | 32 +- 7 files changed, 350 insertions(+), 306 deletions(-) diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 73c2f5d8caf..5a87aed0de2 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -86,16 +86,16 @@ void ClangCodeModelPlugin::initialize() updateStaleIndexEntries.addToContainer(CppEditor::Constants::M_CONTEXT); #ifdef WITH_TESTS - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); - addTest(); + addTestCreator(createActivationSequenceProcessorTest); + addTestCreator(createClangdTestCompletion); + addTestCreator(createClangdTestExternalChanges); + addTestCreator(createClangdTestFindReferences); + addTestCreator(createClangdTestFollowSymbol); + addTestCreator(createClangdTestHighlighting); + addTestCreator(createClangdTestIndirectChanges); + addTestCreator(createClangdTestLocalReferences); + addTestCreator(createClangdTestTooltips); + addTestCreator(createClangFixItTest); #endif } diff --git a/src/plugins/clangcodemodel/test/activationsequenceprocessortest.cpp b/src/plugins/clangcodemodel/test/activationsequenceprocessortest.cpp index 3ea86d85ff9..2b958dd858c 100644 --- a/src/plugins/clangcodemodel/test/activationsequenceprocessortest.cpp +++ b/src/plugins/clangcodemodel/test/activationsequenceprocessortest.cpp @@ -11,7 +11,7 @@ using namespace CPlusPlus; -namespace ClangCodeModel::Internal::Tests { +namespace ClangCodeModel::Internal { static bool resultIs(const ActivationSequenceProcessor &processor, Kind expectedKind, int expectedOffset, int expectedNewPos) @@ -21,6 +21,33 @@ static bool resultIs(const ActivationSequenceProcessor &processor, Kind expected && processor.operatorStartPosition() == expectedNewPos; } +class ActivationSequenceProcessorTest : public QObject +{ + Q_OBJECT + +private slots: + void testCouldNotProcesseRandomCharacters(); + void testCouldNotProcesseEmptyString(); + void testDot(); + void testComma(); + void testLeftParenAsFunctionCall(); + void testLeftParenNotAsFunctionCall(); + void testColonColon(); + void testArrow(); + void testDotStar(); + void testArrowStar(); + void testDoxyGenCommentBackSlash(); + void testDoxyGenCommentAt(); + void testAngleStringLiteral(); + void testStringLiteral(); + void testSlash(); + void testPound(); + void testPositionIsOne(); + void testPositionIsTwo(); + void testPositionIsTwoWithASingleSign(); + void testPositionIsThree(); +}; + void ActivationSequenceProcessorTest::testCouldNotProcesseRandomCharacters() { ActivationSequenceProcessor processor(QStringLiteral("xxx"), 3, false); @@ -155,4 +182,11 @@ void ActivationSequenceProcessorTest::testPositionIsThree() QVERIFY(resultIs(processor, T_ANGLE_STRING_LITERAL, 1, 2)); } -} // namespace ClangCodeModel::Internal::Tests +QObject *createActivationSequenceProcessorTest() +{ + return new ActivationSequenceProcessorTest; +} + +} // namespace ClangCodeModel::Internal + +#include "activationsequenceprocessortest.moc" diff --git a/src/plugins/clangcodemodel/test/activationsequenceprocessortest.h b/src/plugins/clangcodemodel/test/activationsequenceprocessortest.h index 63c9059b03a..1633e405e85 100644 --- a/src/plugins/clangcodemodel/test/activationsequenceprocessortest.h +++ b/src/plugins/clangcodemodel/test/activationsequenceprocessortest.h @@ -5,33 +5,8 @@ #include -namespace ClangCodeModel::Internal::Tests { +namespace ClangCodeModel::Internal { -class ActivationSequenceProcessorTest : public QObject -{ - Q_OBJECT +QObject *createActivationSequenceProcessorTest(); -private slots: - void testCouldNotProcesseRandomCharacters(); - void testCouldNotProcesseEmptyString(); - void testDot(); - void testComma(); - void testLeftParenAsFunctionCall(); - void testLeftParenNotAsFunctionCall(); - void testColonColon(); - void testArrow(); - void testDotStar(); - void testArrowStar(); - void testDoxyGenCommentBackSlash(); - void testDoxyGenCommentAt(); - void testAngleStringLiteral(); - void testStringLiteral(); - void testSlash(); - void testPound(); - void testPositionIsOne(); - void testPositionIsTwo(); - void testPositionIsTwoWithASingleSign(); - void testPositionIsThree(); -}; - -} // namespace ClangCodeModel::Internal::Tests +} // ClangCodeModel::Internal diff --git a/src/plugins/clangcodemodel/test/clangdtests.cpp b/src/plugins/clangcodemodel/test/clangdtests.cpp index 1919d5cfdb7..733951ba022 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.cpp +++ b/src/plugins/clangcodemodel/test/clangdtests.cpp @@ -8,25 +8,37 @@ #include "../clangmodelmanagersupport.h" #include + #include + #include #include #include #include #include + #include + #include #include #include #include + +#include + +#include #include +#include #include +#include #include + #include #include #include +#include +#include #include -#include #include #include @@ -47,22 +59,16 @@ using namespace ProjectExplorer; using namespace TextEditor; using namespace Utils; -namespace ClangCodeModel { -namespace Internal { -namespace Tests { +namespace ClangCodeModel::Internal { using Range = std::tuple; -} // namespace Tests -} // namespace Internal -} // namespace ClangCodeModel +} // namespace ClangCodeModel::Internal -Q_DECLARE_METATYPE(ClangCodeModel::Internal::Tests::Range) +Q_DECLARE_METATYPE(ClangCodeModel::Internal::Range) Q_DECLARE_METATYPE(IAssistProposal *) -namespace ClangCodeModel { -namespace Internal { -namespace Tests { +namespace ClangCodeModel::Internal { const Usage::Tags Initialization{Usage::Tag::Declaration, Usage::Tag::Write}; @@ -92,6 +98,42 @@ int timeOutInMs() return timeOut; } +class ClangdTest : public QObject +{ + Q_OBJECT + +public: + ~ClangdTest(); + +protected: + // Convention: base bame == name of parent dir + void setProjectFileName(const QString &fileName) { m_projectFileName = fileName; } + + void setSourceFileNames(const QStringList &fileNames) { m_sourceFileNames = fileNames; } + void setMinimumVersion(int version) { m_minVersion = version; } + + ClangdClient *client() const { return m_client; } + Utils::FilePath filePath(const QString &fileName) const; + TextEditor::TextDocument *document(const QString &fileName) const { + return m_sourceDocuments.value(fileName); + } + ProjectExplorer::Project *project() const { return m_project; } + void waitForNewClient(bool withIndex = true); + +protected slots: + virtual void initTestCase(); + +private: + CppEditor::Tests::TemporaryCopiedDir *m_projectDir = nullptr; + QString m_projectFileName; + QStringList m_sourceFileNames; + QHash m_sourceDocuments; + ProjectExplorer::Kit *m_kit = nullptr; + ProjectExplorer::Project *m_project = nullptr; + ClangdClient *m_client = nullptr; + int m_minVersion = -1; +}; + ClangdTest::~ClangdTest() { EditorManager::closeAllEditors(false); @@ -182,11 +224,26 @@ void ClangdTest::initTestCase() } } -ClangdTestFindReferences::ClangdTestFindReferences() +class ClangdTestFindReferences final : public ClangdTest { - setProjectFileName("find-usages.pro"); - setSourceFileNames({"defs.h", "main.cpp"}); -} + Q_OBJECT + +public: + ClangdTestFindReferences() + { + setProjectFileName("find-usages.pro"); + setSourceFileNames({"defs.h", "main.cpp"}); + } + +private slots: + void initTestCase() override; + void init() { m_actualResults.clear(); } + void test_data(); + void test(); + +private: + Utils::SearchResultItems m_actualResults; +}; void ClangdTestFindReferences::initTestCase() { @@ -333,11 +390,22 @@ void ClangdTestFindReferences::test() } -ClangdTestFollowSymbol::ClangdTestFollowSymbol() +class ClangdTestFollowSymbol final : public ClangdTest { - setProjectFileName("follow-symbol.pro"); - setSourceFileNames({"main.cpp", "header.h"}); -} + Q_OBJECT + +public: + ClangdTestFollowSymbol() + { + setProjectFileName("follow-symbol.pro"); + setSourceFileNames({"main.cpp", "header.h"}); + } + +private slots: + void test_data(); + void test(); + void testFollowSymbolInHandler(); +}; void ClangdTestFollowSymbol::test_data() { @@ -462,11 +530,21 @@ void ClangdTestFollowSymbol::testFollowSymbolInHandler() timer.stop(); } -ClangdTestLocalReferences::ClangdTestLocalReferences() +class ClangdTestLocalReferences final : public ClangdTest { - setProjectFileName("local-references.pro"); - setSourceFileNames({"references.cpp"}); -} + Q_OBJECT + +public: + ClangdTestLocalReferences() + { + setProjectFileName("local-references.pro"); + setSourceFileNames({"references.cpp"}); + } + +private slots: + void test_data(); + void test(); +}; // We currently only support local variables, but if and when clangd implements // the linkedEditingRange request, we can change the expected values for @@ -583,11 +661,22 @@ void ClangdTestLocalReferences::test() // This tests our help item construction, not the actual tooltip contents. Those come // pre-formatted from clangd. -ClangdTestTooltips::ClangdTestTooltips() + +class ClangdTestTooltips final : public ClangdTest { - setProjectFileName("tooltips.pro"); - setSourceFileNames({"tooltips.cpp"}); -} + Q_OBJECT + +public: + ClangdTestTooltips() + { + setProjectFileName("tooltips.pro"); + setSourceFileNames({"tooltips.cpp"}); + } + +private slots: + void test_data(); + void test(); +}; void ClangdTestTooltips::test_data() { @@ -718,11 +807,28 @@ void ClangdTestTooltips::test() QCOMPARE(helpItem.docMark(), expectedMark); } -ClangdTestHighlighting::ClangdTestHighlighting() + +class ClangdTestHighlighting final : public ClangdTest { - setProjectFileName("highlighting.pro"); - setSourceFileNames({"highlighting.cpp"}); -} + Q_OBJECT + +public: + ClangdTestHighlighting() + { + setProjectFileName("highlighting.pro"); + setSourceFileNames({"highlighting.cpp"}); + } + +private slots: + void initTestCase() override; + void test_data(); + void test(); + void testIfdefedOutBlocks(); + +private: + TextEditor::HighlightingResults m_results; + QList m_ifdefedOutBlocks; +}; void ClangdTestHighlighting::initTestCase() { @@ -1428,7 +1534,7 @@ void ClangdTestHighlighting::testIfdefedOutBlocks() } -class Manipulator : public TextDocumentManipulatorInterface +class Manipulator final : public TextDocumentManipulatorInterface { public: Manipulator() @@ -1497,6 +1603,56 @@ private: int m_skipPos = -1; }; + +class ClangdTestCompletion final : public ClangdTest +{ + Q_OBJECT + +public: + ClangdTestCompletion(); + +private slots: + void initTestCase() override; + + void testCompletePreprocessorKeywords(); + void testCompleteIncludeDirective(); + + void testCompleteGlobals(); + void testCompleteMembers(); + void testCompleteMembersFromInside(); + void testCompleteMembersFromOutside(); + void testCompleteMembersFromFriend(); + void testFunctionAddress(); + void testFunctionHints(); + void testFunctionHintsFiltered(); + void testFunctionHintConstructor(); + void testCompleteClassAndConstructor(); + void testCompletePrivateFunctionDefinition(); + + void testCompleteWithDotToArrowCorrection(); + void testDontCompleteWithDotToArrowCorrectionForFloats(); + + void testCompleteCodeInGeneratedUiFile(); + + void testSignalCompletion_data(); + void testSignalCompletion(); + + void testCompleteAfterProjectChange(); + +private: + void startCollectingHighlightingInfo(); + void getProposal(const QString &fileName, TextEditor::ProposalModelPtr &proposalModel, + const QString &insertString = {}, int *cursorPos = nullptr); + static bool hasItem(TextEditor::ProposalModelPtr model, const QString &text, + const QString &detail = {}); + static bool hasSnippet(TextEditor::ProposalModelPtr model, const QString &text); + static int itemsWithText(TextEditor::ProposalModelPtr model, const QString &text); + static TextEditor::AssistProposalItemInterface *getItem( + TextEditor::ProposalModelPtr model, const QString &text, const QString &detail = {}); + + QSet m_documentsWithHighlighting; +}; + ClangdTestCompletion::ClangdTestCompletion() { setProjectFileName("completion.pro"); @@ -2006,11 +2162,20 @@ AssistProposalItemInterface *ClangdTestCompletion::getItem( } -ClangdTestExternalChanges::ClangdTestExternalChanges() +class ClangdTestExternalChanges final : public ClangdTest { - setProjectFileName("completion.pro"); - setSourceFileNames({"mainwindow.cpp", "main.cpp"}); -} + Q_OBJECT + +public: + ClangdTestExternalChanges() + { + setProjectFileName("completion.pro"); + setSourceFileNames({"mainwindow.cpp", "main.cpp"}); + } + +private slots: + void test(); +}; void ClangdTestExternalChanges::test() { @@ -2053,6 +2218,18 @@ void ClangdTestExternalChanges::test() QVERIFY(waitForSignalOrTimeout(client(), &ClangdClient::textMarkCreated, timeOutInMs())); } + +class ClangdTestIndirectChanges final : public ClangdTest +{ + Q_OBJECT + +public: + ClangdTestIndirectChanges(); + +private slots: + void test(); +}; + ClangdTestIndirectChanges::ClangdTestIndirectChanges() { setProjectFileName("indirect-changes.pro"); @@ -2094,6 +2271,46 @@ void ClangdTestIndirectChanges::test() QVERIFY(src->marks().isEmpty()); } -} // namespace Tests -} // namespace Internal -} // namespace ClangCodeModel +QObject *createClangdTestCompletion() +{ + return new ClangdTestCompletion; +} + +QObject *createClangdTestExternalChanges() +{ + return new ClangdTestExternalChanges; +} + +QObject *createClangdTestFindReferences() +{ + return new ClangdTestFindReferences; +} + +QObject *createClangdTestFollowSymbol() +{ + return new ClangdTestFollowSymbol; +} + +QObject *createClangdTestHighlighting() +{ + return new ClangdTestHighlighting; +} + +QObject *createClangdTestIndirectChanges() +{ + return new ClangdTestIndirectChanges; +} + +QObject *createClangdTestLocalReferences() +{ + return new ClangdTestLocalReferences; +} + +QObject *createClangdTestTooltips() +{ + return new ClangdTestTooltips; +} + +} // namespace ClangCodeModel::Internal + +#include "clangdtests.moc" diff --git a/src/plugins/clangcodemodel/test/clangdtests.h b/src/plugins/clangcodemodel/test/clangdtests.h index b823c050e89..816b0c40429 100644 --- a/src/plugins/clangcodemodel/test/clangdtests.h +++ b/src/plugins/clangcodemodel/test/clangdtests.h @@ -3,202 +3,18 @@ #pragma once -#include -#include -#include -#include -#include -#include - -#include #include -#include -#include -namespace ProjectExplorer { -class Kit; -class Project; -} -namespace TextEditor { class TextDocument; } +namespace ClangCodeModel::Internal { -namespace ClangCodeModel { -namespace Internal { -class ClangdClient; -namespace Tests { +QObject *createClangdTestCompletion(); +QObject *createClangdTestExternalChanges(); +QObject *createClangdTestFindReferences(); +QObject *createClangdTestFollowSymbol(); +QObject *createClangdTestHighlighting(); +QObject *createClangdTestIndirectChanges(); +QObject *createClangdTestLocalReferences(); +QObject *createClangdTestTooltips(); -class ClangdTest : public QObject -{ - Q_OBJECT -public: - ~ClangdTest(); - -protected: - // Convention: base bame == name of parent dir - void setProjectFileName(const QString &fileName) { m_projectFileName = fileName; } - - void setSourceFileNames(const QStringList &fileNames) { m_sourceFileNames = fileNames; } - void setMinimumVersion(int version) { m_minVersion = version; } - - ClangdClient *client() const { return m_client; } - Utils::FilePath filePath(const QString &fileName) const; - TextEditor::TextDocument *document(const QString &fileName) const { - return m_sourceDocuments.value(fileName); - } - ProjectExplorer::Project *project() const { return m_project; } - void waitForNewClient(bool withIndex = true); - -protected slots: - virtual void initTestCase(); - -private: - CppEditor::Tests::TemporaryCopiedDir *m_projectDir = nullptr; - QString m_projectFileName; - QStringList m_sourceFileNames; - QHash m_sourceDocuments; - ProjectExplorer::Kit *m_kit = nullptr; - ProjectExplorer::Project *m_project = nullptr; - ClangdClient *m_client = nullptr; - int m_minVersion = -1; -}; - -class ClangdTestFindReferences : public ClangdTest -{ - Q_OBJECT -public: - ClangdTestFindReferences(); - -private slots: - void initTestCase() override; - void init() { m_actualResults.clear(); } - void test_data(); - void test(); - -private: - Utils::SearchResultItems m_actualResults; -}; - -class ClangdTestFollowSymbol : public ClangdTest -{ - Q_OBJECT -public: - ClangdTestFollowSymbol(); - -private slots: - void test_data(); - void test(); - void testFollowSymbolInHandler(); -}; - -class ClangdTestLocalReferences : public ClangdTest -{ - Q_OBJECT -public: - ClangdTestLocalReferences(); - -private slots: - void test_data(); - void test(); -}; - -class ClangdTestTooltips : public ClangdTest -{ - Q_OBJECT -public: - ClangdTestTooltips(); - -private slots: - void test_data(); - void test(); -}; - -class ClangdTestHighlighting : public ClangdTest -{ - Q_OBJECT -public: - ClangdTestHighlighting(); - -private slots: - void initTestCase() override; - void test_data(); - void test(); - void testIfdefedOutBlocks(); - -private: - TextEditor::HighlightingResults m_results; - QList m_ifdefedOutBlocks; -}; - -class ClangdTestCompletion : public ClangdTest -{ - Q_OBJECT -public: - ClangdTestCompletion(); - -private slots: - void initTestCase() override; - - void testCompletePreprocessorKeywords(); - void testCompleteIncludeDirective(); - - void testCompleteGlobals(); - void testCompleteMembers(); - void testCompleteMembersFromInside(); - void testCompleteMembersFromOutside(); - void testCompleteMembersFromFriend(); - void testFunctionAddress(); - void testFunctionHints(); - void testFunctionHintsFiltered(); - void testFunctionHintConstructor(); - void testCompleteClassAndConstructor(); - void testCompletePrivateFunctionDefinition(); - - void testCompleteWithDotToArrowCorrection(); - void testDontCompleteWithDotToArrowCorrectionForFloats(); - - void testCompleteCodeInGeneratedUiFile(); - - void testSignalCompletion_data(); - void testSignalCompletion(); - - void testCompleteAfterProjectChange(); - -private: - void startCollectingHighlightingInfo(); - void getProposal(const QString &fileName, TextEditor::ProposalModelPtr &proposalModel, - const QString &insertString = {}, int *cursorPos = nullptr); - static bool hasItem(TextEditor::ProposalModelPtr model, const QString &text, - const QString &detail = {}); - static bool hasSnippet(TextEditor::ProposalModelPtr model, const QString &text); - static int itemsWithText(TextEditor::ProposalModelPtr model, const QString &text); - static TextEditor::AssistProposalItemInterface *getItem( - TextEditor::ProposalModelPtr model, const QString &text, const QString &detail = {}); - - QSet m_documentsWithHighlighting; -}; - -class ClangdTestExternalChanges : public ClangdTest -{ - Q_OBJECT - -public: - ClangdTestExternalChanges(); - -private slots: - void test(); -}; - -class ClangdTestIndirectChanges : public ClangdTest -{ - Q_OBJECT - -public: - ClangdTestIndirectChanges(); - -private slots: - void test(); -}; - -} // namespace Tests -} // namespace Internal -} // namespace ClangCodeModel +} // ClangCodeModel::Internal diff --git a/src/plugins/clangcodemodel/test/clangfixittest.cpp b/src/plugins/clangcodemodel/test/clangfixittest.cpp index c41b9613b4d..fd344e01796 100644 --- a/src/plugins/clangcodemodel/test/clangfixittest.cpp +++ b/src/plugins/clangcodemodel/test/clangfixittest.cpp @@ -5,13 +5,38 @@ #include "../clangfixitoperation.h" +#include + #include #include +#include #include #include -namespace ClangCodeModel::Internal::Tests { +namespace ClangCodeModel::Internal { + +class ClangFixItTest final : public QObject +{ + Q_OBJECT + +private slots: + void init(); + void testAppendSemicolon(); + void testComparisonVersusAssignmentChooseComparison(); + void testComparisonVersusAssignmentChooseParentheses(); + void testDescription(); + +private: + Utils::FilePath semicolonFilePath() const; + Utils::FilePath compareFilePath() const; + QString fileContent(const QString &relFilePath) const; + + ClangFixIt semicolonFixIt() const; + +private: + QScopedPointer m_dataDir; +}; static QString qrcPath(const QString &relativeFilePath) { @@ -86,4 +111,11 @@ void ClangFixItTest::testComparisonVersusAssignmentChooseParentheses() fileContent("diagnostic_comparison_fixit_expected2.cpp")); } -} // namespace ClangCodeModel::Internal::Tests +QObject *createClangFixItTest() +{ + return new ClangFixItTest; +} + +} // ClangCodeModel::Internal + +#include "clangfixittest.moc" diff --git a/src/plugins/clangcodemodel/test/clangfixittest.h b/src/plugins/clangcodemodel/test/clangfixittest.h index 28cff4e0fe9..d11c863456c 100644 --- a/src/plugins/clangcodemodel/test/clangfixittest.h +++ b/src/plugins/clangcodemodel/test/clangfixittest.h @@ -3,40 +3,10 @@ #pragma once -#include - #include -#include -#include - -namespace Utils { class FilePath; } namespace ClangCodeModel::Internal { -class ClangFixIt; -namespace Tests { +QObject *createClangFixItTest(); -class ClangFixItTest : public QObject -{ - Q_OBJECT - -private slots: - void init(); - void testAppendSemicolon(); - void testComparisonVersusAssignmentChooseComparison(); - void testComparisonVersusAssignmentChooseParentheses(); - void testDescription(); - -private: - Utils::FilePath semicolonFilePath() const; - Utils::FilePath compareFilePath() const; - QString fileContent(const QString &relFilePath) const; - - ClangFixIt semicolonFixIt() const; - -private: - QScopedPointer m_dataDir; -}; - -} //namespace Tests } // namespace ClangCodeModel::Internal