diff options
| author | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2015-04-21 16:01:35 +0200 |
|---|---|---|
| committer | Nikolai Kosjar <nikolai.kosjar@theqtcompany.com> | 2015-04-29 12:21:32 +0000 |
| commit | ff5e71ba2156be591793992b3f53be551a92b2a2 (patch) | |
| tree | 92c7e141de0149a301122872ab833318427abe16 | |
| parent | 04a79dc7356e1c57ec29e3fc1a6c0957daa9437b (diff) | |
| download | qt-creator-ff5e71ba2156be591793992b3f53be551a92b2a2.tar.gz | |
Clang: Add ClangCodeCompletionTest
This is a high level test the basic completion code path.
Later we might merge clangcompletion_test.cpp into this.
Change-Id: Iee37179b4e8c3efa1ad629d04ab88fe823f96f51
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@theqtcompany.com>
12 files changed, 311 insertions, 3 deletions
diff --git a/src/plugins/clangcodemodel/clangcodemodel.pro b/src/plugins/clangcodemodel/clangcodemodel.pro index 0e90ca1921..bbd1ef53ea 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.pro +++ b/src/plugins/clangcodemodel/clangcodemodel.pro @@ -91,13 +91,16 @@ equals(TEST, 1) { $$PWD/test/clang_tests_database.qrc HEADERS += \ - $$PWD/test/completiontesthelper.h + $$PWD/test/completiontesthelper.h \ + $$PWD/test/clangcodecompletion_test.h SOURCES += \ $$PWD/test/completiontesthelper.cpp \ - $$PWD/test/clangcompletion_test.cpp + $$PWD/test/clangcompletion_test.cpp \ + $$PWD/test/clangcodecompletion_test.cpp DISTFILES += \ + $$PWD/test/globalCompletion.cpp \ $$PWD/test/cxx_regression_1.cpp \ $$PWD/test/cxx_regression_2.cpp \ $$PWD/test/cxx_regression_3.cpp \ diff --git a/src/plugins/clangcodemodel/clangcodemodel.qbs b/src/plugins/clangcodemodel/clangcodemodel.qbs index c0466e972b..6def352e54 100644 --- a/src/plugins/clangcodemodel/clangcodemodel.qbs +++ b/src/plugins/clangcodemodel/clangcodemodel.qbs @@ -120,6 +120,8 @@ QtcPlugin { prefix: "test/" files: [ "clang_tests_database.qrc", + "clangcodecompletion_test.cpp", + "clangcodecompletion_test.h", "clangcompletion_test.cpp", "completiontesthelper.cpp", "completiontesthelper.h", @@ -131,6 +133,7 @@ QtcPlugin { prefix: "test/" fileTags: "none" files: [ + "globalCompletion.cpp", "cxx_regression_1.cpp", "cxx_regression_2.cpp", "cxx_regression_3.cpp", diff --git a/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri b/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri index dea57152d0..d8ebbec2af 100644 --- a/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri +++ b/src/plugins/clangcodemodel/clangcodemodel_dependencies.pri @@ -5,3 +5,6 @@ QTC_PLUGIN_DEPENDS += \ coreplugin \ cpptools \ texteditor +QTC_TEST_DEPENDS += \ + cppeditor \ + qmakeprojectmanager diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp index 7028365e89..e214749f3f 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.cpp +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.cpp @@ -34,6 +34,10 @@ #include "pchmanager.h" #include "utils.h" +#ifdef WITH_TESTS +# include "test/clangcodecompletion_test.h" +#endif + #include <cpptools/cppmodelmanager.h> #include <projectexplorer/projectpanelfactory.h> @@ -84,5 +88,14 @@ void ClangCodeModelPlugin::extensionsInitialized() { } +#ifdef WITH_TESTS +QList<QObject *> ClangCodeModelPlugin::createTestObjects() const +{ + return QList<QObject *>() + << new Tests::ClangCodeCompletionTest + ; +} +#endif + } // namespace Internal } // namespace Clang diff --git a/src/plugins/clangcodemodel/clangcodemodelplugin.h b/src/plugins/clangcodemodel/clangcodemodelplugin.h index a30c328bea..d21963f2f1 100644 --- a/src/plugins/clangcodemodel/clangcodemodelplugin.h +++ b/src/plugins/clangcodemodel/clangcodemodelplugin.h @@ -60,6 +60,8 @@ private: #endif // CLANG_INDEXING #ifdef WITH_TESTS + QList<QObject *> createTestObjects() const; + private slots: void test_CXX_regressions(); void test_CXX_regressions_data(); diff --git a/src/plugins/clangcodemodel/clangcompletion.h b/src/plugins/clangcodemodel/clangcompletion.h index efdbbdc912..0449be0116 100644 --- a/src/plugins/clangcodemodel/clangcompletion.h +++ b/src/plugins/clangcodemodel/clangcompletion.h @@ -53,6 +53,8 @@ class ClangAssistProposalModel; class ClangCompletionAssistProvider : public CppTools::CppCompletionAssistProvider { + Q_OBJECT + public: ClangCompletionAssistProvider(); diff --git a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp index 84c0ec5995..ca34051cee 100644 --- a/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp +++ b/src/plugins/clangcodemodel/clangmodelmanagersupport.cpp @@ -28,6 +28,7 @@ ** ****************************************************************************/ +#include "constants.h" #include "clangcompletion.h" #include "clangeditordocumentprocessor.h" #include "clangmodelmanagersupport.h" @@ -48,7 +49,7 @@ ModelManagerSupport::~ModelManagerSupport() QString ModelManagerSupport::id() const { - return QLatin1String("ClangCodeMode.ClangCodeMode"); + return QLatin1String(Constants::CLANG_MODELMANAGERSUPPORT_ID); } QString ModelManagerSupport::displayName() const diff --git a/src/plugins/clangcodemodel/constants.h b/src/plugins/clangcodemodel/constants.h index f67f93f5f6..8bdb3f9b33 100644 --- a/src/plugins/clangcodemodel/constants.h +++ b/src/plugins/clangcodemodel/constants.h @@ -55,6 +55,8 @@ static const QLatin1Char kDoubleQuote('"'); static const QLatin1Char kNewLine('\n'); static const QLatin1Char kHorizontalTab('\t'); +const char CLANG_MODELMANAGERSUPPORT_ID[] = "ClangCodeMode.ClangCodeMode"; + } } diff --git a/src/plugins/clangcodemodel/test/clang_tests_database.qrc b/src/plugins/clangcodemodel/test/clang_tests_database.qrc index 0014d36087..77c34581d5 100644 --- a/src/plugins/clangcodemodel/test/clang_tests_database.qrc +++ b/src/plugins/clangcodemodel/test/clang_tests_database.qrc @@ -16,5 +16,6 @@ <file>objc_messages_1.mm</file> <file>objc_messages_2.mm</file> <file>objc_messages_3.mm</file> + <file>globalCompletion.cpp</file> </qresource> </RCC> diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp new file mode 100644 index 0000000000..9bae78dd9f --- /dev/null +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.cpp @@ -0,0 +1,207 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#include "clangcodecompletion_test.h" + +#include <clangcodemodel/clangcompletion.h> +#include <clangcodemodel/constants.h> + +#include <coreplugin/editormanager/editormanager.h> +#include <coreplugin/editormanager/ieditor.h> +#include <cpptools/cppcodemodelsettings.h> +#include <cpptools/cpptoolsconstants.h> +#include <cpptools/cpptoolsreuse.h> +#include <cpptools/cpptoolstestcase.h> +#include <texteditor/codeassist/assistinterface.h> +#include <texteditor/codeassist/completionassistprovider.h> +#include <texteditor/codeassist/iassistprocessor.h> +#include <texteditor/codeassist/iassistproposal.h> +#include <texteditor/codeassist/iassistproposalmodel.h> +#include <texteditor/textdocument.h> +#include <texteditor/texteditor.h> + +#include <utils/executeondestruction.h> +#include <utils/qtcassert.h> + +#include <QDebug> +#include <QtTest> + +namespace { + +QStringList completionResults(TextEditor::BaseTextEditor *textEditor) +{ + using namespace TextEditor; + using namespace ClangCodeModel::Internal; + + QStringList results; + + TextEditorWidget *textEditorWidget = qobject_cast<TextEditorWidget *>(textEditor->widget()); + QTC_ASSERT(textEditorWidget, return results); + AssistInterface *assistInterface = textEditorWidget->createAssistInterface( + TextEditor::Completion, TextEditor::ExplicitlyInvoked); + QTC_ASSERT(assistInterface, return results); + CompletionAssistProvider *assistProvider + = textEditor->textDocument()->completionAssistProvider(); + QTC_ASSERT(qobject_cast<ClangCompletionAssistProvider *>(assistProvider), return results); + QTC_ASSERT(assistProvider, return results); + IAssistProcessor *processor = assistProvider->createProcessor(); + QTC_ASSERT(processor, return results); + IAssistProposal *assistProposal = processor->perform(assistInterface); + QTC_ASSERT(assistProposal, return results); + IAssistProposalModel *assistProposalModel = assistProposal->model(); + QTC_ASSERT(assistProposalModel, return results); + + for (int i = 0, size = assistProposalModel->size(); i < size; ++i) + results << assistProposalModel->text(i); + + return results; +} + +class TestDocument +{ +public: + TestDocument(const QString &fileName) + { + QTC_ASSERT(!fileName.isEmpty(), return); + const QResource resource(QLatin1String(":/unittests/ClangCodeModel/") + fileName); + QTC_ASSERT(resource.isValid(), return); + const QByteArray contents = QByteArray(reinterpret_cast<const char*>(resource.data()), + resource.size()); + m_cursorPosition = contents.indexOf(" // COMPLETE HERE"); + if (!contents.isEmpty() && m_cursorPosition > -1) + m_filePath = m_temporaryDir.createFile(fileName.toUtf8(), contents); + } + + bool isValid() const { return !m_filePath.isEmpty(); } + QString filePath() const { return m_filePath; } + int cursorPosition() const { return m_cursorPosition; } + +private: + QString m_filePath; + int m_cursorPosition; + CppTools::Tests::TemporaryDir m_temporaryDir; +}; + +class OpenEditorAtCursorPosition +{ +public: + OpenEditorAtCursorPosition(const QString &filePath, int cursorPosition); + ~OpenEditorAtCursorPosition(); + + bool succeeded() const { return m_editor; } + TextEditor::BaseTextEditor *editor() const { return m_editor; } + +private: + TextEditor::BaseTextEditor *m_editor; +}; + +OpenEditorAtCursorPosition::OpenEditorAtCursorPosition(const QString &filePath, int cursorPosition) +{ + Core::IEditor *coreEditor = Core::EditorManager::openEditor(filePath); + if ((m_editor = qobject_cast<TextEditor::BaseTextEditor *>(coreEditor))) + m_editor->setCursorPosition(cursorPosition); +} + +OpenEditorAtCursorPosition::~OpenEditorAtCursorPosition() +{ + if (m_editor) + Core::EditorManager::closeEditor(m_editor); +} + +} // anonymous namespace + +namespace ClangCodeModel { +namespace Internal { +namespace Tests { + +typedef QSharedPointer<CppTools::CppCodeModelSettings> CppCodeModelSettingsPtr; + +class ActivateClangModelManagerSupport +{ +public: + ActivateClangModelManagerSupport(CppCodeModelSettingsPtr codeModelSettings); + ~ActivateClangModelManagerSupport(); + +private: + ActivateClangModelManagerSupport(); + + CppCodeModelSettingsPtr m_codeModelSettings; + QHash<QString, QString> m_toRestore; +}; + +ActivateClangModelManagerSupport::ActivateClangModelManagerSupport( + CppCodeModelSettingsPtr codeModelSettings) + : m_codeModelSettings(codeModelSettings) +{ + QTC_CHECK(m_codeModelSettings); + const QString clangModelManagerSupportId + = QLatin1String(Constants::CLANG_MODELMANAGERSUPPORT_ID); + foreach (const QString &mimeType, CppTools::CppCodeModelSettings::supportedMimeTypes()) { + m_toRestore.insert(mimeType, m_codeModelSettings->modelManagerSupportId(mimeType)); + m_codeModelSettings->setModelManagerSupportId(mimeType, clangModelManagerSupportId); + } +} + +ActivateClangModelManagerSupport::~ActivateClangModelManagerSupport() +{ + QHash<QString, QString>::const_iterator i = m_toRestore.constBegin(); + for (; i != m_toRestore.end(); ++i) + m_codeModelSettings->setModelManagerSupportId(i.key(), i.value()); +} + +ClangCodeCompletionTest::ClangCodeCompletionTest() +{ +} + +ClangCodeCompletionTest::~ClangCodeCompletionTest() +{ +} + +void ClangCodeCompletionTest::initTestCase() +{ + m_activater.reset(new ActivateClangModelManagerSupport(CppTools::codeModelSettings())); +} + +void ClangCodeCompletionTest::testGlobalCompletion() +{ + TestDocument testDocument(QLatin1String("globalCompletion.cpp")); + QVERIFY(testDocument.isValid()); + OpenEditorAtCursorPosition openEditor(testDocument.filePath(), testDocument.cursorPosition()); + QVERIFY(openEditor.succeeded()); + + const QStringList theCompletionResults = completionResults(openEditor.editor()); + QVERIFY(theCompletionResults.contains(QLatin1String("globalVariable"))); + QVERIFY(theCompletionResults.contains(QLatin1String("globalFunction"))); + QVERIFY(theCompletionResults.contains(QLatin1String("GlobalClass"))); +} + +} // namespace Tests +} // namespace Internal +} // namespace ClangCodeModel diff --git a/src/plugins/clangcodemodel/test/clangcodecompletion_test.h b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h new file mode 100644 index 0000000000..f7c4953997 --- /dev/null +++ b/src/plugins/clangcodemodel/test/clangcodecompletion_test.h @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms and +** conditions see http://www.qt.io/terms-conditions. For further information +** use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +****************************************************************************/ + +#ifndef CLANGCODECOMPLETIONTEST_H +#define CLANGCODECOMPLETIONTEST_H + +#include <QObject> + +namespace ClangCodeModel { +namespace Internal { +namespace Tests { + +class ActivateClangModelManagerSupport; + +class ClangCodeCompletionTest : public QObject +{ + Q_OBJECT + +public: + ClangCodeCompletionTest(); + ~ClangCodeCompletionTest(); + +private slots: + void initTestCase(); + + void testGlobalCompletion(); + +private: + QScopedPointer<ActivateClangModelManagerSupport> m_activater; +}; + +} // namespace Tests +} // namespace Internal +} // namespace ClangCodeModel + +#endif // CLANGCODECOMPLETIONTEST_H diff --git a/src/plugins/clangcodemodel/test/globalCompletion.cpp b/src/plugins/clangcodemodel/test/globalCompletion.cpp new file mode 100644 index 0000000000..184c031cde --- /dev/null +++ b/src/plugins/clangcodemodel/test/globalCompletion.cpp @@ -0,0 +1,8 @@ +int globalVariable; +void globalFunction(); +class GlobalClass {}; + +void f() +{ + // COMPLETE HERE +} |
