diff options
author | Eike Ziller <eike.ziller@qt.io> | 2018-01-17 09:30:57 +0100 |
---|---|---|
committer | Eike Ziller <eike.ziller@qt.io> | 2018-01-17 09:30:57 +0100 |
commit | 115afed94b8e85db29b0c057e7c143a3d053d6cc (patch) | |
tree | 7663d95ed448c963ab8b913b675a78f0dea65fdc /tests | |
parent | 76bc20ffceadfff894dfd98a0285ae52577be3bf (diff) | |
parent | 2765409d2bdc79753f96bf6bb894b2884ac5b0cd (diff) |
Merge remote-tracking branch 'origin/4.6'
Conflicts:
tests/unit/unittest/gtest-creator-printing.cpp
tests/unit/unittest/gtest-creator-printing.h
Change-Id: I43d2571617bfbf41c0fcf23502ab77975540eba4
Diffstat (limited to 'tests')
-rw-r--r-- | tests/unit/echoserver/echoclangcodemodelserver.cpp | 5 | ||||
-rw-r--r-- | tests/unit/echoserver/echoclangcodemodelserver.h | 1 | ||||
-rw-r--r-- | tests/unit/unittest/clangtooltipinfo-test.cpp | 628 | ||||
-rw-r--r-- | tests/unit/unittest/conditionally-disabled-tests.h | 6 | ||||
-rw-r--r-- | tests/unit/unittest/data/tooltipinfo.cpp | 180 | ||||
-rw-r--r-- | tests/unit/unittest/data/tooltipinfo.h | 3 | ||||
-rw-r--r-- | tests/unit/unittest/dummyclangipcclient.h | 1 | ||||
-rw-r--r-- | tests/unit/unittest/gtest-creator-printing.cpp | 46 | ||||
-rw-r--r-- | tests/unit/unittest/gtest-creator-printing.h | 6 | ||||
-rw-r--r-- | tests/unit/unittest/mockclangcodemodelclient.h | 2 | ||||
-rw-r--r-- | tests/unit/unittest/mockclangcodemodelserver.h | 2 | ||||
-rw-r--r-- | tests/unit/unittest/unittest.pro | 1 | ||||
-rw-r--r-- | tests/unit/unittest/unsavedfile-test.cpp | 28 |
13 files changed, 908 insertions, 1 deletions
diff --git a/tests/unit/echoserver/echoclangcodemodelserver.cpp b/tests/unit/echoserver/echoclangcodemodelserver.cpp index 2c0fea98c9..38d2d39544 100644 --- a/tests/unit/echoserver/echoclangcodemodelserver.cpp +++ b/tests/unit/echoserver/echoclangcodemodelserver.cpp @@ -98,6 +98,11 @@ void EchoClangCodeModelServer::requestFollowSymbol(const RequestFollowSymbolMess echoMessage(message); } +void EchoClangCodeModelServer::requestToolTip(const RequestToolTipMessage &message) +{ + echoMessage(message); +} + void EchoClangCodeModelServer::updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) { echoMessage(message); diff --git a/tests/unit/echoserver/echoclangcodemodelserver.h b/tests/unit/echoserver/echoclangcodemodelserver.h index 2dc8c30913..d3452d2d32 100644 --- a/tests/unit/echoserver/echoclangcodemodelserver.h +++ b/tests/unit/echoserver/echoclangcodemodelserver.h @@ -47,6 +47,7 @@ public: void requestDocumentAnnotations(const RequestDocumentAnnotationsMessage &message) override; void requestReferences(const RequestReferencesMessage &message) override; void requestFollowSymbol(const RequestFollowSymbolMessage &message) override; + void requestToolTip(const RequestToolTipMessage &message) override; void updateVisibleTranslationUnits(const UpdateVisibleTranslationUnitsMessage &message) override; private: diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp new file mode 100644 index 0000000000..4f6c980649 --- /dev/null +++ b/tests/unit/unittest/clangtooltipinfo-test.cpp @@ -0,0 +1,628 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://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 https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "googletest.h" +#include "rundocumentparse-utility.h" + +#include <clangdocument.h> +#include <clangdocuments.h> +#include <clangsupport_global.h> +#include <clangtooltipinfocollector.h> +#include <clangtranslationunit.h> +#include <fixitcontainer.h> +#include <projectpart.h> +#include <projects.h> +#include <sourcelocationcontainer.h> +#include <sourcerangecontainer.h> +#include <unsavedfiles.h> + +#include <utils/qtcassert.h> + +#include <clang-c/Index.h> + +using ::ClangBackEnd::ProjectPart; +using ::ClangBackEnd::SourceLocationContainer; +using ::ClangBackEnd::Document; +using ::ClangBackEnd::UnsavedFiles; +using ::ClangBackEnd::ToolTipInfo; +using ::ClangBackEnd::SourceRangeContainer; + +namespace { + +#define CHECK_MEMBER(actual, expected, memberName) \ + if (actual.memberName() != expected.memberName()) { \ + *result_listener << #memberName " is " + PrintToString(actual.memberName()) \ + << " and not " + PrintToString(expected.memberName()); \ + return false; \ + } + +MATCHER_P(IsToolTip, expected, std::string(negation ? "isn't" : "is") + PrintToString(expected)) +{ + CHECK_MEMBER(arg, expected, text); + CHECK_MEMBER(arg, expected, briefComment); + + CHECK_MEMBER(arg, expected, qdocIdCandidates); + CHECK_MEMBER(arg, expected, qdocMark); + CHECK_MEMBER(arg, expected, qdocCategory); + + CHECK_MEMBER(arg, expected, sizeInBytes); + + return true; +} + +MATCHER_P(IsQdocToolTip, expected, std::string(negation ? "isn't" : "is") + PrintToString(expected)) +{ + CHECK_MEMBER(arg, expected, qdocIdCandidates); + CHECK_MEMBER(arg, expected, qdocMark); + CHECK_MEMBER(arg, expected, qdocCategory); + + return true; +} + +#undef CHECK_MEMBER + +struct Data { + ProjectPart projectPart{Utf8StringLiteral("projectPartId"), {Utf8StringLiteral("-std=c++14")}}; + ClangBackEnd::ProjectParts projects; + ClangBackEnd::UnsavedFiles unsavedFiles; + ClangBackEnd::Documents documents{projects, unsavedFiles}; + Document document{Utf8StringLiteral(TESTDATA_DIR "/tooltipinfo.cpp"), + projectPart, + {}, + documents}; + UnitTest::RunDocumentParse _1{document}; +}; + +class ToolTipInfo : public ::testing::Test +{ +protected: + ::ToolTipInfo tooltip(uint line, uint column) + { + return d->document.translationUnit().tooltip(d->unsavedFiles, + Utf8StringLiteral("UTF-8"), + line, + column); + } + + static void SetUpTestCase(); + static void TearDownTestCase(); + +private: + static std::unique_ptr<Data> d; +}; + +TEST_F(ToolTipInfo, LocalVariableInt) +{ + const ::ToolTipInfo actual = tooltip(3, 5); + + ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("int")))); +} + +TEST_F(ToolTipInfo, LocalVariablePointerToConstInt) +{ + const ::ToolTipInfo actual = tooltip(4, 5); + + ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("const int *")))); +} + +TEST_F(ToolTipInfo, LocalParameterVariableConstRefCustomType) +{ + ::ToolTipInfo expected(Utf8StringLiteral("const Foo &")); + expected.setQdocIdCandidates({Utf8StringLiteral("Foo")}); + expected.setQdocMark(Utf8StringLiteral("Foo")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(12, 12); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, LocalNonParameterVariableConstRefCustomType) +{ + ::ToolTipInfo expected(Utf8StringLiteral("const Foo")); + expected.setQdocIdCandidates({Utf8StringLiteral("Foo")}); + expected.setQdocMark(Utf8StringLiteral("Foo")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(14, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, MemberVariable) +{ + const ::ToolTipInfo actual = tooltip(12, 16); + + ASSERT_THAT(actual, IsToolTip(::ToolTipInfo(Utf8StringLiteral("int")))); +} + +TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_QualifiedName)) +{ + const ::ToolTipInfo actual = tooltip(21, 9); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("int Bar::mem()")); +} + +// ChangeLog: Show extra specifiers. For functions e.g.: virtual, inline, explicit, const, volatile +TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_ExtraSpecifiers)) +{ + const ::ToolTipInfo actual = tooltip(22, 9); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("virtual int Bar::virtualConstMem() const")); +} + +TEST_F(ToolTipInfo, MemberFunctionCall_qdocIdCandidates) +{ + const ::ToolTipInfo actual = tooltip(21, 9); + + ASSERT_THAT(actual.qdocIdCandidates(), ElementsAre(Utf8StringLiteral("Bar::mem"), + Utf8StringLiteral("mem"))); +} + +TEST_F(ToolTipInfo, MemberFunctionCall_qdocMark_FIXLIBCLANG_CHECKED) +{ + const ::ToolTipInfo actual = tooltip(21, 9); + + ASSERT_THAT(actual.qdocMark(), Utf8StringLiteral("mem()")); +} + +// TODO: Check what is really needed for qdoc before implementing this one. +TEST_F(ToolTipInfo, DISABLED_MemberFunctionCall_qdocMark_extraSpecifiers) +{ + const ::ToolTipInfo actual = tooltip(22, 9); + + ASSERT_THAT(actual.qdocMark(), Utf8StringLiteral("virtualConstMem() const")); +} + +TEST_F(ToolTipInfo, MemberFunctionCall_qdocCategory) +{ + const ::ToolTipInfo actual = tooltip(21, 9); + + ASSERT_THAT(actual.qdocCategory(), ::ToolTipInfo::Function); +} + +// TODO: Show the template parameter type, too: "template<typename T>...)" +TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(TemplateFunctionCall)) +{ + const ::ToolTipInfo actual = tooltip(30, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("template<> void t<Foo>(int foo)")); +} + +TEST_F(ToolTipInfo, TemplateFunctionCall_qdocIdCandidates) +{ + const ::ToolTipInfo actual = tooltip(30, 5); + + ASSERT_THAT(actual.qdocIdCandidates(), ElementsAre(Utf8StringLiteral("t"))); +} + +TEST_F(ToolTipInfo, TemplateFunctionCall_qdocMark_FIXLIBCLANG_CHECKED) +{ + const ::ToolTipInfo actual = tooltip(30, 5); + + ASSERT_THAT(actual.qdocMark(), Utf8StringLiteral("t(int)")); +} + +TEST_F(ToolTipInfo, TemplateFunctionCall_qdocCategory) +{ + const ::ToolTipInfo actual = tooltip(30, 5); + + ASSERT_THAT(actual.qdocCategory(), ::ToolTipInfo::Function); +} + +TEST_F(ToolTipInfo, BriefComment) +{ + const ::ToolTipInfo actual = tooltip(41, 5); + + ASSERT_THAT(actual.briefComment(), Utf8StringLiteral("This is a crazy function.")); +} + +TEST_F(ToolTipInfo, Enum) +{ + ::ToolTipInfo expected(Utf8StringLiteral("EnumType")); + expected.setQdocIdCandidates({Utf8StringLiteral("EnumType")}); + expected.setQdocMark(Utf8StringLiteral("EnumType")); + expected.setQdocCategory(::ToolTipInfo::Enum); + + const ::ToolTipInfo actual = tooltip(49, 12); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, Enumerator) +{ + ::ToolTipInfo expected(Utf8StringLiteral("6")); + expected.setQdocIdCandidates({Utf8StringLiteral("Custom")}); + expected.setQdocMark(Utf8StringLiteral("EnumType")); + expected.setQdocCategory(::ToolTipInfo::Enum); + + const ::ToolTipInfo actual = tooltip(49, 22); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, TemplateTypeFromParameter) +{ + ::ToolTipInfo expected(Utf8StringLiteral("const Baz<int> &")); + expected.setQdocIdCandidates({Utf8StringLiteral("Baz")}); + expected.setQdocMark(Utf8StringLiteral("Baz")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(55, 25); + + ASSERT_THAT(actual, IsQdocToolTip(expected)); +} + +TEST_F(ToolTipInfo, TemplateTypeFromNonParameter) +{ + ::ToolTipInfo expected(Utf8StringLiteral("Baz<int>")); + expected.setQdocIdCandidates({Utf8StringLiteral("Baz")}); + expected.setQdocMark(Utf8StringLiteral("Baz")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(56, 19); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, IncludeDirective) +{ + ::ToolTipInfo expected(Utf8StringLiteral(TESTDATA_DIR"/tooltipinfo.h")); + expected.setQdocIdCandidates({Utf8StringLiteral("tooltipinfo.h")}); + expected.setQdocMark(Utf8StringLiteral("tooltipinfo.h")); + expected.setQdocCategory(::ToolTipInfo::Brief); + + const ::ToolTipInfo actual = tooltip(59, 11); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, MacroUse_WithMacroFromSameFile) +{ + const ::ToolTipInfo actual = tooltip(66, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("#define MACRO_FROM_MAINFILE(x) x + 3")); +} + +TEST_F(ToolTipInfo, MacroUse_WithMacroFromHeader) +{ + const ::ToolTipInfo actual = tooltip(67, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("#define MACRO_FROM_HEADER(x) x + \\\n x + \\\n x")); +} + +TEST_F(ToolTipInfo, MacroUse_qdoc) +{ + ::ToolTipInfo expected; + expected.setQdocIdCandidates({Utf8StringLiteral("MACRO_FROM_MAINFILE")}); + expected.setQdocMark(Utf8StringLiteral("MACRO_FROM_MAINFILE")); + expected.setQdocCategory(::ToolTipInfo::Macro); + + const ::ToolTipInfo actual = tooltip(66, 5); + + ASSERT_THAT(actual, IsQdocToolTip(expected)); +} + +TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveIsQualified) +{ + ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); + expected.setQdocIdCandidates({Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}); + expected.setQdocMark(Utf8StringLiteral("Muu")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(77, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveOfAliasIsResolvedAndQualified) +{ + ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); + expected.setQdocIdCandidates({Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}); + expected.setQdocMark(Utf8StringLiteral("Muu")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(82, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDeclarationIsQualified) +{ + ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); + expected.setQdocIdCandidates({Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}); + expected.setQdocMark(Utf8StringLiteral("Muu")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(87, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, SizeForClassDefinition) +{ + const ::ToolTipInfo actual = tooltip(92, 8); + + ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("2")); +} + +TEST_F(ToolTipInfo, SizeForMemberField) +{ + const ::ToolTipInfo actual = tooltip(95, 10); + + ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("1")); +} + +TEST_F(ToolTipInfo, SizeForEnum) +{ + const ::ToolTipInfo actual = tooltip(97, 12); + + ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("4")); +} + +TEST_F(ToolTipInfo, SizeForUnion) +{ + const ::ToolTipInfo actual = tooltip(98, 7); + + ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("1")); +} + +TEST_F(ToolTipInfo, Namespace) +{ + ::ToolTipInfo expected(Utf8StringLiteral("X")); + expected.setQdocIdCandidates({Utf8StringLiteral("X")}); + expected.setQdocMark(Utf8StringLiteral("X")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(106, 11); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, NamespaceQualified) +{ + ::ToolTipInfo expected(Utf8StringLiteral("X::Y")); + expected.setQdocIdCandidates({Utf8StringLiteral("X::Y"), Utf8StringLiteral("Y")}); + expected.setQdocMark(Utf8StringLiteral("Y")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(107, 11); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +// TODO: Show unresolved and resolved name, for F1 try both. +TEST_F(ToolTipInfo, TypeName_ResolveTypeDef) +{ + ::ToolTipInfo expected(Utf8StringLiteral("Ptr<Nuu>")); + expected.setQdocIdCandidates({Utf8StringLiteral("PtrFromTypeDef")}); + expected.setQdocMark(Utf8StringLiteral("PtrFromTypeDef")); + expected.setQdocCategory(::ToolTipInfo::Typedef); + + const ::ToolTipInfo actual = tooltip(122, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +// TODO: Show unresolved and resolved name, for F1 try both. +TEST_F(ToolTipInfo, TypeName_ResolveAlias) +{ + ::ToolTipInfo expected(Utf8StringLiteral("Ptr<Nuu>")); + expected.setQdocIdCandidates({Utf8StringLiteral("PtrFromTypeAlias")}); + expected.setQdocMark(Utf8StringLiteral("PtrFromTypeAlias")); + expected.setQdocCategory(::ToolTipInfo::Typedef); + + const ::ToolTipInfo actual = tooltip(123, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +// The referenced cursor is a CXCursor_TypeAliasTemplateDecl, its type is invalid +// and so probably clang_getTypedefDeclUnderlyingType() does not return anything useful. +// TODO: Fix the cursor's type or add new API in libclang for querying the template type alias. +TEST_F(ToolTipInfo, DISABLED_TypeName_ResolveTemplateTypeAlias) +{ + const ::ToolTipInfo actual = tooltip(124, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("Ptr<Nuu>")); +} + +TEST_F(ToolTipInfo, TypeName_ResolveTemplateTypeAlias_qdoc) +{ + ::ToolTipInfo expected; + expected.setQdocIdCandidates({Utf8StringLiteral("PtrFromTemplateTypeAlias")}); + expected.setQdocMark(Utf8StringLiteral("PtrFromTemplateTypeAlias")); + expected.setQdocCategory(::ToolTipInfo::Typedef); + + const ::ToolTipInfo actual = tooltip(124, 5); + + ASSERT_THAT(actual, IsQdocToolTip(expected)); +} + +TEST_F(ToolTipInfo, TemplateClassReference) +{ + ::ToolTipInfo expected(Utf8StringLiteral("Zii<T>")); + expected.setQdocIdCandidates({Utf8StringLiteral("Zii")}); + expected.setQdocMark(Utf8StringLiteral("Zii")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(134, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, TemplateClassQualified) +{ + ::ToolTipInfo expected(Utf8StringLiteral("U::Yii<T>")); + expected.setQdocIdCandidates({Utf8StringLiteral("U::Yii"), Utf8StringLiteral("Yii")}); + expected.setQdocMark(Utf8StringLiteral("Yii")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(135, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, ResolveNamespaceAliasForType) +{ + ::ToolTipInfo expected(Utf8StringLiteral("A::X")); + expected.setQdocIdCandidates({Utf8StringLiteral("A::X"), Utf8StringLiteral("X")}); + expected.setQdocMark(Utf8StringLiteral("X")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(144, 8); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +// TODO: Show unresolved and resolved name, for F1 try both. +TEST_F(ToolTipInfo, ResolveNamespaceAlias) +{ + ::ToolTipInfo expected(Utf8StringLiteral("A")); + expected.setQdocIdCandidates({Utf8StringLiteral("B")}); + expected.setQdocMark(Utf8StringLiteral("B")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + + const ::ToolTipInfo actual = tooltip(144, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, QualificationForTemplateClassInClassInNamespace) +{ + ::ToolTipInfo expected(Utf8StringLiteral("N::Outer::Inner<int>")); + expected.setQdocIdCandidates({Utf8StringLiteral("N::Outer::Inner"), + Utf8StringLiteral("Outer::Inner"), + Utf8StringLiteral("Inner")}); + expected.setQdocMark(Utf8StringLiteral("Inner")); + expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.setSizeInBytes(Utf8StringLiteral("1")); + + const ::ToolTipInfo actual = tooltip(153, 16); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, Function) +{ + ::ToolTipInfo expected(Utf8StringLiteral("void f()")); + expected.setQdocIdCandidates({Utf8StringLiteral("f")}); + expected.setQdocMark(Utf8StringLiteral("f()")); + expected.setQdocCategory(::ToolTipInfo::Function); + + const ::ToolTipInfo actual = tooltip(165, 5); + + ASSERT_THAT(actual, IsToolTip(expected)); +} + +TEST_F(ToolTipInfo, Function_QualifiedName) +{ + const ::ToolTipInfo actual = tooltip(166, 8); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("void R::f()")); +} + +TEST_F(ToolTipInfo, Function_qdocIdCandidatesAreQualified) +{ + const ::ToolTipInfo actual = tooltip(166, 8); + + ASSERT_THAT(actual.qdocIdCandidates(), ElementsAre(Utf8StringLiteral("R::f"), + Utf8StringLiteral("f"))); +} + +TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_HasParameterName)) +{ + const ::ToolTipInfo actual = tooltip(167, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("void f(int param)")); +} + +// TODO: Implement with CXPrintingPolicy +TEST_F(ToolTipInfo, DISABLED_Function_HasDefaultArgument) +{ + const ::ToolTipInfo actual = tooltip(168, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("void z(int = 1)")); +} + +TEST_F(ToolTipInfo, Function_qdocMarkHasNoParameterName) +{ + const ::ToolTipInfo actual = tooltip(167, 5); + + ASSERT_THAT(actual.qdocMark(), Utf8StringLiteral("f(int)")); +} + +TEST_F(ToolTipInfo, Function_qdocMarkHasNoDefaultArgument) +{ + const ::ToolTipInfo actual = tooltip(168, 5); + + ASSERT_THAT(actual.qdocMark(), Utf8StringLiteral("z(int)")); +} + +TEST_F(ToolTipInfo, AutoTypeBuiltin) +{ + const ::ToolTipInfo actual = tooltip(176, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("int")); +} + +// TODO: Test for qdoc entries, too. +TEST_F(ToolTipInfo, AutoTypeEnum) +{ + const ::ToolTipInfo actual = tooltip(177, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("EnumType")); +} + +// TODO: Test for qdoc entries, too. +TEST_F(ToolTipInfo, AutoTypeClassType) +{ + const ::ToolTipInfo actual = tooltip(178, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("Bar")); +} + +// TODO: Test for qdoc entries, too. +// TODO: Deduced template arguments work, too?! +TEST_F(ToolTipInfo, AutoTypeClassTemplateType) +{ + const ::ToolTipInfo actual = tooltip(179, 5); + + ASSERT_THAT(actual.text(), Utf8StringLiteral("Zii<int>")); +} + +std::unique_ptr<Data> ToolTipInfo::d; + +void ToolTipInfo::SetUpTestCase() +{ + d.reset(new Data); +} + +void ToolTipInfo::TearDownTestCase() +{ + d.reset(); +} + +} // anonymous namespace diff --git a/tests/unit/unittest/conditionally-disabled-tests.h b/tests/unit/unittest/conditionally-disabled-tests.h index 27e6fe173b..8f55db10d7 100644 --- a/tests/unit/unittest/conditionally-disabled-tests.h +++ b/tests/unit/unittest/conditionally-disabled-tests.h @@ -33,3 +33,9 @@ #else # define DISABLED_ON_WINDOWS(x) x #endif + +#ifdef IS_PRETTY_DECL_SUPPORTED +# define DISABLED_WITHOUT_PRETTYDECL_PATCH(x) x +#else +# define DISABLED_WITHOUT_PRETTYDECL_PATCH(x) DISABLED_##x +#endif diff --git a/tests/unit/unittest/data/tooltipinfo.cpp b/tests/unit/unittest/data/tooltipinfo.cpp new file mode 100644 index 0000000000..1945577b63 --- /dev/null +++ b/tests/unit/unittest/data/tooltipinfo.cpp @@ -0,0 +1,180 @@ +void f(int foo, const int *cfoo) +{ + foo++; + cfoo++; +} + + + +struct Foo { int member = 0; }; +int g(const Foo &foo) +{ + return foo.member; + const Foo bar; + bar; +} + +struct Bar { virtual ~Bar(); int mem(){} virtual int virtualConstMem() const; }; +void h(const Foo &foo, Bar &bar) +{ + g(foo); + bar.mem(); + bar.virtualConstMem(); +} + + +template <typename T> +void t(int foo) { (void)foo; } +void c() +{ + t<Foo>(3); +} + + + +/** + * \brief This is a crazy function. + */ +void documentedFunction(); +void d() +{ + documentedFunction(); +} + + + +enum EnumType { V1, V2, Custom = V2 + 5 }; +EnumType e() +{ + return EnumType::Custom; +} + + + +template <typename T> struct Baz { T member; }; +void t2(const Baz<int> &b) { + Baz<int> baz; baz = b; +} + +#include "tooltipinfo.h" + + + +#define MACRO_FROM_MAINFILE(x) x + 3 +void foo() +{ + MACRO_FROM_MAINFILE(7); + MACRO_FROM_HEADER(7); +} + + + +namespace N { struct Muu{}; } +namespace G = N; +void o() +{ + using namespace N; + Muu muu; (void)muu; +} +void n() +{ + using namespace G; + Muu muu; (void)muu; +} +void q() +{ + using N::Muu; + Muu muu; (void)muu; +} + + + +struct Sizes +{ + char memberChar1; + char memberChar2; +}; +enum class FancyEnumType { V1, V2 }; +union Union +{ + char memberChar1; + char memberChar2; +}; + + + +namespace X { +namespace Y { +} +} + + + +template<typename T> struct Ptr {}; +struct Nuu {}; + +typedef Ptr<Nuu> PtrFromTypeDef; +using PtrFromTypeAlias = Ptr<Nuu>; +template<typename T> using PtrFromTemplateTypeAlias = Ptr<T>; + +void y() +{ + PtrFromTypeDef b; (void)b; + PtrFromTypeAlias a; (void)a; + PtrFromTemplateTypeAlias<Nuu> c; (void)c; +} + + + +template <typename T> struct Zii {}; +namespace U { template <typename T> struct Yii {}; } +void mc() +{ + using namespace U; + Zii<int> zii; (void) zii; + Yii<int> yii; (void) yii; +} + + + +namespace A { struct X {}; } +namespace B = A; +void ab() +{ + B::X x; (void)x; +} + + + +namespace N { +struct Outer +{ + template <typename T> struct Inner {}; + Inner<int> inner; +}; +} + + + +void f(); +namespace R { void f(); } +void f(int param); +void z(int = 1); +void user() +{ + f(); + R::f(); + f(1); + z(); +} + + + + +void autoTypes() +{ + auto a = 3; (void)a; + auto b = EnumType::V1; (void)b; + auto c = Bar(); (void)c; + auto d = Zii<int>(); (void)d; +} diff --git a/tests/unit/unittest/data/tooltipinfo.h b/tests/unit/unittest/data/tooltipinfo.h new file mode 100644 index 0000000000..47d3bb92e7 --- /dev/null +++ b/tests/unit/unittest/data/tooltipinfo.h @@ -0,0 +1,3 @@ +#define MACRO_FROM_HEADER(x) x + \ + x + \ + x diff --git a/tests/unit/unittest/dummyclangipcclient.h b/tests/unit/unittest/dummyclangipcclient.h index 3908f9e89f..e840b0a6c7 100644 --- a/tests/unit/unittest/dummyclangipcclient.h +++ b/tests/unit/unittest/dummyclangipcclient.h @@ -38,4 +38,5 @@ public: void documentAnnotationsChanged(const ClangBackEnd::DocumentAnnotationsChangedMessage &) override {} void references(const ClangBackEnd::ReferencesMessage &) override {} void followSymbol(const ClangBackEnd::FollowSymbolMessage &) override {} + void tooltip(const ClangBackEnd::ToolTipMessage &) override {} }; diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index 16e5133c56..dc8edee24b 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -42,6 +42,7 @@ #include <sourcelocationscontainer.h> #include <tokeninfos.h> #include <filepathview.h> +#include <tooltipinfo.h> #include <cpptools/usages.h> @@ -290,6 +291,17 @@ std::ostream &operator<<(std::ostream &os, const ReferencesMessage &message) return os; } +std::ostream &operator<<(std::ostream &os, const ToolTipMessage &message) +{ + os << "(" + << message.fileContainer() << ", " + << message.ticketNumber() << ", " + << message.toolTipInfo() << ", " + << ")"; + + return os; +} + std::ostream &operator<<(std::ostream &os, const EchoMessage &/*message*/) { return os << "()"; @@ -406,7 +418,8 @@ std::ostream &operator<<(std::ostream &os, const FileContainer &container) << container.filePath() << ", " << container.projectPartId() << ", " << container.fileArguments() << ", " - << container.documentRevision(); + << container.documentRevision() << ", " + << container.textCodecName(); if (container.hasUnsavedFileContent()) os << ", " @@ -573,6 +586,37 @@ std::ostream &operator<<(std::ostream &os, const RequestReferencesMessage &messa return os; } +std::ostream &operator<<(std::ostream &out, const RequestToolTipMessage &message) +{ + out << "(" + << message.fileContainer() << ", " + << message.ticketNumber() << ", " + << message.line() << ", " + << message.column() << ", " + << ")"; + + return out; +} + +std::ostream &operator<<(std::ostream &os, const ToolTipInfo::QdocCategory category) +{ + return os << qdocCategoryToString(category); +} + +std::ostream &operator<<(std::ostream &out, const ToolTipInfo &info) +{ + out << "(" + << info.m_text << ", " + << info.m_briefComment << ", " + << info.m_qdocIdCandidates << ", " + << info.m_qdocMark << ", " + << info.m_qdocCategory + << info.m_sizeInBytes << ", " + << ")"; + + return out; +} + std::ostream &operator<<(std::ostream &os, const RequestSourceLocationsForRenamingMessage &message) { diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index 072719ff6d..73848ba854 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -79,6 +79,7 @@ class CodeCompletedMessage; class EchoMessage; class DocumentAnnotationsChangedMessage; class ReferencesMessage; +class ToolTipMessage; class FollowSymbolMessage; class CompleteCodeMessage; class EndMessage; @@ -103,6 +104,7 @@ class RemovePchProjectPartsMessage; class RequestDocumentAnnotationsMessage; class RequestFollowSymbolMessage; class RequestReferencesMessage; +class RequestToolTipMessage; class RequestSourceLocationsForRenamingMessage; class RequestSourceRangesAndDiagnosticsForQueryMessage; class RequestSourceRangesForQueryMessage; @@ -124,6 +126,7 @@ template <char WindowsSlash> class AbstractFilePathView; using FilePathView = AbstractFilePathView<'/'>; using NativeFilePathView = AbstractFilePathView<'\\'>; +class ToolTipInfo; std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry); std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths); @@ -136,6 +139,7 @@ std::ostream &operator<<(std::ostream &out, const CodeCompletedMessage &message) std::ostream &operator<<(std::ostream &out, const EchoMessage &message); std::ostream &operator<<(std::ostream &out, const DocumentAnnotationsChangedMessage &message); std::ostream &operator<<(std::ostream &out, const ReferencesMessage &message); +std::ostream &operator<<(std::ostream &out, const ToolTipMessage &message); std::ostream &operator<<(std::ostream &out, const FollowSymbolMessage &message); std::ostream &operator<<(std::ostream &out, const CompleteCodeMessage &message); std::ostream &operator<<(std::ostream &out, const EndMessage &message); @@ -162,6 +166,8 @@ std::ostream &operator<<(std::ostream &out, const RemovePchProjectPartsMessage & std::ostream &operator<<(std::ostream &out, const RequestDocumentAnnotationsMessage &message); std::ostream &operator<<(std::ostream &out, const RequestFollowSymbolMessage &message); std::ostream &operator<<(std::ostream &out, const RequestReferencesMessage &message); +std::ostream &operator<<(std::ostream &out, const RequestToolTipMessage &message); +std::ostream &operator<<(std::ostream &out, const ToolTipInfo &info); std::ostream &operator<<(std::ostream &out, const RequestSourceLocationsForRenamingMessage &message); std::ostream &operator<<(std::ostream &out, const RequestSourceRangesAndDiagnosticsForQueryMessage &message); std::ostream &operator<<(std::ostream &out, const RequestSourceRangesForQueryMessage &message); diff --git a/tests/unit/unittest/mockclangcodemodelclient.h b/tests/unit/unittest/mockclangcodemodelclient.h index 2e287909dd..3b5a3cfbf5 100644 --- a/tests/unit/unittest/mockclangcodemodelclient.h +++ b/tests/unit/unittest/mockclangcodemodelclient.h @@ -45,4 +45,6 @@ public: void(const ClangBackEnd::ReferencesMessage &message)); MOCK_METHOD1(followSymbol, void(const ClangBackEnd::FollowSymbolMessage &message)); + MOCK_METHOD1(tooltip, + void(const ClangBackEnd::ToolTipMessage &message)); }; diff --git a/tests/unit/unittest/mockclangcodemodelserver.h b/tests/unit/unittest/mockclangcodemodelserver.h index 8b6c66b2a3..468f683bf5 100644 --- a/tests/unit/unittest/mockclangcodemodelserver.h +++ b/tests/unit/unittest/mockclangcodemodelserver.h @@ -55,6 +55,8 @@ public: void(const ClangBackEnd::RequestReferencesMessage &message)); MOCK_METHOD1(requestFollowSymbol, void(const ClangBackEnd::RequestFollowSymbolMessage &message)); + MOCK_METHOD1(requestToolTip, + void(const ClangBackEnd::RequestToolTipMessage &message)); MOCK_METHOD1(updateVisibleTranslationUnits, void(const ClangBackEnd::UpdateVisibleTranslationUnitsMessage &message)); }; diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 3c9642a46a..257a83370c 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -118,6 +118,7 @@ SOURCES += \ clangstring-test.cpp \ clangsupportivetranslationunitinitializer-test.cpp \ clangsuspenddocumentjob-test.cpp \ + clangtooltipinfo-test.cpp \ clangtranslationunits-test.cpp \ clangtranslationunit-test.cpp \ clangupdatedocumentannotationsjob-test.cpp \ diff --git a/tests/unit/unittest/unsavedfile-test.cpp b/tests/unit/unittest/unsavedfile-test.cpp index 05783a33c3..7e4d3dae68 100644 --- a/tests/unit/unittest/unsavedfile-test.cpp +++ b/tests/unit/unittest/unsavedfile-test.cpp @@ -203,4 +203,32 @@ TEST_F(UnsavedFile, HasCharacterForLastLineColumn) ASSERT_TRUE(unsavedFile.hasCharacterAt(1, 7, 't')); } +TEST_F(UnsavedFile, LineRangeForInvalidLines) +{ + ::UnsavedFile unsavedFile(filePath, fileContent); + + ASSERT_THAT(unsavedFile.lineRange(2, 1), Utf8String()); +} + +TEST_F(UnsavedFile, LineRangeForSingleLine) +{ + ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("foo")); + + ASSERT_THAT(unsavedFile.lineRange(1, 1), Utf8StringLiteral("foo")); +} + +TEST_F(UnsavedFile, LineRangeForSingleLineInMultipleLines) +{ + ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("foo\nbar\n\baz")); + + ASSERT_THAT(unsavedFile.lineRange(2, 2), Utf8StringLiteral("bar")); +} + +TEST_F(UnsavedFile, LineRangeForTwoLines) +{ + ::UnsavedFile unsavedFile(filePath, Utf8StringLiteral("foo\nbar\n\baz")); + + ASSERT_THAT(unsavedFile.lineRange(2, 3), Utf8StringLiteral("bar\n\baz")); +} + } // anonymous namespace |