From 0fd213357e4a0e11230e16e4cf25190d6039f30a Mon Sep 17 00:00:00 2001 From: Marco Bubke Date: Tue, 4 Aug 2015 15:04:41 +0200 Subject: Clang: Tests for code completion Reparsing in Clang is broken in master. We need to test what is working in which version. Change-Id: I620acd4a0a5adc951951e0fc3c0a4096ac9844fe Reviewed-by: Nikolai Kosjar --- tests/unit/unittest/codecompletiontest.cpp | 199 +++++++++++++++------ tests/unit/unittest/data/complete_completer.cpp | 101 ----------- .../unit/unittest/data/complete_completer_main.cpp | 28 +++ .../data/complete_completer_main_unsaved.cpp | 28 +++ .../unittest/data/complete_completer_unsaved.cpp | 100 ----------- .../unittest/data/complete_forwarding_header_1.h | 6 + .../unittest/data/complete_forwarding_header_2.h | 7 + tests/unit/unittest/data/complete_target_header.h | 7 + .../unittest/data/complete_target_header_changed.h | 8 + .../unittest/data/complete_target_header_unsaved.h | 8 + 10 files changed, 238 insertions(+), 254 deletions(-) delete mode 100644 tests/unit/unittest/data/complete_completer.cpp create mode 100644 tests/unit/unittest/data/complete_completer_main.cpp create mode 100644 tests/unit/unittest/data/complete_completer_main_unsaved.cpp delete mode 100644 tests/unit/unittest/data/complete_completer_unsaved.cpp create mode 100644 tests/unit/unittest/data/complete_forwarding_header_1.h create mode 100644 tests/unit/unittest/data/complete_forwarding_header_2.h create mode 100644 tests/unit/unittest/data/complete_target_header.h create mode 100644 tests/unit/unittest/data/complete_target_header_changed.h create mode 100644 tests/unit/unittest/data/complete_target_header_unsaved.h (limited to 'tests/unit/unittest') diff --git a/tests/unit/unittest/codecompletiontest.cpp b/tests/unit/unittest/codecompletiontest.cpp index 62bbbb6b9c..8765868717 100644 --- a/tests/unit/unittest/codecompletiontest.cpp +++ b/tests/unit/unittest/codecompletiontest.cpp @@ -28,107 +28,200 @@ ** ****************************************************************************/ -#include "gtest/gtest.h" -#include "gmock/gmock-matchers.h" -#include "gtest-qt-printing.h" - #include #include +#include #include #include #include -#include #include +#include +#include +#include +#include +#include "gtest-qt-printing.h" using ::testing::ElementsAreArray; using ::testing::Contains; using ::testing::AllOf; using ::testing::Not; +using ::testing::PrintToString; using ClangBackEnd::CodeCompletion; using ClangBackEnd::CodeCompleter; namespace { +MATCHER_P2(IsCodeCompletion, text, completionKind, + std::string(negation ? "isn't" : "is") + " code completion with text " + + PrintToString(text) + " and kind " + PrintToString(completionKind) + ) +{ + if (arg.text() != text) { + *result_listener << "text is " + PrintToString(arg.text()) + " and not " + PrintToString(text); + return false; + } + + if (arg.completionKind() != completionKind) { + *result_listener << "kind is " + PrintToString(arg.completionKind()) + " and not " + PrintToString(completionKind); + return false; + } + + return true; +} + class CodeCompleter : public ::testing::Test { -public: - static void SetUpTestCase(); - static void TearDownTestCase(); +protected: + void SetUp(); + void copyTargetHeaderToTemporaryIncludeDirecory(); + void copyChangedTargetHeaderToTemporaryIncludeDirecory(); + static Utf8String readFileContent(const QString &fileName); protected: - static ClangBackEnd::ProjectPart projectPart; - static ClangBackEnd::UnsavedFiles unsavedFiles; - static ClangBackEnd::TranslationUnit translationUnit; - static ClangBackEnd::CodeCompleter completer; + QTemporaryDir includeDirectory; + QString targetHeaderPath{includeDirectory.path() + QStringLiteral("/complete_target_header.h")}; + ClangBackEnd::ProjectPart projectPart{Utf8StringLiteral("projectPartId")}; + ClangBackEnd::UnsavedFiles unsavedFiles; + ClangBackEnd::TranslationUnit translationUnit{Utf8StringLiteral(TESTDATA_DIR"/complete_completer_main.cpp"), + unsavedFiles, + projectPart}; + ClangBackEnd::CodeCompleter completer{translationUnit}; + ClangBackEnd::FileContainer unsavedMainFileContainer{translationUnit.filePath(), + projectPart.projectPartId(), + readFileContent(QStringLiteral("/complete_completer_main_unsaved.cpp")), + true}; + ClangBackEnd::FileContainer unsavedTargetHeaderFileContainer{targetHeaderPath, + projectPart.projectPartId(), + readFileContent(QStringLiteral("/complete_target_header_unsaved.h")), + true}; }; -ClangBackEnd::ProjectPart CodeCompleter::projectPart(Utf8StringLiteral("projectPartId")); -ClangBackEnd::UnsavedFiles CodeCompleter::unsavedFiles; -ClangBackEnd::TranslationUnit CodeCompleter::translationUnit(Utf8StringLiteral(TESTDATA_DIR"/complete_completer.cpp"), unsavedFiles, projectPart); -ClangBackEnd::CodeCompleter CodeCompleter::completer = translationUnit; - -void CodeCompleter::SetUpTestCase() +Utf8String CodeCompleter::readFileContent(const QString &fileName) { - QFile unsavedFileContentFile(QStringLiteral(TESTDATA_DIR) + QStringLiteral("/complete_completer_unsaved.cpp")); - unsavedFileContentFile.open(QIODevice::ReadOnly); + QFile readFileContentFile(QStringLiteral(TESTDATA_DIR) + fileName); + bool hasOpened = readFileContentFile.open(QIODevice::ReadOnly | QIODevice::Text); - const Utf8String unsavedFileContent = Utf8String::fromByteArray(unsavedFileContentFile.readAll()); - const ClangBackEnd::FileContainer unsavedDataFileContainer(translationUnit.filePath(), - projectPart.projectPartId(), - unsavedFileContent, - true); + EXPECT_TRUE(hasOpened); - unsavedFiles.createOrUpdate({unsavedDataFileContainer}); + return Utf8String::fromByteArray(readFileContentFile.readAll()); } -void CodeCompleter::TearDownTestCase() +void CodeCompleter::copyTargetHeaderToTemporaryIncludeDirecory() { - translationUnit.reset(); - completer = ClangBackEnd::CodeCompleter(); + QFile::remove(targetHeaderPath); + bool hasCopied = QFile::copy(QStringLiteral(TESTDATA_DIR "/complete_target_header.h"), + targetHeaderPath); + EXPECT_TRUE(hasCopied); } +void CodeCompleter::copyChangedTargetHeaderToTemporaryIncludeDirecory() +{ + QFile::remove(targetHeaderPath); + bool hasCopied = QFile::copy(QStringLiteral(TESTDATA_DIR "/complete_target_header_changed.h"), + targetHeaderPath); + EXPECT_TRUE(hasCopied); +} + +void CodeCompleter::SetUp() +{ + EXPECT_TRUE(includeDirectory.isValid()); + + Utf8String includePath(QStringLiteral("-I") + includeDirectory.path()); + projectPart.setArguments({includePath}); + + copyTargetHeaderToTemporaryIncludeDirecory(); + + translationUnit.cxTranslationUnit(); // initialize translation unit so we check changes +} TEST_F(CodeCompleter, FunctionInUnsavedFile) { - ASSERT_THAT(completer.complete(100, 1), - AllOf(Contains(CodeCompletion(Utf8StringLiteral("functionWithArguments"), - 0, - CodeCompletion::FunctionCompletionKind)), - Contains(CodeCompletion(Utf8StringLiteral("function"), - 0, - CodeCompletion::FunctionCompletionKind)), - Contains(CodeCompletion(Utf8StringLiteral("newFunction"), - 0, - CodeCompletion::FunctionCompletionKind)), - Contains(CodeCompletion(Utf8StringLiteral("f"), - 0, - CodeCompletion::FunctionCompletionKind)), - Not(Contains(CodeCompletion(Utf8StringLiteral("otherFunction"), - 0, - CodeCompletion::FunctionCompletionKind))))); + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + AllOf(Contains(IsCodeCompletion(Utf8StringLiteral("FunctionWithArguments"), + CodeCompletion::FunctionCompletionKind)), + Contains(IsCodeCompletion(Utf8StringLiteral("Function"), + CodeCompletion::FunctionCompletionKind)), + Contains(IsCodeCompletion(Utf8StringLiteral("UnsavedFunction"), + CodeCompletion::FunctionCompletionKind)), + Contains(IsCodeCompletion(Utf8StringLiteral("f"), + CodeCompletion::FunctionCompletionKind)), + Not(Contains(IsCodeCompletion(Utf8StringLiteral("SavedFunction"), + CodeCompletion::FunctionCompletionKind))))); } +TEST_F(CodeCompleter, VariableInUnsavedFile) +{ + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("VariableInUnsavedFile"), + CodeCompletion::VariableCompletionKind))); +} + +TEST_F(CodeCompleter, GlobalVariableInUnsavedFile) +{ + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("GlobalVariableInUnsavedFile"), + CodeCompletion::VariableCompletionKind))); +} TEST_F(CodeCompleter, Macro) { - ASSERT_THAT(completer.complete(100, 1), - Contains(CodeCompletion(Utf8StringLiteral("Macro"), - 0, - CodeCompletion::PreProcessorCompletionKind))); + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("Macro"), + CodeCompletion::PreProcessorCompletionKind))); } TEST_F(CodeCompleter, Keyword) { - ASSERT_THAT(completer.complete(100, 1), - Contains(CodeCompletion(Utf8StringLiteral("switch"), - 0, - CodeCompletion::KeywordCompletionKind))); + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("switch"), + CodeCompletion::KeywordCompletionKind))); +} + +TEST_F(CodeCompleter, FunctionInIncludedHeader) +{ + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeader"), + CodeCompletion::FunctionCompletionKind))); } +TEST_F(CodeCompleter, FunctionInUnsavedIncludedHeader) +{ + unsavedFiles.createOrUpdate({unsavedTargetHeaderFileContainer}); + + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderUnsaved"), + CodeCompletion::FunctionCompletionKind))); +} + +TEST_F(CodeCompleter, FunctionInChangedIncludedHeader) +{ + copyChangedTargetHeaderToTemporaryIncludeDirecory(); + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderChanged"), + CodeCompletion::FunctionCompletionKind))); } +TEST_F(CodeCompleter, FunctionInChangedIncludedHeaderWithUnsavedContentInMainFile) +{ + unsavedFiles.createOrUpdate({unsavedMainFileContainer}); + + copyChangedTargetHeaderToTemporaryIncludeDirecory(); + ASSERT_THAT(completer.complete(27, 1), + Contains(IsCodeCompletion(Utf8StringLiteral("FunctionInIncludedHeaderChanged"), + CodeCompletion::FunctionCompletionKind))); +} + +} diff --git a/tests/unit/unittest/data/complete_completer.cpp b/tests/unit/unittest/data/complete_completer.cpp deleted file mode 100644 index a764b7adb4..0000000000 --- a/tests/unit/unittest/data/complete_completer.cpp +++ /dev/null @@ -1,101 +0,0 @@ -void function() -{ - -} - -class Foo; -void functionWithArguments(int i, char *c, const Foo &ref) -{ - -} - -void otherFunction() -{ - -} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void f() -{ - -} diff --git a/tests/unit/unittest/data/complete_completer_main.cpp b/tests/unit/unittest/data/complete_completer_main.cpp new file mode 100644 index 0000000000..877ce23d28 --- /dev/null +++ b/tests/unit/unittest/data/complete_completer_main.cpp @@ -0,0 +1,28 @@ +#include "complete_forwarding_header_1.h" + +void Function() +{ + +} + +class Foo; +void FunctionWithArguments(int i, char *c, const Foo &ref) +{ + +} + +void SavedFunction() +{ + +} + + + + + + + +void f() +{ + +} diff --git a/tests/unit/unittest/data/complete_completer_main_unsaved.cpp b/tests/unit/unittest/data/complete_completer_main_unsaved.cpp new file mode 100644 index 0000000000..38af12b858 --- /dev/null +++ b/tests/unit/unittest/data/complete_completer_main_unsaved.cpp @@ -0,0 +1,28 @@ +#include "complete_forwarding_header_2.h" + +void Function() +{ + +} + +class Foo; +void FunctionWithArguments(int i, char *c, const Foo &ref) +{ + +} + +void UnsavedFunction() +{ + +} + +#define Macro + +int GlobalVariableInUnsavedFile; + +void f() +{ + int VariableInUnsavedFile; + + +} diff --git a/tests/unit/unittest/data/complete_completer_unsaved.cpp b/tests/unit/unittest/data/complete_completer_unsaved.cpp deleted file mode 100644 index 9ec3fed8f4..0000000000 --- a/tests/unit/unittest/data/complete_completer_unsaved.cpp +++ /dev/null @@ -1,100 +0,0 @@ -void function() -{ - -} - -class Foo; -void functionWithArguments(int i, char *c, const Foo &ref) -{ - -} - -void newFunction() -{ - -} - -#define Macro - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void f() -{ - -} diff --git a/tests/unit/unittest/data/complete_forwarding_header_1.h b/tests/unit/unittest/data/complete_forwarding_header_1.h new file mode 100644 index 0000000000..4905abf3e8 --- /dev/null +++ b/tests/unit/unittest/data/complete_forwarding_header_1.h @@ -0,0 +1,6 @@ +#ifndef COMPLETE_FORWARDING_HEADER_1_H +#define COMPLETE_FORWARDING_HEADER_1_H + +#include + +#endif // COMPLETE_FORWARDING_HEADER_1_H diff --git a/tests/unit/unittest/data/complete_forwarding_header_2.h b/tests/unit/unittest/data/complete_forwarding_header_2.h new file mode 100644 index 0000000000..dd0c3bc291 --- /dev/null +++ b/tests/unit/unittest/data/complete_forwarding_header_2.h @@ -0,0 +1,7 @@ +#ifndef COMPLETE_FORWARDING_HEADER_2_H +#define COMPLETE_FORWARDING_HEADER_2_H + +#include + +#endif // COMPLETE_FORWARDING_HEADER_2_H + diff --git a/tests/unit/unittest/data/complete_target_header.h b/tests/unit/unittest/data/complete_target_header.h new file mode 100644 index 0000000000..7d0ba1c845 --- /dev/null +++ b/tests/unit/unittest/data/complete_target_header.h @@ -0,0 +1,7 @@ +#ifndef COMPLETE_TARGET_HEADER_H +#define COMPLETE_TARGET_HEADER_H + +void FunctionInIncludedHeader(); + +#endif // COMPLETE_TARGET_HEADER_H + diff --git a/tests/unit/unittest/data/complete_target_header_changed.h b/tests/unit/unittest/data/complete_target_header_changed.h new file mode 100644 index 0000000000..d631afd91b --- /dev/null +++ b/tests/unit/unittest/data/complete_target_header_changed.h @@ -0,0 +1,8 @@ +#ifndef COMPLETE_TARGET_HEADER_CHANGED_H +#define COMPLETE_TARGET_HEADER_CHANGED_H + +void FunctionInIncludedHeader(); +void FunctionInIncludedHeaderChanged(); + +#endif // COMPLETE_TARGET_HEADER_CHANGED_H + diff --git a/tests/unit/unittest/data/complete_target_header_unsaved.h b/tests/unit/unittest/data/complete_target_header_unsaved.h new file mode 100644 index 0000000000..904a861870 --- /dev/null +++ b/tests/unit/unittest/data/complete_target_header_unsaved.h @@ -0,0 +1,8 @@ +#ifndef COMPLETE_TARGET_HEADER_UNSAVED_H +#define COMPLETE_TARGET_HEADER_UNSAVED_H + +void FunctionInIncludedHeader(); +void FunctionInIncludedHeaderUnsaved(); + +#endif // COMPLETE_TARGET_HEADER_UNSAVED_H + -- cgit v1.2.3