diff options
Diffstat (limited to 'tests')
197 files changed, 7663 insertions, 3209 deletions
diff --git a/tests/auto/algorithm/tst_algorithm.cpp b/tests/auto/algorithm/tst_algorithm.cpp index 87e3b7ecbd2..14d30f75473 100644 --- a/tests/auto/algorithm/tst_algorithm.cpp +++ b/tests/auto/algorithm/tst_algorithm.cpp @@ -48,8 +48,8 @@ private slots: void contains(); void findOr(); void findOrDefault(); - void toRawPointer(); void toReferences(); + void take(); }; @@ -475,93 +475,31 @@ void tst_Algorithm::contains() QList<Struct> structQlist = {2, 4, 6, 8}; QVERIFY(Utils::contains(structQlist, &Struct::isEven)); QVERIFY(!Utils::contains(structQlist, &Struct::isOdd)); - std::vector<std::unique_ptr<int>> v2; - v2.emplace_back(std::make_unique<int>(1)); - v2.emplace_back(std::make_unique<int>(2)); - v2.emplace_back(std::make_unique<int>(3)); - v2.emplace_back(std::make_unique<int>(4)); - QVERIFY(Utils::contains(v2, [](const std::unique_ptr<int> &ip) { return *ip == 2; })); - QVERIFY(!Utils::contains(v2, [](const std::unique_ptr<int> &ip) { return *ip == 5; })); - // Find pointers in unique_ptrs: - QVERIFY(Utils::contains(v2, v2.back().get())); - int foo = 42; - QVERIFY(!Utils::contains(v2, &foo)); } void tst_Algorithm::findOr() { std::vector<int> v1{1, 2, 3, 4}; - QCOMPARE(Utils::findOr(v1, 6, [](int i) { return i == 2; }), 2); - QCOMPARE(Utils::findOr(v1, 6, [](int i) { return i == 5; }), 6); - std::vector<std::unique_ptr<int>> v2; - v2.emplace_back(std::make_unique<int>(1)); - v2.emplace_back(std::make_unique<int>(2)); - v2.emplace_back(std::make_unique<int>(3)); - v2.emplace_back(std::make_unique<int>(4)); - int def = 6; - QCOMPARE(Utils::findOr(v2, &def, [](const std::unique_ptr<int> &ip) { return *ip == 2; }), v2.at(1).get()); - QCOMPARE(Utils::findOr(v2, &def, [](const std::unique_ptr<int> &ip) { return *ip == 5; }), &def); - std::vector<std::unique_ptr<Struct>> v3; - v3.emplace_back(std::make_unique<Struct>(1)); - v3.emplace_back(std::make_unique<Struct>(3)); - v3.emplace_back(std::make_unique<Struct>(5)); - v3.emplace_back(std::make_unique<Struct>(7)); - Struct defS(6); - QCOMPARE(Utils::findOr(v3, &defS, &Struct::isOdd), v3.at(0).get()); - QCOMPARE(Utils::findOr(v3, &defS, &Struct::isEven), &defS); - - std::vector<std::shared_ptr<Struct>> v4; - v4.emplace_back(std::make_shared<Struct>(1)); - v4.emplace_back(std::make_shared<Struct>(3)); - v4.emplace_back(std::make_shared<Struct>(5)); - v4.emplace_back(std::make_shared<Struct>(7)); - std::shared_ptr<Struct> sharedDefS = std::make_shared<Struct>(6); - QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isOdd), v4.at(0)); - QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isEven), sharedDefS); + QCOMPARE(Utils::findOr(v1, 10, [](int i) { return i == 2; }), 2); + QCOMPARE(Utils::findOr(v1, 10, [](int i) { return i == 5; }), 10); } void tst_Algorithm::findOrDefault() { - std::vector<int> v1{1, 2, 3, 4}; - QCOMPARE(Utils::findOrDefault(v1, [](int i) { return i == 2; }), 2); - QCOMPARE(Utils::findOrDefault(v1, [](int i) { return i == 5; }), 0); - std::vector<std::unique_ptr<int>> v2; - v2.emplace_back(std::make_unique<int>(1)); - v2.emplace_back(std::make_unique<int>(2)); - v2.emplace_back(std::make_unique<int>(3)); - v2.emplace_back(std::make_unique<int>(4)); - QCOMPARE(Utils::findOrDefault(v2, [](const std::unique_ptr<int> &ip) { return *ip == 2; }), v2.at(1).get()); - QCOMPARE(Utils::findOrDefault(v2, [](const std::unique_ptr<int> &ip) { return *ip == 5; }), static_cast<int*>(0)); - std::vector<std::unique_ptr<Struct>> v3; - v3.emplace_back(std::make_unique<Struct>(1)); - v3.emplace_back(std::make_unique<Struct>(3)); - v3.emplace_back(std::make_unique<Struct>(5)); - v3.emplace_back(std::make_unique<Struct>(7)); - QCOMPARE(Utils::findOrDefault(v3, &Struct::isOdd), v3.at(0).get()); - QCOMPARE(Utils::findOrDefault(v3, &Struct::isEven), static_cast<Struct*>(nullptr)); - - std::vector<std::shared_ptr<Struct>> v4; - v4.emplace_back(std::make_shared<Struct>(1)); - v4.emplace_back(std::make_shared<Struct>(3)); - v4.emplace_back(std::make_shared<Struct>(5)); - v4.emplace_back(std::make_shared<Struct>(7)); - QCOMPARE(Utils::findOrDefault(v4, &Struct::isOdd), v4.at(0)); - QCOMPARE(Utils::findOrDefault(v4, &Struct::isEven), std::shared_ptr<Struct>()); -} - -void tst_Algorithm::toRawPointer() -{ - const std::vector<std::unique_ptr<Struct>> v; - - // same result container - const std::vector<Struct *> x1 = Utils::toRawPointer(v); - // different result container - const std::vector<Struct *> x2 = Utils::toRawPointer<std::vector>(v); - const QVector<Struct *> x3 = Utils::toRawPointer<QVector>(v); - const std::list<Struct *> x4 = Utils::toRawPointer<std::list>(v); - // different fully specified result container - const std::vector<BaseStruct *> x5 = Utils::toRawPointer<std::vector<BaseStruct *>>(v); - const QVector<BaseStruct *> x6 = Utils::toRawPointer<QVector<BaseStruct *>>(v); + { + std::vector<int> v1{1, 2, 3, 4}; + QCOMPARE(Utils::findOrDefault(v1, [](int i) { return i == 2; }), 2); + QCOMPARE(Utils::findOrDefault(v1, [](int i) { return i == 5; }), 0); + } + { + std::vector<std::shared_ptr<Struct>> v4; + v4.emplace_back(std::make_shared<Struct>(1)); + v4.emplace_back(std::make_shared<Struct>(3)); + v4.emplace_back(std::make_shared<Struct>(5)); + v4.emplace_back(std::make_shared<Struct>(7)); + QCOMPARE(Utils::findOrDefault(v4, &Struct::isOdd), v4.at(0)); + QCOMPARE(Utils::findOrDefault(v4, &Struct::isEven), std::shared_ptr<Struct>()); + } } void tst_Algorithm::toReferences() @@ -612,6 +550,31 @@ void tst_Algorithm::toReferences() } } +void tst_Algorithm::take() +{ + { + QList<Struct> v {1, 3, 5, 6, 7, 8, 9, 11, 13, 15, 13, 16, 17}; + Utils::optional<Struct> r1 = Utils::take(v, [](const Struct &s) { return s.member == 13; }); + QVERIFY(static_cast<bool>(r1)); + QCOMPARE(r1.value().member, 13); + Utils::optional<Struct> r2 = Utils::take(v, [](const Struct &s) { return s.member == 13; }); + QVERIFY(static_cast<bool>(r2)); + QCOMPARE(r2.value().member, 13); + Utils::optional<Struct> r3 = Utils::take(v, [](const Struct &s) { return s.member == 13; }); + QVERIFY(!static_cast<bool>(r3)); + + Utils::optional<Struct> r4 = Utils::take(v, &Struct::isEven); + QVERIFY(static_cast<bool>(r4)); + QCOMPARE(r4.value().member, 6); + } + { + QList<Struct> v {0, 0, 0, 0, 0, 0, 1, 2, 3}; + Utils::optional<Struct> r1 = Utils::take(v, &Struct::member); + QVERIFY(static_cast<bool>(r1)); + QCOMPARE(r1.value().member, 1); + } +} + QTEST_MAIN(tst_Algorithm) #include "tst_algorithm.moc" diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index 8eed70e06d2..b1498d40d2f 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -4,7 +4,7 @@ SUBDIRS += \ algorithm \ aggregation \ changeset \ - clangstaticanalyzer \ + clangtools \ cplusplus \ debugger \ diff \ @@ -12,6 +12,7 @@ SUBDIRS += \ externaltool \ environment \ generichighlighter \ + pointeralgorithm \ profilewriter \ treeviewfind \ toolchaincache \ @@ -25,4 +26,4 @@ SUBDIRS += \ valgrind qtHaveModule(qml): SUBDIRS += qml -qtHaveModule(quick): SUBDIRS += flamegraph timeline +qtHaveModule(quick): SUBDIRS += tracing diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs index 26c08fec8eb..03bfeebc86c 100644 --- a/tests/auto/auto.qbs +++ b/tests/auto/auto.qbs @@ -7,7 +7,7 @@ Project { "aggregation/aggregation.qbs", "algorithm/algorithm.qbs", "changeset/changeset.qbs", - "clangstaticanalyzer/clangstaticanalyzer.qbs", + "clangtools/clangtools.qbs", "cplusplus/cplusplus.qbs", "debugger/debugger.qbs", "diff/diff.qbs", @@ -15,7 +15,6 @@ Project { "extensionsystem/extensionsystem.qbs", "externaltool/externaltool.qbs", "filesearch/filesearch.qbs", - "flamegraph/flamegraph.qbs", "generichighlighter/generichighlighter.qbs", "json/json.qbs", "profilewriter/profilewriter.qbs", @@ -23,7 +22,7 @@ Project { "qtcprocess/qtcprocess.qbs", "runextensions/runextensions.qbs", "sdktool/sdktool.qbs", - "timeline/timeline.qbs", + "tracing/tracing.qbs", "treeviewfind/treeviewfind.qbs", "toolchaincache/toolchaincache.qbs", "utils/utils.qbs", diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzer.qbs b/tests/auto/clangstaticanalyzer/clangstaticanalyzer.qbs deleted file mode 100644 index e9ee45d733a..00000000000 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzer.qbs +++ /dev/null @@ -1,9 +0,0 @@ -import qbs - -Project { - name: "ClangStaticAnalyzer autotests" - references: [ - "clangstaticanalyzerlogfilereader", - "clangstaticanalyzerrunner", - ] -} diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/clangstaticanalyzerlogfilereader.pro b/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/clangstaticanalyzerlogfilereader.pro deleted file mode 100644 index 4a1f96e77f7..00000000000 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/clangstaticanalyzerlogfilereader.pro +++ /dev/null @@ -1,14 +0,0 @@ -include(../clangstaticanalyzertest.pri) - -TARGET = tst_clangstaticanalyzerlogfilereader - -DEFINES += SRCDIR=\\\"$$PWD/\\\" - -SOURCES += \ - tst_clangstaticanalyzerlogfilereader.cpp \ - $$PLUGINDIR/clangstaticanalyzerdiagnostic.cpp \ - $$PLUGINDIR/clangstaticanalyzerlogfilereader.cpp - -HEADERS += \ - $$PLUGINDIR/clangstaticanalyzerdiagnostic.h \ - $$PLUGINDIR/clangstaticanalyzerlogfilereader.h diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/clangstaticanalyzerlogfilereader.qbs b/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/clangstaticanalyzerlogfilereader.qbs deleted file mode 100644 index 5fc992aa064..00000000000 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/clangstaticanalyzerlogfilereader.qbs +++ /dev/null @@ -1,22 +0,0 @@ -import qbs -import "../clangstaticanalyzerautotest.qbs" as ClangStaticAnalyzerAutotest - -ClangStaticAnalyzerAutotest { - name: "ClangStaticAnalyzerLogFileReader Autotest" - cpp.defines: base.concat('SRCDIR="' + sourceDirectory + '"') - - Group { - name: "sources from plugin" - prefix: pluginDir + '/' - files: [ - "clangstaticanalyzerdiagnostic.cpp", - "clangstaticanalyzerdiagnostic.h", - "clangstaticanalyzerlogfilereader.cpp", - "clangstaticanalyzerlogfilereader.h", - ] - } - - files: [ - "tst_clangstaticanalyzerlogfilereader.cpp" - ] -} diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerrunner/clangstaticanalyzerrunner.pro b/tests/auto/clangtools/clangstaticanalyzerrunner/clangstaticanalyzerrunner.pro index 7893e8761a4..c0231c0aa01 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerrunner/clangstaticanalyzerrunner.pro +++ b/tests/auto/clangtools/clangstaticanalyzerrunner/clangstaticanalyzerrunner.pro @@ -1,9 +1,11 @@ -include(../clangstaticanalyzertest.pri) +include(../clangtoolstest.pri) TARGET = tst_clangstaticanalyzerrunnertest SOURCES += \ tst_clangstaticanalyzerrunner.cpp \ + $$PLUGINDIR/clangtoolrunner.cpp \ $$PLUGINDIR/clangstaticanalyzerrunner.cpp HEADERS += \ + $$PLUGINDIR/clangtoolrunner.h \ $$PLUGINDIR/clangstaticanalyzerrunner.h diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerrunner/clangstaticanalyzerrunner.qbs b/tests/auto/clangtools/clangstaticanalyzerrunner/clangstaticanalyzerrunner.qbs index 6b0f9da3f37..94580dda1bd 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerrunner/clangstaticanalyzerrunner.qbs +++ b/tests/auto/clangtools/clangstaticanalyzerrunner/clangstaticanalyzerrunner.qbs @@ -1,7 +1,7 @@ import qbs -import "../clangstaticanalyzerautotest.qbs" as ClangStaticAnalyzerAutotest +import "../clangtoolsautotest.qbs" as ClangToolsAutotest -ClangStaticAnalyzerAutotest { +ClangToolsAutotest { name: "ClangStaticAnalyzerRunner Autotest" Group { @@ -10,6 +10,8 @@ ClangStaticAnalyzerAutotest { files: [ "clangstaticanalyzerrunner.cpp", "clangstaticanalyzerrunner.h", + "clangtoolrunner.cpp", + "clangtoolrunner.h", ] } diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp b/tests/auto/clangtools/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp index 9c71b800ecb..e0b1c4e364c 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp +++ b/tests/auto/clangtools/clangstaticanalyzerrunner/tst_clangstaticanalyzerrunner.cpp @@ -23,15 +23,16 @@ ** ****************************************************************************/ -#include <clangstaticanalyzer/clangstaticanalyzerconstants.h> -#include <clangstaticanalyzer/clangstaticanalyzerrunner.h> +#include <clangtools/clangtoolsconstants.h> +#include <clangtools/clangstaticanalyzerrunner.h> +#include <utils/environment.h> #include <utils/hostosinfo.h> #include <utils/temporarydirectory.h> #include <QtTest> -using namespace ClangStaticAnalyzer::Internal; +using namespace ClangTools::Internal; static QString clangExecutablePath() { @@ -193,7 +194,7 @@ void ClangStaticAnalyzerRunnerTest::runWithNonExistentFileToAnalyze() QVERIFY(runner.run(QLatin1String("not.existing.file.111"))); QVERIFY(st.expectStartedSignal()); - QVERIFY(st.expectFinishWithFailureSignal(finishedWithBadExitCode(1))); + QVERIFY(st.expectFinishWithFailureSignal(finishedWithBadExitCode("Clang Static Analyzer", 1))); } int main(int argc, char *argv[]) diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzer.pro b/tests/auto/clangtools/clangtools.pro index 72e7c586e9d..5d550ea70c5 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzer.pro +++ b/tests/auto/clangtools/clangtools.pro @@ -3,4 +3,4 @@ CONFIG += ordered SUBDIRS = \ clangstaticanalyzerrunner \ - clangstaticanalyzerlogfilereader + clangtoolslogfilereader diff --git a/tests/auto/clangtools/clangtools.qbs b/tests/auto/clangtools/clangtools.qbs new file mode 100644 index 00000000000..7340c07363e --- /dev/null +++ b/tests/auto/clangtools/clangtools.qbs @@ -0,0 +1,9 @@ +import qbs + +Project { + name: "ClangTools autotests" + references: [ + "clangtoolslogfilereader", + "clangstaticanalyzerrunner", + ] +} diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerautotest.qbs b/tests/auto/clangtools/clangtoolsautotest.qbs index 5ec34efb84b..fd444596ccd 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerautotest.qbs +++ b/tests/auto/clangtools/clangtoolsautotest.qbs @@ -5,6 +5,6 @@ QtcAutotest { Depends { name: "Debugger" } Depends { name: "Utils" } - property path pluginDir: project.ide_source_tree + "/src/plugins/clangstaticanalyzer" + property path pluginDir: project.ide_source_tree + "/src/plugins/clangtools" cpp.includePaths: base.concat(pluginDir + "/..") } diff --git a/tests/auto/clangtools/clangtoolslogfilereader/clangtoolslogfilereader.pro b/tests/auto/clangtools/clangtoolslogfilereader/clangtoolslogfilereader.pro new file mode 100644 index 00000000000..2c94f7ddac2 --- /dev/null +++ b/tests/auto/clangtools/clangtoolslogfilereader/clangtoolslogfilereader.pro @@ -0,0 +1,20 @@ +include(../clangtoolstest.pri) +include(../../../../src/shared/clang/clang_installation.pri) + +requires(!isEmpty(LLVM_VERSION)) + +TARGET = tst_clangtoolslogfilereader + +DEFINES += SRCDIR=\\\"$$PWD/\\\" + +LIBS += $$LIBCLANG_LIBS +INCLUDEPATH += $$LLVM_INCLUDEPATH + +SOURCES += \ + tst_clangtoolslogfilereader.cpp \ + $$PLUGINDIR/clangtoolsdiagnostic.cpp \ + $$PLUGINDIR/clangtoolslogfilereader.cpp + +HEADERS += \ + $$PLUGINDIR/clangtoolsdiagnostic.h \ + $$PLUGINDIR/clangtoolslogfilereader.h diff --git a/tests/auto/clangtools/clangtoolslogfilereader/clangtoolslogfilereader.qbs b/tests/auto/clangtools/clangtoolslogfilereader/clangtoolslogfilereader.qbs new file mode 100644 index 00000000000..2a1a5b0a259 --- /dev/null +++ b/tests/auto/clangtools/clangtoolslogfilereader/clangtoolslogfilereader.qbs @@ -0,0 +1,32 @@ +import qbs +import "../clangtoolsautotest.qbs" as ClangToolsAutotest + +ClangToolsAutotest { + name: "ClangToolsLogFileReader Autotest" + + Depends { name: "libclang"; required: false } + + cpp.defines: base.concat('SRCDIR="' + sourceDirectory + '"') + + condition: libclang.present + + cpp.includePaths: base.concat(libclang.llvmIncludeDir) + cpp.libraryPaths: base.concat(libclang.llvmLibDir) + cpp.dynamicLibraries: base.concat(libclang.llvmLibs) + cpp.rpaths: base.concat(libclang.llvmLibDir) + + Group { + name: "sources from plugin" + prefix: pluginDir + '/' + files: [ + "clangtoolsdiagnostic.cpp", + "clangtoolsdiagnostic.h", + "clangtoolslogfilereader.cpp", + "clangtoolslogfilereader.h", + ] + } + + files: [ + "tst_clangtoolslogfilereader.cpp" + ] +} diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/data/noDiagnostics.plist b/tests/auto/clangtools/clangtoolslogfilereader/data/noDiagnostics.plist index 2cccbf770f9..2cccbf770f9 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/data/noDiagnostics.plist +++ b/tests/auto/clangtools/clangtoolslogfilereader/data/noDiagnostics.plist diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/data/someDiagnostics.plist b/tests/auto/clangtools/clangtoolslogfilereader/data/someDiagnostics.plist index 3fa5effad2d..3fa5effad2d 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/data/someDiagnostics.plist +++ b/tests/auto/clangtools/clangtoolslogfilereader/data/someDiagnostics.plist diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/tst_clangstaticanalyzerlogfilereader.cpp b/tests/auto/clangtools/clangtoolslogfilereader/tst_clangtoolslogfilereader.cpp index 076f576e82b..33cdf5fd66c 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzerlogfilereader/tst_clangstaticanalyzerlogfilereader.cpp +++ b/tests/auto/clangtools/clangtoolslogfilereader/tst_clangtoolslogfilereader.cpp @@ -23,7 +23,7 @@ ** ****************************************************************************/ -#include <clangstaticanalyzer/clangstaticanalyzerlogfilereader.h> +#include <clangtools/clangtoolslogfilereader.h> #include <utils/fileutils.h> @@ -32,7 +32,7 @@ enum { debug = 0 }; using namespace Debugger; -using namespace ClangStaticAnalyzer::Internal; +using namespace ClangTools::Internal; namespace { @@ -83,7 +83,7 @@ QString testFilePath(const QString &relativePath) } // anonymous namespace -class ClangStaticAnalyzerLogFileReaderTest : public QObject +class ClangToolsLogFileReaderTest : public QObject { Q_OBJECT @@ -93,35 +93,35 @@ private slots: void readFileWithDiagnostics(); }; -void ClangStaticAnalyzerLogFileReaderTest::readEmptyFile() +void ClangToolsLogFileReaderTest::readEmptyFile() { const QString filePath = QDir::tempPath() + QLatin1String("/empty.file"); QVERIFY(createEmptyFile(filePath)); QString errorMessage; - const QList<Diagnostic> diagnostics = LogFileReader::read(filePath, &errorMessage); + const QList<Diagnostic> diagnostics = LogFileReader::readPlist(filePath, &errorMessage); QVERIFY(!errorMessage.isEmpty()); if (debug) qDebug() << errorMessage; QVERIFY(diagnostics.isEmpty()); } -void ClangStaticAnalyzerLogFileReaderTest::readFileWithNoDiagnostics() +void ClangToolsLogFileReaderTest::readFileWithNoDiagnostics() { const QString filePath = testFilePath(QLatin1String("/data/noDiagnostics.plist")); QString errorMessage; - const QList<Diagnostic> diagnostics = LogFileReader::read(filePath, &errorMessage); + const QList<Diagnostic> diagnostics = LogFileReader::readPlist(filePath, &errorMessage); QVERIFY(errorMessage.isEmpty()); QVERIFY(diagnostics.isEmpty()); } -void ClangStaticAnalyzerLogFileReaderTest::readFileWithDiagnostics() +void ClangToolsLogFileReaderTest::readFileWithDiagnostics() { const QString filePath = testFilePath(QLatin1String("/data/someDiagnostics.plist")); QString errorMessage; - const QList<Diagnostic> diagnostics = LogFileReader::read(filePath, &errorMessage); + const QList<Diagnostic> diagnostics = LogFileReader::readPlist(filePath, &errorMessage); QVERIFY(errorMessage.isEmpty()); QVERIFY(!diagnostics.isEmpty()); @@ -157,6 +157,6 @@ void ClangStaticAnalyzerLogFileReaderTest::readFileWithDiagnostics() QCOMPARE(step2.extendedMessage, step2.message); } -QTEST_MAIN(ClangStaticAnalyzerLogFileReaderTest) +QTEST_MAIN(ClangToolsLogFileReaderTest) -#include "tst_clangstaticanalyzerlogfilereader.moc" +#include "tst_clangtoolslogfilereader.moc" diff --git a/tests/auto/clangstaticanalyzer/clangstaticanalyzertest.pri b/tests/auto/clangtools/clangtoolstest.pri index 4f4c74ff30d..8d194121e9e 100644 --- a/tests/auto/clangstaticanalyzer/clangstaticanalyzertest.pri +++ b/tests/auto/clangtools/clangtoolstest.pri @@ -2,4 +2,4 @@ QTC_LIB_DEPENDS += utils QTC_PLUGIN_DEPENDS += debugger include(../qttest.pri) -PLUGINDIR=$$IDE_SOURCE_TREE/src/plugins/clangstaticanalyzer +PLUGINDIR=$$IDE_SOURCE_TREE/src/plugins/clangtools diff --git a/tests/auto/cplusplus/cxx11/cxx11.pro b/tests/auto/cplusplus/cxx11/cxx11.pro index f1b414bc784..51ed3028f0b 100644 --- a/tests/auto/cplusplus/cxx11/cxx11.pro +++ b/tests/auto/cplusplus/cxx11/cxx11.pro @@ -7,6 +7,8 @@ SOURCES += tst_cxx11.cpp DISTFILES += \ data/inlineNamespace.1.cpp \ data/inlineNamespace.1.errors.txt \ + data/nestedNamespace.1.cpp \ + data/nestedNamespace.1.errors.txt \ data/staticAssert.1.cpp \ data/staticAssert.1.errors.txt \ data/noExcept.1.cpp \ diff --git a/tests/auto/cplusplus/cxx11/data/nestedNamespace.1.cpp b/tests/auto/cplusplus/cxx11/data/nestedNamespace.1.cpp new file mode 100644 index 00000000000..92a42a33ad1 --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/nestedNamespace.1.cpp @@ -0,0 +1,7 @@ + +namespace A::B::C { + class Foo { + + }; +} + diff --git a/tests/auto/cplusplus/cxx11/data/nestedNamespace.1.errors.txt b/tests/auto/cplusplus/cxx11/data/nestedNamespace.1.errors.txt new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/auto/cplusplus/cxx11/data/nestedNamespace.1.errors.txt diff --git a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp index a39f367473e..108d93f18f7 100644 --- a/tests/auto/cplusplus/cxx11/tst_cxx11.cpp +++ b/tests/auto/cplusplus/cxx11/tst_cxx11.cpp @@ -176,6 +176,7 @@ void tst_cxx11::parse_data() QTest::addColumn<QString>("errorFile"); QTest::newRow("inlineNamespace.1") << "inlineNamespace.1.cpp" << "inlineNamespace.1.errors.txt"; + QTest::newRow("nestedNamespace.1") << "nestedNamespace.1.cpp" << "nestedNamespace.1.errors.txt"; QTest::newRow("staticAssert.1") << "staticAssert.1.cpp" << "staticAssert.1.errors.txt"; QTest::newRow("noExcept.1") << "noExcept.1.cpp" << "noExcept.1.errors.txt"; QTest::newRow("braceInitializers.1") << "braceInitializers.1.cpp" << "braceInitializers.1.errors.txt"; diff --git a/tests/auto/debugger/tst_dumpers.cpp b/tests/auto/debugger/tst_dumpers.cpp index 2e15b15c88d..9ac49187bae 100644 --- a/tests/auto/debugger/tst_dumpers.cpp +++ b/tests/auto/debugger/tst_dumpers.cpp @@ -37,8 +37,6 @@ #endif // Q_CC_MSVC #endif // Q_OS_WIN -#include <utils/asconst.h> - #include <QtTest> #include <math.h> @@ -1450,7 +1448,7 @@ void tst_Dumpers::dumper() QSet<QString> expandedINames; expandedINames.insert("local"); - for (const Check &check : Utils::asConst(data.checks)) { + for (const Check &check : qAsConst(data.checks)) { QString parent = check.iname; while (true) { parent = parentIName(parent); @@ -1462,7 +1460,7 @@ void tst_Dumpers::dumper() QString expanded; QString expandedq; - for (const QString &iname : Utils::asConst(expandedINames)) { + for (const QString &iname : qAsConst(expandedINames)) { if (!expanded.isEmpty()) { expanded.append(','); expandedq.append(','); @@ -1641,7 +1639,7 @@ void tst_Dumpers::dumper() WatchItem local; local.iname = "local"; - for (const GdbMi &child : Utils::asConst(actual.children())) { + for (const GdbMi &child : qAsConst(actual.children())) { const QString iname = child["iname"].data(); if (iname == "local.qtversion") context.qtVersion = child["value"].toInt(); @@ -1719,7 +1717,7 @@ void tst_Dumpers::dumper() if (!data.checks.isEmpty()) { qDebug() << "SOME TESTS NOT EXECUTED: "; - for (const Check &check : Utils::asConst(data.checks)) { + for (const Check &check : qAsConst(data.checks)) { if (check.optionallyPresent) { qDebug() << " OPTIONAL TEST NOT FOUND FOR INAME: " << check.iname << " IGNORED."; } else { @@ -1938,8 +1936,9 @@ void tst_Dumpers::dumper_data() "FooFlags f1(a);\n" "FooFlags f2(a | b);\n") + CoreProfile() - + Check("f1", "a (1)", TypeDef("QFlags<enum Foo>", "FooFlags")) - + Check("f2", "(a | b) (3)", "FooFlags") % GdbEngine; + + Check("f1", "a (1)", TypeDef("QFlags<enum Foo>", "FooFlags")) % CdbEngine + + Check("f1", "a (0x0001)", "FooFlags") % NoCdbEngine + + Check("f2", "a | b (0x0003)", "FooFlags") % GdbEngine; QTest::newRow("QDateTime") << Data("#include <QDateTime>\n", diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.cpp b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.cpp index 98cfc0e7d4c..bd8c3fd50ee 100644 --- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.cpp +++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.cpp @@ -25,15 +25,8 @@ #include "plugin1.h" -#include <qplugin.h> -#include <QStringList> - using namespace Plugin1; -MyPlugin1::MyPlugin1() -{ -} - bool MyPlugin1::initialize(const QStringList &arguments, QString *errorString) { Q_UNUSED(arguments) diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.h b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.h index 556fc0ba6fc..4fe8e95fc37 100644 --- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.h +++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin1/plugin1.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QtGlobal> - #if defined(PLUGIN1_LIBRARY) # define PLUGIN1_EXPORT Q_DECL_EXPORT #else @@ -44,10 +41,10 @@ class PLUGIN1_EXPORT MyPlugin1 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin1.json") public: - MyPlugin1(); + MyPlugin1() = default; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; }; } // namespace Plugin1 diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.cpp b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.cpp index 4d1bb259b74..3e6367dc3d8 100644 --- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.cpp +++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.cpp @@ -25,14 +25,8 @@ #include "plugin2.h" -#include <qplugin.h> - using namespace Plugin2; -MyPlugin2::MyPlugin2() -{ -} - bool MyPlugin2::initialize(const QStringList &, QString *) { return true; diff --git a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.h b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.h index e5e38e33005..adaf926905e 100644 --- a/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.h +++ b/tests/auto/extensionsystem/pluginmanager/circularplugins/plugin2/plugin2.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QtGlobal> - #if defined(PLUGIN2_LIBRARY) # define PLUGIN2_EXPORT Q_DECL_EXPORT #else @@ -44,10 +41,10 @@ class PLUGIN2_EXPORT MyPlugin2 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin2.json") public: - MyPlugin2(); + MyPlugin2() = default; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; }; } // Plugin2 diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.cpp b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.cpp index 6405c266688..0bb1fc88429 100644 --- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.cpp +++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.cpp @@ -27,22 +27,20 @@ #include <extensionsystem/pluginmanager.h> -#include <qplugin.h> -#include <QObject> - using namespace Plugin1; -MyPlugin1::MyPlugin1() - : initializeCalled(false) +MyPlugin1::~MyPlugin1() { + ExtensionSystem::PluginManager::removeObject(object1); + ExtensionSystem::PluginManager::removeObject(object2); } bool MyPlugin1::initialize(const QStringList & /*arguments*/, QString *errorString) { initializeCalled = true; - QObject *obj = new QObject; - obj->setObjectName(QLatin1String("MyPlugin1")); - addAutoReleasedObject(obj); + object1 = new QObject(this); + object1->setObjectName(QLatin1String("MyPlugin1")); + ExtensionSystem::PluginManager::addObject(object1); bool found2 = false; bool found3 = false; @@ -70,8 +68,8 @@ void MyPlugin1::extensionsInitialized() if (!initializeCalled) return; // don't do this at home, it's just done here for the test - QObject *obj = new QObject; - obj->setObjectName(QLatin1String("MyPlugin1_running")); - addAutoReleasedObject(obj); + object2 = new QObject(this); + object2->setObjectName(QLatin1String("MyPlugin1_running")); + ExtensionSystem::PluginManager::addObject(object2); } diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.h b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.h index 6a0d4c7f09a..a449f279545 100644 --- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.h +++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin1/plugin1.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QtGlobal> - #if defined(PLUGIN1_LIBRARY) # define PLUGIN1_EXPORT Q_DECL_EXPORT #else @@ -44,13 +41,16 @@ class PLUGIN1_EXPORT MyPlugin1 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin1.json") public: - MyPlugin1(); + MyPlugin1() = default; + ~MyPlugin1() final; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; private: - bool initializeCalled; + bool initializeCalled = false; + QObject *object1 = nullptr; + QObject *object2 = nullptr; }; } // namespace Plugin1 diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.cpp b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.cpp index cefdec9d101..3a9b60099f2 100644 --- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.cpp +++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.cpp @@ -27,22 +27,20 @@ #include <extensionsystem/pluginmanager.h> -#include <qplugin.h> -#include <QObject> - using namespace Plugin2; -MyPlugin2::MyPlugin2() - : initializeCalled(false) +MyPlugin2::~MyPlugin2() { + ExtensionSystem::PluginManager::removeObject(object1); + ExtensionSystem::PluginManager::removeObject(object2); } bool MyPlugin2::initialize(const QStringList &, QString *) { initializeCalled = true; - QObject *obj = new QObject; - obj->setObjectName(QLatin1String("MyPlugin2")); - addAutoReleasedObject(obj); + object1 = new QObject(this); + object1->setObjectName("MyPlugin2"); + ExtensionSystem::PluginManager::addObject(object1); return true; } @@ -52,8 +50,8 @@ void MyPlugin2::extensionsInitialized() if (!initializeCalled) return; // don't do this at home, it's just done here for the test - QObject *obj = new QObject; - obj->setObjectName(QLatin1String("MyPlugin2_running")); - addAutoReleasedObject(obj); + object2 = new QObject(this); + object2->setObjectName("MyPlugin2_running"); + ExtensionSystem::PluginManager::addObject(object2); } diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.h b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.h index 1a5ff1eb5ce..1cf5d217e99 100644 --- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.h +++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin2/plugin2.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QtGlobal> - #if defined(PLUGIN2_LIBRARY) # define PLUGIN2_EXPORT Q_DECL_EXPORT #else @@ -44,13 +41,16 @@ class PLUGIN2_EXPORT MyPlugin2 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin2.json") public: - MyPlugin2(); + MyPlugin2() = default; + ~MyPlugin2() final; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; private: - bool initializeCalled; + bool initializeCalled = false; + QObject *object1 = nullptr; + QObject *object2 = nullptr; }; } // namespace Plugin2 diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.cpp b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.cpp index b5f32ea1c77..a75ee58241e 100644 --- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.cpp +++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.cpp @@ -27,22 +27,20 @@ #include <extensionsystem/pluginmanager.h> -#include <qplugin.h> -#include <QObject> - using namespace Plugin3; -MyPlugin3::MyPlugin3() - : initializeCalled(false) +MyPlugin3::~MyPlugin3() { + ExtensionSystem::PluginManager::removeObject(object1); + ExtensionSystem::PluginManager::removeObject(object2); } bool MyPlugin3::initialize(const QStringList & /*arguments*/, QString *errorString) { initializeCalled = true; - QObject *obj = new QObject; - obj->setObjectName(QLatin1String("MyPlugin3")); - addAutoReleasedObject(obj); + object1 = new QObject(this); + object1->setObjectName(QLatin1String("MyPlugin3")); + ExtensionSystem::PluginManager::addObject(object1); bool found2 = false; foreach (QObject *object, ExtensionSystem::PluginManager::allObjects()) { @@ -61,7 +59,7 @@ void MyPlugin3::extensionsInitialized() if (!initializeCalled) return; // don't do this at home, it's just done here for the test - QObject *obj = new QObject; - obj->setObjectName(QLatin1String("MyPlugin3_running")); - addAutoReleasedObject(obj); + object2 = new QObject(this); + object2->setObjectName(QLatin1String("MyPlugin3_running")); + ExtensionSystem::PluginManager::addObject(object2); } diff --git a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.h b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.h index a8bfb4e7b64..bbc1e4d54d0 100644 --- a/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.h +++ b/tests/auto/extensionsystem/pluginmanager/correctplugins1/plugin3/plugin3.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QtGlobal> - #if defined(PLUGIN3_LIBRARY) # define PLUGIN3_EXPORT Q_DECL_EXPORT #else @@ -44,13 +41,16 @@ class PLUGIN3_EXPORT MyPlugin3 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin3.json") public: - MyPlugin3(); + MyPlugin3() = default; + ~MyPlugin3() final; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; private: - bool initializeCalled; + bool initializeCalled = false; + QObject *object1 = nullptr; + QObject *object2 = nullptr; }; } // namespace Plugin3 diff --git a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp index 01b92352a71..28696e73499 100644 --- a/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp +++ b/tests/auto/extensionsystem/pluginmanager/tst_pluginmanager.cpp @@ -44,7 +44,6 @@ private slots: void cleanup(); void addRemoveObjects(); void getObject(); - void getObjects(); void circularPlugins(); void correctPlugins1(); @@ -140,10 +139,8 @@ void tst_PluginManager::getObject() object2b->setObjectName(objectName); m_pm->addObject(object2); QCOMPARE(m_pm->getObject<MyClass11>(), static_cast<MyClass11 *>(0)); - QCOMPARE(m_pm->getObjectByClassName("MyClass11"), static_cast<QObject*>(0)); QCOMPARE(m_pm->getObject<MyClass1>(), static_cast<MyClass1 *>(0)); QCOMPARE(m_pm->getObject<MyClass2>(), object2); - QCOMPARE(m_pm->getObjectByClassName("MyClass2"), object2); m_pm->addObject(object11); QCOMPARE(m_pm->getObject<MyClass11>(), object11); QCOMPARE(m_pm->getObject<MyClass1>(), qobject_cast<MyClass1 *>(object11)); @@ -161,40 +158,6 @@ void tst_PluginManager::getObject() delete object2b; } -void tst_PluginManager::getObjects() -{ - MyClass1 *object1 = new MyClass1; - MyClass2 *object2 = new MyClass2; - MyClass11 *object11 = new MyClass11; - m_pm->addObject(object2); - QCOMPARE(m_pm->getObjects<MyClass11>(), QList<MyClass11*>()); - QCOMPARE(m_pm->getObjects<MyClass1>(), QList<MyClass1*>()); - QCOMPARE(m_pm->getObjects<MyClass2>(), QList<MyClass2*>() << object2); - QCOMPARE(m_pm->allObjects(), QList<QObject*>() << object2); - m_pm->addObject(object11); - QCOMPARE(m_pm->getObjects<MyClass11>(), QList<MyClass11*>() << object11); - QCOMPARE(m_pm->getObjects<MyClass1>(), QList<MyClass1*>() << object11); - QCOMPARE(m_pm->getObjects<MyClass2>(), QList<MyClass2*>() << object2); - QCOMPARE(m_pm->allObjects(), QList<QObject*>() << object2 << object11); - m_pm->addObject(object1); - QCOMPARE(m_pm->getObjects<MyClass11>(), QList<MyClass11*>() << object11); - QCOMPARE(m_pm->getObjects<MyClass1>(), QList<MyClass1*>() << object11 << object1); - QCOMPARE(m_pm->getObjects<MyClass2>(), QList<MyClass2*>() << object2); - QCOMPARE(m_pm->allObjects(), QList<QObject*>() << object2 << object11 << object1); - - QCOMPARE(m_pm->getObjects<MyClass1>( - [](MyClass1 *o){ - return !qobject_cast<MyClass11 *>(o);} ), - QList<MyClass1 *>() << object1); - - m_pm->removeObject(object2); - m_pm->removeObject(object11); - m_pm->removeObject(object1); - delete object1; - delete object2; - delete object11; -} - void tst_PluginManager::circularPlugins() { m_pm->setPluginPaths(QStringList() << pluginFolder(QLatin1String("circularplugins"))); diff --git a/tests/auto/flamegraph/flamegraph.pro b/tests/auto/flamegraph/flamegraph.pro deleted file mode 100644 index 6ea151f4c92..00000000000 --- a/tests/auto/flamegraph/flamegraph.pro +++ /dev/null @@ -1,5 +0,0 @@ -QTC_LIB_DEPENDS += flamegraph -include(../qttest.pri) - -QT += quick -SOURCES += tst_flamegraph.cpp diff --git a/tests/auto/flamegraph/flamegraph.qbs b/tests/auto/flamegraph/flamegraph.qbs deleted file mode 100644 index de00698243b..00000000000 --- a/tests/auto/flamegraph/flamegraph.qbs +++ /dev/null @@ -1,9 +0,0 @@ -import qbs - -QtcAutotest { - name: "FlameGraph autotest" - Depends { name: "FlameGraph" } - Depends { name: "Qt.quick" } - Depends { name: "Qt.gui" } - files: "tst_flamegraph.cpp" -} diff --git a/tests/auto/pointeralgorithm/pointeralgorithm.pro b/tests/auto/pointeralgorithm/pointeralgorithm.pro new file mode 100644 index 00000000000..9a71c27da1b --- /dev/null +++ b/tests/auto/pointeralgorithm/pointeralgorithm.pro @@ -0,0 +1,4 @@ +include(../qttest.pri) + +SOURCES += tst_pointeralgorithm.cpp +OTHER_FILES += $$IDE_SOURCE_TREE/src/libs/utils/pointeralgorithm.h diff --git a/tests/auto/pointeralgorithm/pointeralgorithm.qbs b/tests/auto/pointeralgorithm/pointeralgorithm.qbs new file mode 100644 index 00000000000..838ecfe2e92 --- /dev/null +++ b/tests/auto/pointeralgorithm/pointeralgorithm.qbs @@ -0,0 +1,10 @@ +import qbs + +QtcAutotest { + name: "PointerAlgorithm autotest" + + cpp.includePaths: [project.ide_source_tree + "/src/libs"] + files: [ + "tst_pointeralgorithm.cpp", + ] +} diff --git a/tests/auto/pointeralgorithm/tst_pointeralgorithm.cpp b/tests/auto/pointeralgorithm/tst_pointeralgorithm.cpp new file mode 100644 index 00000000000..d160768c5fc --- /dev/null +++ b/tests/auto/pointeralgorithm/tst_pointeralgorithm.cpp @@ -0,0 +1,324 @@ +/**************************************************************************** +** +** 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 <QtTest> + +#include <array> +#include <deque> +#include <list> +#include <memory> +#include <unordered_map> +#include <unordered_set> +#include <valarray> + +// must get included after the containers above or gcc4.9 will have a problem using +// initializer_list related code on the templates inside algorithm.h +#include <utils/pointeralgorithm.h> + +class tst_PointerAlgorithm : public QObject +{ + Q_OBJECT + +private slots: + void anyOf(); + void count(); + void contains(); + void findOr(); + void findOrDefault(); + void toRawPointer(); + void toReferences(); + void take(); + void takeOrDefault(); +}; + + +int stringToInt(const QString &s) +{ + return s.toInt(); +} + +namespace { + +struct BaseStruct +{ + BaseStruct(int m) : member(m) {} + bool operator==(const BaseStruct &other) const { return member == other.member; } + + int member; +}; + +struct Struct : public BaseStruct +{ + Struct(int m) : BaseStruct(m) {} + bool isOdd() const { return member % 2 == 1; } + bool isEven() const { return !isOdd(); } + + int getMember() const { return member; } + +}; +} + +void tst_PointerAlgorithm::anyOf() +{ + { + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + + QVERIFY(Utils::anyOf(vector, ptrVector.at(0))); + int foo = 42; + QVERIFY(!Utils::anyOf(vector, &foo)); + QVERIFY(Utils::anyOf(vector, nullptr)); + } + { + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + + QVERIFY(!Utils::anyOf(vector, nullptr)); + } +} + +void tst_PointerAlgorithm::count() +{ + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::unique_ptr<int>()); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + + QCOMPARE(Utils::count(vector, ptrVector.at(0)), 1); + int foo = 42; + QCOMPARE(Utils::count(vector, &foo), 0); + QCOMPARE(Utils::count(vector, nullptr), 2); +} + +void tst_PointerAlgorithm::contains() +{ + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + + QVERIFY(Utils::contains(vector, ptrVector.at(0))); + int foo = 42; + QVERIFY(!Utils::contains(vector, &foo)); + QVERIFY(Utils::contains(vector, nullptr)); +} + +void tst_PointerAlgorithm::findOr() +{ + { + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(2)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + + int foo = 42; + int bar = 23; + QVERIFY(Utils::findOr(vector, &foo, ptrVector.at(0)) == ptrVector.at(0)); + QVERIFY(Utils::findOr(vector, nullptr, &foo) == nullptr); + QVERIFY(Utils::findOr(vector, &foo, nullptr) == nullptr); + QVERIFY(Utils::findOr(vector, &foo, &bar) == &foo); + + QCOMPARE(Utils::findOr(vector, &foo, + [](const std::unique_ptr<int> &ip) { return ip && *ip == 2; }), + ptrVector.at(1)); + QCOMPARE(Utils::findOr(vector, &foo, + [](const std::unique_ptr<int> &ip) { return ip && *ip == 43; }), + &foo); + } + { + std::vector<std::unique_ptr<Struct>> v3; + v3.emplace_back(std::make_unique<Struct>(1)); + v3.emplace_back(std::make_unique<Struct>(3)); + v3.emplace_back(std::make_unique<Struct>(5)); + v3.emplace_back(std::make_unique<Struct>(7)); + Struct defS(6); + QCOMPARE(Utils::findOr(v3, &defS, &Struct::isOdd), v3.at(0).get()); + QCOMPARE(Utils::findOr(v3, &defS, &Struct::isEven), &defS); + } + { + std::vector<std::shared_ptr<Struct>> v4; + v4.emplace_back(std::make_shared<Struct>(1)); + v4.emplace_back(std::make_shared<Struct>(3)); + v4.emplace_back(std::make_shared<Struct>(5)); + v4.emplace_back(std::make_shared<Struct>(7)); + std::shared_ptr<Struct> sharedDefS = std::make_shared<Struct>(6); + QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isOdd), v4.at(0)); + QCOMPARE(Utils::findOr(v4, sharedDefS, &Struct::isEven), sharedDefS); + } +} + +void tst_PointerAlgorithm::findOrDefault() +{ + { + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + + int foo = 42; + QVERIFY(Utils::findOrDefault(vector, ptrVector.at(0)) == ptrVector.at(0)); + QVERIFY(Utils::findOrDefault(vector, &foo) == nullptr); + } + { + std::vector<std::unique_ptr<int>> v2; + v2.emplace_back(std::make_unique<int>(1)); + v2.emplace_back(std::make_unique<int>(2)); + v2.emplace_back(std::make_unique<int>(3)); + v2.emplace_back(std::make_unique<int>(4)); + QCOMPARE(Utils::findOrDefault(v2, [](const std::unique_ptr<int> &ip) { return *ip == 2; }), v2.at(1).get()); + QCOMPARE(Utils::findOrDefault(v2, [](const std::unique_ptr<int> &ip) { return *ip == 5; }), static_cast<int*>(nullptr)); + } + { + std::vector<std::unique_ptr<Struct>> v3; + v3.emplace_back(std::make_unique<Struct>(1)); + v3.emplace_back(std::make_unique<Struct>(3)); + v3.emplace_back(std::make_unique<Struct>(5)); + v3.emplace_back(std::make_unique<Struct>(7)); + QCOMPARE(Utils::findOrDefault(v3, &Struct::isOdd), v3.at(0).get()); + QCOMPARE(Utils::findOrDefault(v3, &Struct::isEven), static_cast<Struct*>(nullptr)); + } +} + +void tst_PointerAlgorithm::toRawPointer() +{ + const std::vector<std::unique_ptr<Struct>> v; + + // same result container + const std::vector<Struct *> x1 = Utils::toRawPointer(v); + // different result container + const std::vector<Struct *> x2 = Utils::toRawPointer<std::vector>(v); + const QVector<Struct *> x3 = Utils::toRawPointer<QVector>(v); + const std::list<Struct *> x4 = Utils::toRawPointer<std::list>(v); + // different fully specified result container + const std::vector<BaseStruct *> x5 = Utils::toRawPointer<std::vector<BaseStruct *>>(v); + const QVector<BaseStruct *> x6 = Utils::toRawPointer<QVector<BaseStruct *>>(v); +} + +void tst_PointerAlgorithm::toReferences() +{ + // toReference + { + // std::vector -> std::vector + std::vector<Struct> v; + const std::vector<std::reference_wrapper<Struct>> x = Utils::toReferences(v); + } + { + // QList -> std::vector + QList<Struct> v; + const std::vector<std::reference_wrapper<Struct>> x = Utils::toReferences<std::vector>(v); + } + { + // std::vector -> QList + std::vector<Struct> v; + const QList<std::reference_wrapper<Struct>> x = Utils::toReferences<QList>(v); + } + { + // std::vector -> std::list + std::vector<Struct> v; + const std::list<std::reference_wrapper<Struct>> x = Utils::toReferences<std::list>(v); + } + // toConstReference + { + // std::vector -> std::vector + const std::vector<Struct> v; + const std::vector<std::reference_wrapper<const Struct>> x = Utils::toConstReferences(v); + } + { + // QList -> std::vector + const QList<Struct> v; + const std::vector<std::reference_wrapper<const Struct>> x + = Utils::toConstReferences<std::vector>(v); + } + { + // std::vector -> QList + const std::vector<Struct> v; + const QList<std::reference_wrapper<const Struct>> x = Utils::toConstReferences<QList>(v); + } + { + // std::vector -> std::list + const std::vector<Struct> v; + const std::list<std::reference_wrapper<const Struct>> x + = Utils::toConstReferences<std::list>(v); + } +} + +void tst_PointerAlgorithm::take() +{ + { + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(2)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + int foo = 42; + + QVERIFY(Utils::take(vector, ptrVector.at(0)).value().get() == ptrVector.at(0)); + QVERIFY(Utils::take(vector, ptrVector.at(0)) == Utils::nullopt); + QVERIFY(Utils::take(vector, &foo) == Utils::nullopt); + QVERIFY(Utils::take(vector, nullptr).value().get() == nullptr); + } +} + +void tst_PointerAlgorithm::takeOrDefault() +{ + { + std::vector<std::unique_ptr<int>> vector; + vector.emplace_back(std::make_unique<int>(5)); + vector.emplace_back(std::make_unique<int>(2)); + vector.emplace_back(std::make_unique<int>(6)); + vector.emplace_back(std::make_unique<int>(7)); + vector.emplace_back(std::unique_ptr<int>()); + std::vector<int *> ptrVector = Utils::toRawPointer(vector); + int foo = 42; + + QVERIFY(Utils::takeOrDefault(vector, ptrVector.at(0)).get() == ptrVector.at(0)); + QVERIFY(Utils::takeOrDefault(vector, ptrVector.at(0)).get() == nullptr); + QVERIFY(Utils::takeOrDefault(vector, &foo).get() == nullptr); + QVERIFY(Utils::takeOrDefault(vector, nullptr).get() == nullptr); + } +} + +QTEST_MAIN(tst_PointerAlgorithm) + +#include "tst_pointeralgorithm.moc" diff --git a/tests/auto/qml/codemodel/check/properties.qml b/tests/auto/qml/codemodel/check/properties.qml new file mode 100644 index 00000000000..5d2b0a68820 --- /dev/null +++ b/tests/auto/qml/codemodel/check/properties.qml @@ -0,0 +1,10 @@ +import QtQuick 1.0 + +Item { + property int width: 200 + property int height: 200 + property string name + property color someColor + property Rectangle someRectangle + default property list<QtObject> foo +} diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp index 6f8e390a05a..af4723c8729 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.cpp @@ -64,14 +64,6 @@ #include <QPlainTextEdit> -#if QT_VERSION >= 0x050000 -#define MSKIP_SINGLE(x) QSKIP(x) -#define MSKIP_ALL(x) QSKIP(x); -#else -#define MSKIP_SINGLE(x) QSKIP(x, SkipSingle) -#define MSKIP_ALL(x) QSKIP(x, SkipAll) -#endif - //TESTED_COMPONENT=src/plugins/qmldesigner/designercore using namespace QmlDesigner; @@ -1392,7 +1384,7 @@ void tst_TestCore::testBasicStatesQtQuick20() qDebug() << rootModelNode.nodeListProperty("states").toModelNodeList().first().metaInfo().majorVersion(); qDebug() << rootModelNode.nodeListProperty("states").toModelNodeList().first().metaInfo().typeName(); - MSKIP_ALL("No qml2puppet"); + QSKIP("No qml2puppet"); QScopedPointer<TestView> view(new TestView(model.data())); QVERIFY(view.data()); @@ -4198,7 +4190,7 @@ void tst_TestCore::testMetaInfoEnums() QApplication::processEvents(); } -void tst_TestCore::testMetaInfoQtQuick1Vs2() +void tst_TestCore::testMetaInfoQtQuickVersion2() { char qmlString[] = "import QtQuick 2.0\n" "Rectangle {\n" @@ -8013,7 +8005,7 @@ void tst_TestCore::loadTestFiles() QCOMPARE(rootModelNode.nodeListProperty("states").toModelNodeList().count(), 2); } - MSKIP_ALL("Fails because the text editor model doesn't know about components"); + QSKIP("Fails because the text editor model doesn't know about components"); { //usingbutton.qml QFile file(":/fx/usingbutton.qml"); QVERIFY(file.open(QIODevice::ReadOnly | QIODevice::Text)); diff --git a/tests/auto/qml/qmldesigner/coretests/tst_testcore.h b/tests/auto/qml/qmldesigner/coretests/tst_testcore.h index def024c63f3..cde63a12d1c 100644 --- a/tests/auto/qml/qmldesigner/coretests/tst_testcore.h +++ b/tests/auto/qml/qmldesigner/coretests/tst_testcore.h @@ -56,7 +56,7 @@ private slots: void testMetaInfoEnums(); void testMetaInfoProperties(); void testMetaInfoDotProperties(); - void testMetaInfoQtQuick1Vs2(); + void testMetaInfoQtQuickVersion2(); void testMetaInfoListProperties(); void testQtQuick20Basic(); void testQtQuick20BasicRectangle(); diff --git a/tests/auto/qml/reformatter/objectliteral.js b/tests/auto/qml/reformatter/objectliteral.js index 9c8bfc46f1d..37f68633746 100644 --- a/tests/auto/qml/reformatter/objectliteral.js +++ b/tests/auto/qml/reformatter/objectliteral.js @@ -1,12 +1,12 @@ var x = { - x: 12, - y: { - x: 12, - y: "abc", - z: function (x) { + "x": 12, + "y": { + "x": 12, + "y": "abc", + "z": function (x) { return a }, - abc: 15 + "abc": 15 }, - z: 12 + "z": 12 } diff --git a/tests/auto/tracing/flamegraph/flamegraph.pro b/tests/auto/tracing/flamegraph/flamegraph.pro new file mode 100644 index 00000000000..b668b987d10 --- /dev/null +++ b/tests/auto/tracing/flamegraph/flamegraph.pro @@ -0,0 +1,7 @@ +QT += quick + +QTC_LIB_DEPENDS += tracing +include(../../qttest.pri) + +SOURCES += \ + tst_flamegraph.cpp diff --git a/tests/auto/tracing/flamegraph/flamegraph.qbs b/tests/auto/tracing/flamegraph/flamegraph.qbs new file mode 100644 index 00000000000..7323dd7fb73 --- /dev/null +++ b/tests/auto/tracing/flamegraph/flamegraph.qbs @@ -0,0 +1,12 @@ +import qbs +import "../tracingautotest.qbs" as TracingAutotest + +TracingAutotest { + name: "FlameGraph autotest" + Group { + name: "Test sources" + files: [ + "tst_flamegraph.cpp" + ] + } +} diff --git a/tests/auto/flamegraph/tst_flamegraph.cpp b/tests/auto/tracing/flamegraph/tst_flamegraph.cpp index 4e249887b22..e8335e034c1 100644 --- a/tests/auto/flamegraph/tst_flamegraph.cpp +++ b/tests/auto/tracing/flamegraph/tst_flamegraph.cpp @@ -23,8 +23,8 @@ ** ****************************************************************************/ -#include <flamegraph/flamegraph.h> -#include <flamegraph/flamegraphattached.h> +#include <tracing/flamegraph.h> +#include <tracing/flamegraphattached.h> #include <QObject> #include <QStandardItemModel> #include <QQmlComponent> diff --git a/tests/auto/timeline/timelineabstractrenderer/timelineabstractrenderer.pro b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.pro index 60eea25e903..53038ebfdf7 100644 --- a/tests/auto/timeline/timelineabstractrenderer/timelineabstractrenderer.pro +++ b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelineabstractrenderer/timelineabstractrenderer.qbs b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.qbs index 5eabbb36726..99880dd7c95 100644 --- a/tests/auto/timeline/timelineabstractrenderer/timelineabstractrenderer.qbs +++ b/tests/auto/tracing/timelineabstractrenderer/timelineabstractrenderer.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineAbstractRenderer autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelineabstractrenderer/tst_timelineabstractrenderer.cpp b/tests/auto/tracing/timelineabstractrenderer/tst_timelineabstractrenderer.cpp index 10453ffcffe..e4f8e7b69d9 100644 --- a/tests/auto/timeline/timelineabstractrenderer/tst_timelineabstractrenderer.cpp +++ b/tests/auto/tracing/timelineabstractrenderer/tst_timelineabstractrenderer.cpp @@ -24,7 +24,8 @@ ****************************************************************************/ #include <QtTest> -#include <timeline/timelineabstractrenderer_p.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelineabstractrenderer_p.h> using namespace Timeline; @@ -82,10 +83,11 @@ void tst_TimelineAbstractRenderer::selectedItem() void tst_TimelineAbstractRenderer::model() { TimelineAbstractRenderer renderer; + TimelineModelAggregator aggregator; QSignalSpy spy(&renderer, SIGNAL(modelChanged(TimelineModel*))); QVERIFY(!renderer.modelDirty()); QCOMPARE(spy.count(), 0); - TimelineModel model(0); + TimelineModel model(&aggregator); QCOMPARE(renderer.model(), static_cast<TimelineModel *>(0)); renderer.setModel(&model); QVERIFY(renderer.modelDirty()); diff --git a/tests/auto/timeline/timelineitemsrenderpass/timelineitemsrenderpass.pro b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.pro index 1ac34f8c275..ba375915908 100644 --- a/tests/auto/timeline/timelineitemsrenderpass/timelineitemsrenderpass.pro +++ b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelineitemsrenderpass/timelineitemsrenderpass.qbs b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.qbs index 3e2eef8e29f..0ba6f6ca64b 100644 --- a/tests/auto/timeline/timelineitemsrenderpass/timelineitemsrenderpass.qbs +++ b/tests/auto/tracing/timelineitemsrenderpass/timelineitemsrenderpass.qbs @@ -1,8 +1,8 @@ import qbs import QtcFunctions -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineItemsRenderPass autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp b/tests/auto/tracing/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp index 1f26877f4f5..7a987332b82 100644 --- a/tests/auto/timeline/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp +++ b/tests/auto/tracing/timelineitemsrenderpass/tst_timelineitemsrenderpass.cpp @@ -23,9 +23,10 @@ ** ****************************************************************************/ -#include <timeline/runscenegraphtest.h> -#include <timeline/timelineitemsrenderpass.h> -#include <timeline/timelinerenderstate.h> +#include <tracing/runscenegraphtest.h> +#include <tracing/timelineitemsrenderpass.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelinerenderstate.h> #include <QtTest> #include <QSGMaterialShader> @@ -34,7 +35,7 @@ using namespace Timeline; class DummyModel : public TimelineModel { public: - DummyModel(); + DummyModel(TimelineModelAggregator *parent); void loadData(); float relativeHeight(int index) const; }; @@ -48,7 +49,7 @@ private slots: void update(); }; -DummyModel::DummyModel() : TimelineModel(12) +DummyModel::DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) { } @@ -77,13 +78,14 @@ void tst_TimelineItemsRenderPass::update() { const TimelineItemsRenderPass *inst = TimelineItemsRenderPass::instance(); TimelineAbstractRenderer renderer; + TimelineModelAggregator aggregator; TimelineRenderState parentState(0, 8, 1, 1); TimelineRenderPass::State *nullState = 0; QSGNode *nullNode = 0; TimelineRenderPass::State *result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1); QCOMPARE(result, nullState); - DummyModel model; + DummyModel model(&aggregator); renderer.setModel(&model); result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1); QCOMPARE(result, nullState); diff --git a/tests/auto/timeline/timelinemodel/timelinemodel.pro b/tests/auto/tracing/timelinemodel/timelinemodel.pro index a0b56add42c..a14fd3a09f9 100644 --- a/tests/auto/timeline/timelinemodel/timelinemodel.pro +++ b/tests/auto/tracing/timelinemodel/timelinemodel.pro @@ -1,4 +1,4 @@ -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinemodel/timelinemodel.qbs b/tests/auto/tracing/timelinemodel/timelinemodel.qbs index f4fc5f7be33..b936a29a14f 100644 --- a/tests/auto/timeline/timelinemodel/timelinemodel.qbs +++ b/tests/auto/tracing/timelinemodel/timelinemodel.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineModel autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinemodel/tst_timelinemodel.cpp b/tests/auto/tracing/timelinemodel/tst_timelinemodel.cpp index eb24474bd44..be527af1273 100644 --- a/tests/auto/timeline/timelinemodel/tst_timelinemodel.cpp +++ b/tests/auto/tracing/timelinemodel/tst_timelinemodel.cpp @@ -25,7 +25,8 @@ #include <QtTest> #include <QColor> -#include <timeline/timelinemodel_p.h> +#include <tracing/timelinemodel_p.h> +#include <tracing/timelinemodelaggregator.h> static const int NumItems = 32; static const qint64 ItemDuration = 1 << 19; @@ -36,8 +37,8 @@ class DummyModel : public Timeline::TimelineModel Q_OBJECT friend class tst_TimelineModel; public: - DummyModel(int modelId); - DummyModel(QString displayName = tr("dummy"), QObject *parent = 0); + DummyModel(Timeline::TimelineModelAggregator *parent); + DummyModel(QString displayName, Timeline::TimelineModelAggregator *parent); int expandedRow(int) const { return 2; } int collapsedRow(int) const { return 1; } @@ -54,7 +55,6 @@ public: tst_TimelineModel(); private slots: - void privateModel(); void isEmpty(); void modelId(); void rowHeight(); @@ -77,15 +77,18 @@ private slots: void rowCount(); void prevNext(); void parentingOfEqualStarts(); + +private: + Timeline::TimelineModelAggregator aggregator; }; -DummyModel::DummyModel(int modelId) : - Timeline::TimelineModel(modelId, 0) +DummyModel::DummyModel(Timeline::TimelineModelAggregator *parent) : + Timeline::TimelineModel(parent) { } -DummyModel::DummyModel(QString displayName, QObject *parent) : - TimelineModel(12, parent) +DummyModel::DummyModel(QString displayName, Timeline::TimelineModelAggregator *parent) : + TimelineModel(parent) { setDisplayName(displayName); } @@ -112,15 +115,9 @@ tst_TimelineModel::tst_TimelineModel() : { } -void tst_TimelineModel::privateModel() -{ - DummyModel dummy(15); - QCOMPARE(dummy.modelId(), 15); -} - void tst_TimelineModel::isEmpty() { - DummyModel dummy; + DummyModel dummy(&aggregator); QVERIFY(dummy.isEmpty()); dummy.loadData(); QVERIFY(!dummy.isEmpty()); @@ -130,13 +127,13 @@ void tst_TimelineModel::isEmpty() void tst_TimelineModel::modelId() { - DummyModel dummy; - QCOMPARE(dummy.modelId(), 12); + DummyModel dummy(&aggregator); + QCOMPARE(dummy.modelId(), aggregator.generateModelId() - 1); } void tst_TimelineModel::rowHeight() { - DummyModel dummy; + DummyModel dummy(&aggregator); QCOMPARE(dummy.rowHeight(0), DefaultRowHeight); QCOMPARE(dummy.collapsedRowHeight(0), DefaultRowHeight); QCOMPARE(dummy.expandedRowHeight(0), DefaultRowHeight); @@ -178,7 +175,7 @@ void tst_TimelineModel::rowHeight() void tst_TimelineModel::rowOffset() { - DummyModel dummy; + DummyModel dummy(&aggregator); QCOMPARE(dummy.rowOffset(0), 0); dummy.loadData(); @@ -215,7 +212,7 @@ void tst_TimelineModel::rowOffset() void tst_TimelineModel::height() { - DummyModel dummy; + DummyModel dummy(&aggregator); int heightAfterLastSignal = 0; int heightChangedSignals = 0; connect(&dummy, &Timeline::TimelineModel::heightChanged, [&](){ @@ -258,7 +255,7 @@ void tst_TimelineModel::height() void tst_TimelineModel::count() { - DummyModel dummy; + DummyModel dummy(&aggregator); QCOMPARE(dummy.count(), 0); dummy.loadData(); QCOMPARE(dummy.count(), NumItems); @@ -270,7 +267,7 @@ void tst_TimelineModel::count() void tst_TimelineModel::times() { - DummyModel dummy; + DummyModel dummy(&aggregator); dummy.loadData(); QCOMPARE(dummy.startTime(0), 0); QCOMPARE(dummy.duration(0), ItemDuration * 3 + 2); @@ -280,14 +277,14 @@ void tst_TimelineModel::times() void tst_TimelineModel::selectionId() { - DummyModel dummy; + DummyModel dummy(&aggregator); dummy.loadData(); QCOMPARE(dummy.selectionId(0), 4); } void tst_TimelineModel::firstLast() { - DummyModel dummy; + DummyModel dummy(&aggregator); QCOMPARE(dummy.firstIndex(0), -1); QCOMPARE(dummy.firstIndex(ItemSpacing), -1); QCOMPARE(dummy.lastIndex(0), -1); @@ -307,7 +304,7 @@ void tst_TimelineModel::firstLast() void tst_TimelineModel::expand() { - DummyModel dummy; + DummyModel dummy(&aggregator); QSignalSpy spy(&dummy, SIGNAL(expandedChanged())); QVERIFY(!dummy.expanded()); dummy.setExpanded(true); @@ -326,7 +323,7 @@ void tst_TimelineModel::expand() void tst_TimelineModel::hide() { - DummyModel dummy; + DummyModel dummy(&aggregator); QSignalSpy spy(&dummy, SIGNAL(hiddenChanged())); QVERIFY(!dummy.hidden()); dummy.setHidden(true); @@ -346,7 +343,7 @@ void tst_TimelineModel::hide() void tst_TimelineModel::displayName() { QLatin1String name("testest"); - DummyModel dummy(name); + DummyModel dummy(name, &aggregator); QSignalSpy spy(&dummy, SIGNAL(displayNameChanged())); QCOMPARE(dummy.displayName(), name); QCOMPARE(spy.count(), 0); @@ -361,7 +358,7 @@ void tst_TimelineModel::displayName() void tst_TimelineModel::defaultValues() { - Timeline::TimelineModel dummy(12); + Timeline::TimelineModel dummy(&aggregator); QCOMPARE(dummy.location(0), QVariantMap()); QCOMPARE(dummy.handlesTypeId(0), false); QCOMPARE(dummy.relativeHeight(0), 1.0); @@ -377,7 +374,7 @@ void tst_TimelineModel::defaultValues() void tst_TimelineModel::row() { - DummyModel dummy; + DummyModel dummy(&aggregator); dummy.loadData(); QCOMPARE(dummy.row(0), 1); dummy.setExpanded(true); @@ -386,33 +383,34 @@ void tst_TimelineModel::row() void tst_TimelineModel::colorByHue() { - DummyModel dummy; + Timeline::TimelineModelAggregator aggregator; + DummyModel dummy(&aggregator); QCOMPARE(dummy.colorByHue(10), QColor::fromHsl(10, 150, 166).rgb()); QCOMPARE(dummy.colorByHue(500), QColor::fromHsl(140, 150, 166).rgb()); } void tst_TimelineModel::colorBySelectionId() { - DummyModel dummy; + DummyModel dummy(&aggregator); dummy.loadData(); QCOMPARE(dummy.colorBySelectionId(5), QColor::fromHsl(6 * 25, 150, 166).rgb()); } void tst_TimelineModel::colorByFraction() { - DummyModel dummy; + DummyModel dummy(&aggregator); QCOMPARE(dummy.colorByFraction(0.5), QColor::fromHsl(0.5 * 96 + 10, 150, 166).rgb()); } void tst_TimelineModel::supportedRenderPasses() { - DummyModel dummy; + DummyModel dummy(&aggregator); QVERIFY(!dummy.supportedRenderPasses().isEmpty()); } void tst_TimelineModel::insertStartEnd() { - DummyModel dummy; + DummyModel dummy(&aggregator); int id = dummy.insertStart(10, 0); dummy.insertEnd(id, 10); QCOMPARE(dummy.startTime(id), 10); @@ -433,7 +431,7 @@ void tst_TimelineModel::insertStartEnd() void tst_TimelineModel::rowCount() { - DummyModel dummy; + DummyModel dummy(&aggregator); QSignalSpy expandedSpy(&dummy, SIGNAL(expandedRowCountChanged())); QSignalSpy collapsedSpy(&dummy, SIGNAL(collapsedRowCountChanged())); QCOMPARE(dummy.rowCount(), 1); @@ -453,7 +451,7 @@ void tst_TimelineModel::rowCount() void tst_TimelineModel::prevNext() { - DummyModel dummy; + DummyModel dummy(&aggregator); QCOMPARE(dummy.nextItemBySelectionId(5, 10, 5), -1); QCOMPARE(dummy.prevItemBySelectionId(5, 10, 5), -1); @@ -474,7 +472,7 @@ void tst_TimelineModel::prevNext() void tst_TimelineModel::parentingOfEqualStarts() { - DummyModel dummy; + DummyModel dummy(&aggregator); // Trick it so that it cannot reorder the events and has to parent them in the "wrong" way ... QCOMPARE(dummy.insert(1, 10, 998), 0); QCOMPARE(dummy.insertStart(1, 999), 1); diff --git a/tests/auto/timeline/timelinemodelaggregator/timelinemodelaggregator.pro b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.pro index 61a8a31c28e..8eff246b1b4 100644 --- a/tests/auto/timeline/timelinemodelaggregator/timelinemodelaggregator.pro +++ b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.pro @@ -1,4 +1,4 @@ -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinemodelaggregator/timelinemodelaggregator.qbs b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.qbs index 2531cf5c2e8..2329ae3ed1e 100644 --- a/tests/auto/timeline/timelinemodelaggregator/timelinemodelaggregator.qbs +++ b/tests/auto/tracing/timelinemodelaggregator/timelinemodelaggregator.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineModelAggregator autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinemodelaggregator/tst_timelinemodelaggregator.cpp b/tests/auto/tracing/timelinemodelaggregator/tst_timelinemodelaggregator.cpp index 5776e387522..fedd3dfafa8 100644 --- a/tests/auto/timeline/timelinemodelaggregator/tst_timelinemodelaggregator.cpp +++ b/tests/auto/tracing/timelinemodelaggregator/tst_timelinemodelaggregator.cpp @@ -24,7 +24,7 @@ ****************************************************************************/ #include <QtTest> -#include <timeline/timelinemodelaggregator.h> +#include <tracing/timelinemodelaggregator.h> class tst_TimelineModelAggregator : public QObject { @@ -38,7 +38,7 @@ private slots: class HeightTestModel : public Timeline::TimelineModel { public: - HeightTestModel() : TimelineModel(2) + HeightTestModel(Timeline::TimelineModelAggregator *parent) : TimelineModel(parent) { insert(0, 1, 1); } @@ -46,15 +46,15 @@ public: void tst_TimelineModelAggregator::height() { - Timeline::TimelineModelAggregator aggregator(0); + Timeline::TimelineModelAggregator aggregator; QCOMPARE(aggregator.height(), 0); QSignalSpy heightSpy(&aggregator, SIGNAL(heightChanged())); - Timeline::TimelineModel *model = new Timeline::TimelineModel(25); + Timeline::TimelineModel *model = new Timeline::TimelineModel(&aggregator); aggregator.addModel(model); QCOMPARE(aggregator.height(), 0); QCOMPARE(heightSpy.count(), 0); - aggregator.addModel(new HeightTestModel); + aggregator.addModel(new HeightTestModel(&aggregator)); QVERIFY(aggregator.height() > 0); QCOMPARE(heightSpy.count(), 1); aggregator.clear(); @@ -70,8 +70,8 @@ void tst_TimelineModelAggregator::addRemoveModel() QCOMPARE(aggregator.notes(), ¬es); - Timeline::TimelineModel *model1 = new Timeline::TimelineModel(25); - Timeline::TimelineModel *model2 = new Timeline::TimelineModel(26); + Timeline::TimelineModel *model1 = new Timeline::TimelineModel(&aggregator); + Timeline::TimelineModel *model2 = new Timeline::TimelineModel(&aggregator); aggregator.addModel(model1); QCOMPARE(spy.count(), 1); QCOMPARE(aggregator.modelCount(), 1); @@ -84,9 +84,9 @@ void tst_TimelineModelAggregator::addRemoveModel() QCOMPARE(aggregator.model(1), model2); QCOMPARE(aggregator.models().count(), 2); - QCOMPARE(aggregator.modelIndexById(25), 0); - QCOMPARE(aggregator.modelIndexById(26), 1); - QCOMPARE(aggregator.modelIndexById(27), -1); + QCOMPARE(aggregator.modelIndexById(model1->modelId()), 0); + QCOMPARE(aggregator.modelIndexById(model2->modelId()), 1); + QCOMPARE(aggregator.modelIndexById(aggregator.generateModelId()), -1); QCOMPARE(aggregator.modelOffset(0), 0); QCOMPARE(aggregator.modelOffset(1), 0); @@ -99,22 +99,23 @@ void tst_TimelineModelAggregator::addRemoveModel() class PrevNextTestModel : public Timeline::TimelineModel { public: - PrevNextTestModel(int x) : TimelineModel(x) + PrevNextTestModel(Timeline::TimelineModelAggregator *parent) : TimelineModel(parent) { for (int i = 0; i < 20; ++i) - insert(i + x, i * x, x); + insert(i + modelId(), i * modelId(), modelId()); } }; void tst_TimelineModelAggregator::prevNext() { - Timeline::TimelineModelAggregator aggregator(0); - aggregator.addModel(new PrevNextTestModel(1)); - aggregator.addModel(new PrevNextTestModel(2)); - aggregator.addModel(new PrevNextTestModel(3)); + Timeline::TimelineModelAggregator aggregator; + aggregator.generateModelId(); // start modelIds at 1 + aggregator.addModel(new PrevNextTestModel(&aggregator)); + aggregator.addModel(new PrevNextTestModel(&aggregator)); + aggregator.addModel(new PrevNextTestModel(&aggregator)); // Add an empty model to trigger the special code paths that skip it - aggregator.addModel(new Timeline::TimelineModel(4)); + aggregator.addModel(new Timeline::TimelineModel(&aggregator)); QLatin1String item("item"); QLatin1String model("model"); QVariantMap result; diff --git a/tests/auto/timeline/timelinenotesmodel/timelinenotesmodel.pro b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.pro index 47e00891ea6..bc7a68e570f 100644 --- a/tests/auto/timeline/timelinenotesmodel/timelinenotesmodel.pro +++ b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.pro @@ -1,4 +1,4 @@ -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinenotesmodel/timelinenotesmodel.qbs b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.qbs index b43cf6486a2..adcacb7d998 100644 --- a/tests/auto/timeline/timelinenotesmodel/timelinenotesmodel.qbs +++ b/tests/auto/tracing/timelinenotesmodel/timelinenotesmodel.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineNotesModel autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinenotesmodel/tst_timelinenotesmodel.cpp b/tests/auto/tracing/timelinenotesmodel/tst_timelinenotesmodel.cpp index df0f977cdee..dd861cb5a9e 100644 --- a/tests/auto/timeline/timelinenotesmodel/tst_timelinenotesmodel.cpp +++ b/tests/auto/tracing/timelinenotesmodel/tst_timelinenotesmodel.cpp @@ -25,7 +25,8 @@ #include <QtTest> #include <QColor> -#include <timeline/timelinenotesmodel.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelinenotesmodel.h> class tst_TimelineNotesModel : public QObject { @@ -37,11 +38,14 @@ private slots: void properties(); void selection(); void modify(); + +private: + Timeline::TimelineModelAggregator aggregator; }; class TestModel : public Timeline::TimelineModel { public: - TestModel(int modelId = 10) : TimelineModel(modelId) + TestModel(Timeline::TimelineModelAggregator *parent) : TimelineModel(parent) { insert(0, 10, 10); } @@ -59,11 +63,11 @@ class TestNotesModel : public Timeline::TimelineNotesModel { void tst_TimelineNotesModel::timelineModel() { TestNotesModel notes; - TestModel *model = new TestModel; - TestModel *model2 = new TestModel(2); + TestModel *model = new TestModel(&aggregator); + TestModel *model2 = new TestModel(&aggregator); notes.addTimelineModel(model); notes.addTimelineModel(model2); - QCOMPARE(notes.timelineModelByModelId(10), model); + QCOMPARE(notes.timelineModelByModelId(model->modelId()), model); QCOMPARE(notes.timelineModels().count(), 2); QVERIFY(notes.timelineModels().contains(model)); QVERIFY(notes.timelineModels().contains(model2)); @@ -78,11 +82,11 @@ void tst_TimelineNotesModel::timelineModel() void tst_TimelineNotesModel::addRemove() { TestNotesModel notes; - TestModel model; + TestModel model(&aggregator); notes.addTimelineModel(&model); QSignalSpy spy(¬es, SIGNAL(changed(int,int,int))); - int id = notes.add(10, 0, QLatin1String("xyz")); + int id = notes.add(model.modelId(), 0, QLatin1String("xyz")); QCOMPARE(spy.count(), 1); QCOMPARE(notes.isModified(), true); QCOMPARE(notes.count(), 1); @@ -99,32 +103,34 @@ void tst_TimelineNotesModel::properties() TestNotesModel notes; int id = -1; + int modelId = -1; { - TestModel model; + TestModel model(&aggregator); + modelId = model.modelId(); notes.addTimelineModel(&model); - id = notes.add(10, 0, QLatin1String("xyz")); + id = notes.add(model.modelId(), 0, QLatin1String("xyz")); QVERIFY(id >= 0); QCOMPARE(notes.typeId(id), 7); QCOMPARE(notes.timelineIndex(id), 0); - QCOMPARE(notes.timelineModel(id), 10); + QCOMPARE(notes.timelineModel(id), modelId); QCOMPARE(notes.text(id), QLatin1String("xyz")); } QCOMPARE(notes.typeId(id), -1); // cannot ask the model anymore QCOMPARE(notes.timelineIndex(id), 0); - QCOMPARE(notes.timelineModel(id), 10); + QCOMPARE(notes.timelineModel(id), modelId); QCOMPARE(notes.text(id), QLatin1String("xyz")); } void tst_TimelineNotesModel::selection() { TestNotesModel notes; - TestModel model; + TestModel model(&aggregator); notes.addTimelineModel(&model); - int id1 = notes.add(10, 0, QLatin1String("blablub")); - int id2 = notes.add(10, 0, QLatin1String("xyz")); - QVariantList ids = notes.byTimelineModel(10); + int id1 = notes.add(model.modelId(), 0, QLatin1String("blablub")); + int id2 = notes.add(model.modelId(), 0, QLatin1String("xyz")); + QVariantList ids = notes.byTimelineModel(model.modelId()); QCOMPARE(ids.length(), 2); QVERIFY(ids.contains(id1)); QVERIFY(ids.contains(id2)); @@ -134,19 +140,19 @@ void tst_TimelineNotesModel::selection() QVERIFY(ids.contains(id1)); QVERIFY(ids.contains(id2)); - int got = notes.get(10, 0); + int got = notes.get(model.modelId(), 0); QVERIFY(got == id1 || got == id2); - QCOMPARE(notes.get(10, 20), -1); - QCOMPARE(notes.get(20, 10), -1); + QCOMPARE(notes.get(model.modelId(), 20), -1); + QCOMPARE(notes.get(model.modelId() + 10, 10), -1); } void tst_TimelineNotesModel::modify() { TestNotesModel notes; - TestModel model; + TestModel model(&aggregator); notes.addTimelineModel(&model); QSignalSpy spy(¬es, SIGNAL(changed(int,int,int))); - int id = notes.add(10, 0, QLatin1String("a")); + int id = notes.add(model.modelId(), 0, QLatin1String("a")); QCOMPARE(spy.count(), 1); notes.resetModified(); notes.update(id, QLatin1String("b")); @@ -165,15 +171,15 @@ void tst_TimelineNotesModel::modify() QCOMPARE(notes.text(id), QLatin1String("a")); notes.resetModified(); - notes.setText(10, 0, QLatin1String("x")); + notes.setText(model.modelId(), 0, QLatin1String("x")); QVERIFY(notes.isModified()); QCOMPARE(spy.count(), 4); QCOMPARE(notes.text(id), QLatin1String("x")); notes.resetModified(); - TestModel model2(9); + TestModel model2(&aggregator); notes.addTimelineModel(&model2); - notes.setText(9, 0, QLatin1String("hh")); + notes.setText(model2.modelId(), 0, QLatin1String("hh")); QVERIFY(notes.isModified()); QCOMPARE(spy.count(), 5); QCOMPARE(notes.count(), 2); diff --git a/tests/auto/timeline/timelinenotesrenderpass/timelinenotesrenderpass.pro b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.pro index b1167b02bdf..33c09eb66c2 100644 --- a/tests/auto/timeline/timelinenotesrenderpass/timelinenotesrenderpass.pro +++ b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinenotesrenderpass/timelinenotesrenderpass.qbs b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.qbs index 4f3c25e758f..3b0efa5b53f 100644 --- a/tests/auto/timeline/timelinenotesrenderpass/timelinenotesrenderpass.qbs +++ b/tests/auto/tracing/timelinenotesrenderpass/timelinenotesrenderpass.qbs @@ -1,8 +1,8 @@ import qbs import QtcFunctions -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineNotesRenderPass autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp b/tests/auto/tracing/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp index b67d10536a4..f7891b37d78 100644 --- a/tests/auto/timeline/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp +++ b/tests/auto/tracing/timelinenotesrenderpass/tst_timelinenotesrenderpass.cpp @@ -23,10 +23,11 @@ ** ****************************************************************************/ -#include <timeline/runscenegraphtest.h> -#include <timeline/timelinenotesrenderpass.h> -#include <timeline/timelinerenderstate.h> -#include <timeline/timelineabstractrenderer_p.h> +#include <tracing/runscenegraphtest.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelinenotesrenderpass.h> +#include <tracing/timelinerenderstate.h> +#include <tracing/timelineabstractrenderer_p.h> #include <QtTest> #include <QSGMaterialShader> @@ -35,7 +36,7 @@ using namespace Timeline; class DummyModel : public TimelineModel { public: - DummyModel(int id = 12); + DummyModel(TimelineModelAggregator *parent); void loadData(); }; @@ -48,7 +49,7 @@ private slots: void update(); }; -DummyModel::DummyModel(int id) : TimelineModel(id) +DummyModel::DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) { } @@ -70,14 +71,15 @@ void tst_TimelineNotesRenderPass::update() { const TimelineNotesRenderPass *inst = TimelineNotesRenderPass::instance(); TimelineAbstractRenderer renderer; + TimelineModelAggregator aggregator; TimelineRenderState parentState(0, 8, 1, 1); TimelineRenderPass::State *nullState = 0; QSGNode *nullNode = 0; TimelineRenderPass::State *result = inst->update(&renderer, &parentState, 0, 0, 0, true, 1); QCOMPARE(result, nullState); - DummyModel model; - DummyModel otherModel(13); + DummyModel model(&aggregator); + DummyModel otherModel(&aggregator); TimelineNotesModel notes; notes.addTimelineModel(&model); @@ -104,9 +106,9 @@ void tst_TimelineNotesRenderPass::update() 1); QCOMPARE(result2, result); - notes.add(12, 0, QLatin1String("x")); - notes.add(12, 9, QLatin1String("xx")); - notes.add(13, 0, QLatin1String("y")); + notes.add(model.modelId(), 0, QLatin1String("x")); + notes.add(model.modelId(), 9, QLatin1String("xx")); + notes.add(otherModel.modelId(), 0, QLatin1String("y")); QVERIFY(renderer.notesDirty()); result = inst->update(&renderer, &parentState, result, 0, 0, true, 1); QVERIFY(result != nullState); diff --git a/tests/auto/timeline/timelineoverviewrenderer/timelineoverviewrenderer.pro b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.pro index 2e533e63206..55299115904 100644 --- a/tests/auto/timeline/timelineoverviewrenderer/timelineoverviewrenderer.pro +++ b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelineoverviewrenderer/timelineoverviewrenderer.qbs b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.qbs index d2cc5b0c124..2144dba1f99 100644 --- a/tests/auto/timeline/timelineoverviewrenderer/timelineoverviewrenderer.qbs +++ b/tests/auto/tracing/timelineoverviewrenderer/timelineoverviewrenderer.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineOverviewRenderer autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp b/tests/auto/tracing/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp index c7049c27bc2..0dfed3eec85 100644 --- a/tests/auto/timeline/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp +++ b/tests/auto/tracing/timelineoverviewrenderer/tst_timelineoverviewrenderer.cpp @@ -24,7 +24,8 @@ ****************************************************************************/ #include <QtTest> -#include <timeline/timelineoverviewrenderer_p.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelineoverviewrenderer_p.h> using namespace Timeline; @@ -34,7 +35,7 @@ class DummyRenderer : public TimelineOverviewRenderer { class DummyModel : public TimelineModel { public: - DummyModel() : TimelineModel(0) {} + DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) {} void loadData() { @@ -57,8 +58,9 @@ private slots: void tst_TimelineOverviewRenderer::updatePaintNode() { DummyRenderer renderer; + TimelineModelAggregator aggregator; QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0)); - DummyModel model; + DummyModel model(&aggregator); renderer.setModel(&model); QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0)); model.loadData(); diff --git a/tests/auto/timeline/timelinerenderer/timelinerenderer.pro b/tests/auto/tracing/timelinerenderer/timelinerenderer.pro index 8d3fa6a17b8..1c49cfdfbf1 100644 --- a/tests/auto/timeline/timelinerenderer/timelinerenderer.pro +++ b/tests/auto/tracing/timelinerenderer/timelinerenderer.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinerenderer/timelinerenderer.qbs b/tests/auto/tracing/timelinerenderer/timelinerenderer.qbs index 0ae1434193b..45a97acc6d4 100644 --- a/tests/auto/timeline/timelinerenderer/timelinerenderer.qbs +++ b/tests/auto/tracing/timelinerenderer/timelinerenderer.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineRenderer autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinerenderer/tst_timelinerenderer.cpp b/tests/auto/tracing/timelinerenderer/tst_timelinerenderer.cpp index b657cb0649b..5378df44675 100644 --- a/tests/auto/timeline/timelinerenderer/tst_timelinerenderer.cpp +++ b/tests/auto/tracing/timelinerenderer/tst_timelinerenderer.cpp @@ -24,7 +24,8 @@ ****************************************************************************/ #include <QtTest> -#include <timeline/timelinerenderer_p.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelinerenderer_p.h> using namespace Timeline; @@ -34,7 +35,7 @@ class DummyRenderer : public TimelineRenderer { class DummyModel : public TimelineModel { public: - DummyModel() : TimelineModel(0) {} + DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) {} void loadData() { @@ -55,6 +56,7 @@ class tst_TimelineRenderer : public QObject private: void testMouseEvents(DummyRenderer *renderer, int x, int y); + TimelineModelAggregator aggregator; private slots: void updatePaintNode(); @@ -65,7 +67,7 @@ void tst_TimelineRenderer::updatePaintNode() { DummyRenderer renderer; QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0)); - DummyModel model; + DummyModel model(&aggregator); renderer.setModel(&model); QCOMPARE(renderer.updatePaintNode(0, 0), static_cast<QSGNode *>(0)); model.loadData(); @@ -124,7 +126,7 @@ void tst_TimelineRenderer::mouseEvents() QCOMPARE(renderer.selectedItem(), -1); QCOMPARE(renderer.selectionLocked(), true); - DummyModel model; + DummyModel model(&aggregator); renderer.setModel(&model); testMouseEvents(&renderer, 1, 1); QCOMPARE(renderer.selectedItem(), -1); diff --git a/tests/auto/timeline/timelinerenderpass/timelinerenderpass.pro b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.pro index 3e2971c23e3..2bf096ae0b6 100644 --- a/tests/auto/timeline/timelinerenderpass/timelinerenderpass.pro +++ b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.pro @@ -1,4 +1,4 @@ -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinerenderpass/timelinerenderpass.qbs b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.qbs index c5628578f07..b2bc54fec25 100644 --- a/tests/auto/timeline/timelinerenderpass/timelinerenderpass.qbs +++ b/tests/auto/tracing/timelinerenderpass/timelinerenderpass.qbs @@ -1,8 +1,8 @@ import qbs import QtcFunctions -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineRenderPass autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinerenderpass/tst_timelinerenderpass.cpp b/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp index 2eec7bbefda..cfff804e52f 100644 --- a/tests/auto/timeline/timelinerenderpass/tst_timelinerenderpass.cpp +++ b/tests/auto/tracing/timelinerenderpass/tst_timelinerenderpass.cpp @@ -23,7 +23,7 @@ ** ****************************************************************************/ -#include <timeline/timelinerenderpass.h> +#include <tracing/timelinerenderpass.h> #include <QtTest> using namespace Timeline; diff --git a/tests/auto/timeline/timelinerenderstate/timelinerenderstate.pro b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.pro index d08588fc91a..b6ccbd07273 100644 --- a/tests/auto/timeline/timelinerenderstate/timelinerenderstate.pro +++ b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinerenderstate/timelinerenderstate.qbs b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.qbs index d560ac30cfa..b35b97e296b 100644 --- a/tests/auto/timeline/timelinerenderstate/timelinerenderstate.qbs +++ b/tests/auto/tracing/timelinerenderstate/timelinerenderstate.qbs @@ -1,8 +1,8 @@ import qbs import QtcFunctions -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineRenderState autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinerenderstate/tst_timelinerenderstate.cpp b/tests/auto/tracing/timelinerenderstate/tst_timelinerenderstate.cpp index 647c7f32e42..08329bb69af 100644 --- a/tests/auto/timeline/timelinerenderstate/tst_timelinerenderstate.cpp +++ b/tests/auto/tracing/timelinerenderstate/tst_timelinerenderstate.cpp @@ -23,7 +23,8 @@ ** ****************************************************************************/ -#include <timeline/timelinerenderstate.h> +#include <tracing/timelinemodelaggregator.h> +#include <tracing/timelinerenderstate.h> #include <QtTest> #include <QSGSimpleRectNode> @@ -140,7 +141,8 @@ void tst_TimelineRenderState::emptyRoots() void tst_TimelineRenderState::assembleNodeTree() { - TimelineModel model(3); + TimelineModelAggregator aggregator; + TimelineModel model(&aggregator); TimelineRenderState state1(1, 2, 0.5, 3); state1.assembleNodeTree(&model, 30, 30); QSGTransformNode *node = state1.finalize(0, true, QMatrix4x4()); diff --git a/tests/auto/timeline/timelineselectionrenderpass/timelineselectionrenderpass.pro b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.pro index ad90b6d0aec..77f723bc1c5 100644 --- a/tests/auto/timeline/timelineselectionrenderpass/timelineselectionrenderpass.pro +++ b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.pro @@ -1,6 +1,6 @@ QT += quick -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelineselectionrenderpass/timelineselectionrenderpass.qbs b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.qbs index d600da3b2ca..0cdf08d0c04 100644 --- a/tests/auto/timeline/timelineselectionrenderpass/timelineselectionrenderpass.qbs +++ b/tests/auto/tracing/timelineselectionrenderpass/timelineselectionrenderpass.qbs @@ -1,8 +1,8 @@ import qbs import QtcFunctions -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineSelectionRenderPass autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp b/tests/auto/tracing/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp index b718dacdf86..2456ab6674a 100644 --- a/tests/auto/timeline/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp +++ b/tests/auto/tracing/timelineselectionrenderpass/tst_timelineselectionrenderpass.cpp @@ -23,11 +23,12 @@ ** ****************************************************************************/ -#include <timeline/runscenegraphtest.h> -#include <timeline/timelineselectionrenderpass.h> -#include <timeline/timelinerenderstate.h> -#include <timeline/timelineabstractrenderer_p.h> -#include <timeline/timelineitemsrenderpass.h> +#include <tracing/runscenegraphtest.h> +#include <tracing/timelineselectionrenderpass.h> +#include <tracing/timelinerenderstate.h> +#include <tracing/timelineabstractrenderer_p.h> +#include <tracing/timelineitemsrenderpass.h> +#include <tracing/timelinemodelaggregator.h> #include <QtTest> #include <QSGMaterialShader> @@ -37,7 +38,7 @@ using namespace Timeline; class DummyModel : public TimelineModel { public: - DummyModel(int id = 12); + DummyModel(TimelineModelAggregator *parent); void loadData(); float relativeHeight(int index) const; }; @@ -51,7 +52,7 @@ private slots: void update(); }; -DummyModel::DummyModel(int id) : TimelineModel(id) +DummyModel::DummyModel(TimelineModelAggregator *parent) : TimelineModel(parent) { } @@ -112,13 +113,14 @@ void tst_TimelineSelectionRenderPass::update() { const TimelineSelectionRenderPass *inst = TimelineSelectionRenderPass::instance(); TimelineAbstractRenderer renderer; + TimelineModelAggregator aggregator; TimelineRenderState parentState(0, 400, 1, 1); TimelineRenderPass::State *nullState = 0; QSGNode *nullNode = 0; TimelineRenderPass::State *result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1); QCOMPARE(result, nullState); - DummyModel model; + DummyModel model(&aggregator); result = inst->update(&renderer, &parentState, 0, 0, 10, true, 1); QCOMPARE(result, nullState); diff --git a/tests/auto/timeline/timelinezoomcontrol/timelinezoomcontrol.pro b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.pro index 90a4c202395..8923467c49e 100644 --- a/tests/auto/timeline/timelinezoomcontrol/timelinezoomcontrol.pro +++ b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.pro @@ -1,4 +1,4 @@ -QTC_LIB_DEPENDS += timeline +QTC_LIB_DEPENDS += tracing include(../../qttest.pri) SOURCES += \ diff --git a/tests/auto/timeline/timelinezoomcontrol/timelinezoomcontrol.qbs b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.qbs index 6f189d16b92..5981e1cb9ad 100644 --- a/tests/auto/timeline/timelinezoomcontrol/timelinezoomcontrol.qbs +++ b/tests/auto/tracing/timelinezoomcontrol/timelinezoomcontrol.qbs @@ -1,7 +1,7 @@ import qbs -import "../timelineautotest.qbs" as TimelineAutotest +import "../tracingautotest.qbs" as TracingAutotest -TimelineAutotest { +TracingAutotest { name: "TimelineZoomcontrol autotest" Group { name: "Test sources" diff --git a/tests/auto/timeline/timelinezoomcontrol/tst_timelinezoomcontrol.cpp b/tests/auto/tracing/timelinezoomcontrol/tst_timelinezoomcontrol.cpp index 9f35da6ada3..e57763cf66d 100644 --- a/tests/auto/timeline/timelinezoomcontrol/tst_timelinezoomcontrol.cpp +++ b/tests/auto/tracing/timelinezoomcontrol/tst_timelinezoomcontrol.cpp @@ -25,7 +25,7 @@ #include <QtTest> #include <QColor> -#include <timeline/timelinezoomcontrol.h> +#include <tracing/timelinezoomcontrol.h> class tst_TimelineZoomControl : public QObject { diff --git a/tests/auto/timeline/timeline.pro b/tests/auto/tracing/tracing.pro index 9a4821612ab..7772d6ec6b6 100644 --- a/tests/auto/timeline/timeline.pro +++ b/tests/auto/tracing/tracing.pro @@ -2,6 +2,7 @@ include(../../../qtcreator.pri) TEMPLATE = subdirs SUBDIRS = \ + flamegraph \ timelineabstractrenderer \ timelineitemsrenderpass \ timelinemodel \ @@ -16,4 +17,4 @@ SUBDIRS = \ timelinezoomcontrol OTHER_FILES += \ - timelineautotest.qbs + tracingautotest.qbs diff --git a/tests/auto/timeline/timeline.qbs b/tests/auto/tracing/tracing.qbs index 27cf27bc79f..643d25f31ab 100644 --- a/tests/auto/timeline/timeline.qbs +++ b/tests/auto/tracing/tracing.qbs @@ -1,11 +1,10 @@ import qbs Project { - name: "Timeline autotests" + name: "Tracing autotests" - property path timelineDir: project.ide_source_tree - + "/src/libs/timeline" references: [ + "flamegraph/flamegraph.qbs", "timelinemodel/timelinemodel.qbs", "timelinemodelaggregator/timelinemodelaggregator.qbs", "timelinenotesmodel/timelinenotesmodel.qbs", diff --git a/tests/auto/timeline/timelineautotest.qbs b/tests/auto/tracing/tracingautotest.qbs index 33ae595cbd2..3a6f47961fd 100644 --- a/tests/auto/timeline/timelineautotest.qbs +++ b/tests/auto/tracing/tracingautotest.qbs @@ -1,7 +1,7 @@ import qbs QtcAutotest { - Depends { name: "Timeline" } + Depends { name: "Tracing" } Depends { name: "Qt.quick" } Depends { name: "Qt.gui" } } diff --git a/tests/auto/utils/objectpool/objectpool.pro b/tests/auto/utils/objectpool/objectpool.pro deleted file mode 100644 index 4da02c45c52..00000000000 --- a/tests/auto/utils/objectpool/objectpool.pro +++ /dev/null @@ -1,4 +0,0 @@ -QTC_LIB_DEPENDS += utils -include(../../qttest.pri) - -SOURCES += tst_objectpool.cpp diff --git a/tests/auto/utils/objectpool/objectpool.qbs b/tests/auto/utils/objectpool/objectpool.qbs deleted file mode 100644 index 1fdd37c19ac..00000000000 --- a/tests/auto/utils/objectpool/objectpool.qbs +++ /dev/null @@ -1,7 +0,0 @@ -import qbs - -QtcAutotest { - name: "ObjectPool autotest" - Depends { name: "Utils" } - files: "tst_objectpool.cpp" -} diff --git a/tests/auto/utils/objectpool/tst_objectpool.cpp b/tests/auto/utils/objectpool/tst_objectpool.cpp deleted file mode 100644 index 40bf1eb47a6..00000000000 --- a/tests/auto/utils/objectpool/tst_objectpool.cpp +++ /dev/null @@ -1,96 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 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 <utils/objectpool.h> - -#include <QtTest> - -//TESTED_COMPONENT=src/libs/utils - -using namespace Utils; - -class tst_ObjectPool : public QObject -{ - Q_OBJECT - -private slots: - void testSize(); -}; - -void tst_ObjectPool::testSize() -{ - QObject parent; - - QPointer<QObject> object1 = new QObject; - object1->setObjectName("object1"); - - QPointer<QObject> object2 = new QObject(&parent); - object2->setObjectName("object2"); - - QPointer<QObject> object3 = new QObject; - object3->setObjectName("object3"); - - QPointer<QObject> object4 = new QObject(&parent); - object4->setObjectName("object4"); - - { - ObjectPool<QObject> pool; - QCOMPARE(pool.size(), 0); - - pool.addObject(object1.data()); - QCOMPARE(pool.size(), 1); - - pool.addObject(object2.data()); - QCOMPARE(pool.size(), 2); - - pool.addObject(object3.data()); - QCOMPARE(pool.size(), 3); - - pool.addObject(object4.data()); - QCOMPARE(pool.size(), 4); - - delete object1; - QCOMPARE(pool.size(), 3); - QCOMPARE(parent.children().size(), 2); - - delete object2; - QCOMPARE(pool.size(), 2); - QCOMPARE(parent.children().size(), 1); - } - - QCOMPARE(parent.children().size(), 1); - QCOMPARE(object3.isNull(), true); - QCOMPARE(object4.isNull(), false); - - delete object4; - QCOMPARE(parent.children().size(), 0); - QCOMPARE(object3.isNull(), true); - QCOMPARE(object4.isNull(), true); -} - - -QTEST_MAIN(tst_ObjectPool) - -#include "tst_objectpool.moc" diff --git a/tests/auto/utils/settings/tst_settings.cpp b/tests/auto/utils/settings/tst_settings.cpp index 43809e7aef8..867f9bbe910 100644 --- a/tests/auto/utils/settings/tst_settings.cpp +++ b/tests/auto/utils/settings/tst_settings.cpp @@ -23,7 +23,7 @@ ** ****************************************************************************/ -#include <utils/persistentsettings.h> +#include <utils/algorithm.h> #include <utils/settingsaccessor.h> #include <QTemporaryDir> @@ -67,14 +67,82 @@ public: // BasicTestSettingsAccessor: // -------------------------------------------------------------------- -class BasicTestSettingsAccessor : public Utils::SettingsAccessor +class BasicTestSettingsAccessor : public Utils::MergingSettingsAccessor { public: BasicTestSettingsAccessor(const Utils::FileName &baseName = Utils::FileName::fromString("/foo/bar"), - const QByteArray &id = QByteArray(TESTACCESSOR_DEFAULT_ID)) : - Utils::SettingsAccessor(baseName, "TestData", TESTACCESSOR_DN, TESTACCESSOR_APPLICATION_DN) + const QByteArray &id = QByteArray(TESTACCESSOR_DEFAULT_ID)); + + using Utils::MergingSettingsAccessor::addVersionUpgrader; + + QHash<Utils::FileName, QVariantMap> files() const { return m_files; } + void addFile(const Utils::FileName &path, const QVariantMap &data) const { m_files.insert(path, data); } + Utils::FileNameList fileNames() const { return m_files.keys(); } + QVariantMap fileContents(const Utils::FileName &path) const { return m_files.value(path); } + +protected: + RestoreData readFile(const Utils::FileName &path) const override + { + if (!m_files.contains(path)) + return RestoreData("File not found.", "File not found.", Issue::Type::ERROR); + + return RestoreData(path, m_files.value(path)); + } + + SettingsMergeResult merge(const SettingsMergeData &global, + const SettingsMergeData &local) const final + { + Q_UNUSED(global); + + const QString key = local.key; + const QVariant main = local.main.value(key); + const QVariant secondary = local.secondary.value(key); + + if (isHouseKeepingKey(key)) + return qMakePair(key, main); + + if (main.isNull() && secondary.isNull()) + return nullopt; + if (!main.isNull()) + return qMakePair(key, main); + return qMakePair(key, secondary); + } + + Utils::optional<Issue> writeFile(const Utils::FileName &path, const QVariantMap &data) const override + { + if (data.isEmpty()) { + return Issue(QCoreApplication::translate("Utils::SettingsAccessor", "Failed to Write File"), + QCoreApplication::translate("Utils::SettingsAccessor", "There was nothing to write."), + Issue::Type::WARNING); + } + + addFile(path, data); + return nullopt; + } + +private: + mutable QHash<Utils::FileName, QVariantMap> m_files; +}; + +// -------------------------------------------------------------------- +// TestBackUpStrategy: +// -------------------------------------------------------------------- + +class BasicTestSettingsAccessor; + +class TestBackUpStrategy : public Utils::VersionedBackUpStrategy +{ +public: + TestBackUpStrategy(BasicTestSettingsAccessor *accessor) : + VersionedBackUpStrategy(accessor) + { } + + FileNameList readFileCandidates(const Utils::FileName &baseFileName) const { - setSettingsId(id); + return Utils::filtered(static_cast<const BasicTestSettingsAccessor *>(accessor())->fileNames(), + [&baseFileName](const Utils::FileName &f) { + return f.parentDir() == baseFileName.parentDir() && f.toString().startsWith(baseFileName.toString()); + }); } }; @@ -95,12 +163,17 @@ public: } // Make methods public for the tests: - using Utils::SettingsAccessor::findIssues; - using Utils::SettingsAccessor::isValidVersionAndId; - using Utils::SettingsAccessor::isBetterMatch; - using Utils::SettingsAccessor::upgradeSettings; + using Utils::MergingSettingsAccessor::upgradeSettings; }; +BasicTestSettingsAccessor::BasicTestSettingsAccessor(const FileName &baseName, const QByteArray &id) : + Utils::MergingSettingsAccessor(std::make_unique<TestBackUpStrategy>(this), + "TestData", TESTACCESSOR_DN, TESTACCESSOR_APPLICATION_DN) +{ + setSettingsId(id); + setBaseFilePath(baseName); +} + // -------------------------------------------------------------------- // tst_SettingsAccessor: // -------------------------------------------------------------------- @@ -119,12 +192,12 @@ private slots: void isValidVersionAndId(); - void isBetterMatch(); - void isBetterMatch_idMismatch(); - void isBetterMatch_noId(); - void isBetterMatch_sameVersion(); - void isBetterMatch_emptyMap(); - void isBetterMatch_twoEmptyMaps(); + void RestoreDataCompare(); + void RestoreDataCompare_idMismatch(); + void RestoreDataCompare_noId(); + void RestoreDataCompare_sameVersion(); + void RestoreDataCompare_emptyMap(); + void RestoreDataCompare_twoEmptyMaps(); void upgradeSettings_noUpgradeNecessary(); void upgradeSettings_invalidId(); @@ -136,18 +209,18 @@ private slots: void upgradeSettings_targetVersionTooOld(); void upgradeSettings_targetVersionTooNew(); +#if 0 void findIssues_ok(); void findIssues_emptyData(); void findIssues_tooNew(); void findIssues_tooOld(); void findIssues_wrongId(); void findIssues_nonDefaultPath(); +#endif void saveSettings(); void loadSettings(); - -private: - QTemporaryDir m_tempDir; + void loadSettings_pickBest(); }; static QVariantMap versionedMap(int version, const QByteArray &id = QByteArray(), @@ -162,9 +235,16 @@ static QVariantMap versionedMap(int version, const QByteArray &id = QByteArray() return result; } -static Utils::FileName testPath(const QTemporaryDir &td, const QString &name) +static Utils::SettingsAccessor::RestoreData restoreData(const Utils::FileName &path, + const QVariantMap &data) +{ + return Utils::SettingsAccessor::RestoreData(path, data); +} + +static Utils::SettingsAccessor::RestoreData restoreData(const QByteArray &path, + const QVariantMap &data) { - return Utils::FileName::fromString(td.path() + "/" + name); + return restoreData(Utils::FileName::fromUtf8(path), data); } void tst_SettingsAccessor::addVersionUpgrader() @@ -246,10 +326,10 @@ void tst_SettingsAccessor::isValidVersionAndId() const TestSettingsAccessor accessor; QVERIFY(!accessor.isValidVersionAndId(4, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(accessor.isValidVersionAndId(5, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(accessor.isValidVersionAndId(6, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(accessor.isValidVersionAndId(7, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(accessor.isValidVersionAndId(8, TESTACCESSOR_DEFAULT_ID)); + QVERIFY( accessor.isValidVersionAndId(5, TESTACCESSOR_DEFAULT_ID)); + QVERIFY( accessor.isValidVersionAndId(6, TESTACCESSOR_DEFAULT_ID)); + QVERIFY( accessor.isValidVersionAndId(7, TESTACCESSOR_DEFAULT_ID)); + QVERIFY( accessor.isValidVersionAndId(8, TESTACCESSOR_DEFAULT_ID)); QVERIFY(!accessor.isValidVersionAndId(9, TESTACCESSOR_DEFAULT_ID)); QVERIFY(!accessor.isValidVersionAndId(4, "foo")); @@ -260,165 +340,194 @@ void tst_SettingsAccessor::isValidVersionAndId() QVERIFY(!accessor.isValidVersionAndId(9, "foo")); } -void tst_SettingsAccessor::isBetterMatch() +void tst_SettingsAccessor::RestoreDataCompare() { const TestSettingsAccessor accessor; - const QVariantMap a = versionedMap(5, TESTACCESSOR_DEFAULT_ID); - const QVariantMap b = versionedMap(6, TESTACCESSOR_DEFAULT_ID); + Utils::SettingsAccessor::RestoreData a = restoreData("/foo/bar", versionedMap(5, TESTACCESSOR_DEFAULT_ID)); + Utils::SettingsAccessor::RestoreData b = restoreData("/foo/baz", versionedMap(6, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(accessor.isBetterMatch(a, b)); - QVERIFY(!accessor.isBetterMatch(b, a)); + QCOMPARE(accessor.strategy()->compare(a, a), 0); + QCOMPARE(accessor.strategy()->compare(a, b), 1); + QCOMPARE(accessor.strategy()->compare(b, a), -1); } -void tst_SettingsAccessor::isBetterMatch_idMismatch() +void tst_SettingsAccessor::RestoreDataCompare_idMismatch() { const TestSettingsAccessor accessor; - const QVariantMap a = versionedMap(5, TESTACCESSOR_DEFAULT_ID); - const QVariantMap b = versionedMap(6, "foo"); + Utils::SettingsAccessor::RestoreData a = restoreData("/foo/bar", versionedMap(5, TESTACCESSOR_DEFAULT_ID)); + Utils::SettingsAccessor::RestoreData b = restoreData("/foo/baz", versionedMap(6, "foo")); - QVERIFY(!accessor.isBetterMatch(a, b)); - QVERIFY(accessor.isBetterMatch(b, a)); + QCOMPARE(accessor.strategy()->compare(a, b), -1); + QCOMPARE(accessor.strategy()->compare(b, a), 1); } -void tst_SettingsAccessor::isBetterMatch_noId() +void tst_SettingsAccessor::RestoreDataCompare_noId() { const TestSettingsAccessor accessor(Utils::FileName::fromString("/foo/baz"), QByteArray()); - const QVariantMap a = versionedMap(5, TESTACCESSOR_DEFAULT_ID); - const QVariantMap b = versionedMap(6, "foo"); + Utils::SettingsAccessor::RestoreData a = restoreData("/foo/bar", versionedMap(5, TESTACCESSOR_DEFAULT_ID)); + Utils::SettingsAccessor::RestoreData b = restoreData("/foo/baz", versionedMap(6, "foo")); - QVERIFY(accessor.isBetterMatch(a, b)); - QVERIFY(!accessor.isBetterMatch(b, a)); + QCOMPARE(accessor.strategy()->compare(a, b), 1); + QCOMPARE(accessor.strategy()->compare(b, a), -1); } -void tst_SettingsAccessor::isBetterMatch_sameVersion() +void tst_SettingsAccessor::RestoreDataCompare_sameVersion() { const TestSettingsAccessor accessor; - const QVariantMap a = versionedMap(7, TESTACCESSOR_DEFAULT_ID); - const QVariantMap b = versionedMap(7, TESTACCESSOR_DEFAULT_ID); + Utils::SettingsAccessor::RestoreData a = restoreData("/foo/bar", versionedMap(7, TESTACCESSOR_DEFAULT_ID)); + Utils::SettingsAccessor::RestoreData b = restoreData("/foo/baz", versionedMap(7, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(!accessor.isBetterMatch(a, b)); - QVERIFY(!accessor.isBetterMatch(b, a)); + QCOMPARE(accessor.strategy()->compare(a, b), 0); + QCOMPARE(accessor.strategy()->compare(b, a), 0); } -void tst_SettingsAccessor::isBetterMatch_emptyMap() +void tst_SettingsAccessor::RestoreDataCompare_emptyMap() { const TestSettingsAccessor accessor; - const QVariantMap a; - const QVariantMap b = versionedMap(7, TESTACCESSOR_DEFAULT_ID); + Utils::SettingsAccessor::RestoreData a = restoreData("/foo/bar", QVariantMap()); + Utils::SettingsAccessor::RestoreData b = restoreData("/foo/baz", versionedMap(7, TESTACCESSOR_DEFAULT_ID)); - QVERIFY(accessor.isBetterMatch(a, b)); - QVERIFY(!accessor.isBetterMatch(b, a)); + QCOMPARE(accessor.strategy()->compare(a, b), 1); + QCOMPARE(accessor.strategy()->compare(b, a), -1); } -void tst_SettingsAccessor::isBetterMatch_twoEmptyMaps() +void tst_SettingsAccessor::RestoreDataCompare_twoEmptyMaps() { const TestSettingsAccessor accessor; - const QVariantMap a; - const QVariantMap b; + Utils::SettingsAccessor::RestoreData a = restoreData("/foo/bar", QVariantMap()); + Utils::SettingsAccessor::RestoreData b = restoreData("/foo/baz", QVariantMap()); - QVERIFY(!accessor.isBetterMatch(a, b)); - QVERIFY(!accessor.isBetterMatch(b, a)); + QCOMPARE(accessor.strategy()->compare(a, b), 0); + QCOMPARE(accessor.strategy()->compare(b, a), 0); } void tst_SettingsAccessor::upgradeSettings_noUpgradeNecessary() { const TestSettingsAccessor accessor; const int startVersion = 8; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData())); - const QVariantMap result = accessor.upgradeSettings(input, 8); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 8); - for (auto it = result.cbegin(); it != result.cend(); ++it) { + QVERIFY(!result.hasIssue()); + for (auto it = result.data.cbegin(); it != result.data.cend(); ++it) { if (it.key() == "OriginalVersion") QCOMPARE(it.value().toInt(), startVersion); - else if (input.contains(it.key())) // extra settings pass through unchanged! - QCOMPARE(it.value(), input.value(it.key())); + else if (input.data.contains(it.key())) // extra settings pass through unchanged! + QCOMPARE(it.value(), input.data.value(it.key())); else QVERIFY2(false, "Unexpected value found in upgraded result!"); } - QCOMPARE(result.size(), input.size() + 1); // OriginalVersion was added + QCOMPARE(result.data.size(), input.data.size() + 1); // OriginalVersion was added } void tst_SettingsAccessor::upgradeSettings_invalidId() { const TestSettingsAccessor accessor; const int startVersion = 8; - const QVariantMap input = versionedMap(startVersion, "foo", generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, "foo", generateExtraData())); + - const QVariantMap result = accessor.upgradeSettings(input, 8); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 8); // Data is unchanged - QCOMPARE(result, input); + QVERIFY(result.hasWarning()); + for (auto it = result.data.cbegin(); it != result.data.cend(); ++it) { + if (it.key() == "OriginalVersion") + QCOMPARE(it.value().toInt(), startVersion); + else if (input.data.contains(it.key())) // extra settings pass through unchanged! + QCOMPARE(it.value(), input.data.value(it.key())); + else + QVERIFY2(false, "Unexpected value found in upgraded result!"); + } + QCOMPARE(result.data.size(), input.data.size() + 1); // OriginalVersion was added } void tst_SettingsAccessor::upgradeSettings_tooOld() { const TestSettingsAccessor accessor; const int startVersion = 1; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData())); - const QVariantMap result = accessor.upgradeSettings(input, 8); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 8); // Data is unchanged - QCOMPARE(result, input); + QVERIFY(result.hasIssue()); + QCOMPARE(result.data, input.data); } void tst_SettingsAccessor::upgradeSettings_tooNew() { const TestSettingsAccessor accessor; const int startVersion = 42; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData())); - const QVariantMap result = accessor.upgradeSettings(input, 8); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 8); // Data is unchanged - QCOMPARE(result, input); + QVERIFY(result.hasIssue()); + QCOMPARE(result.data, input.data); } void tst_SettingsAccessor::upgradeSettings_oneStep() { const TestSettingsAccessor accessor; const int startVersion = 7; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData())); - const QVariantMap result = accessor.upgradeSettings(input, 8); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 8); - for (auto it = result.cbegin(); it != result.cend(); ++it) { + QVERIFY(!result.hasIssue()); + for (auto it = result.data.cbegin(); it != result.data.cend(); ++it) { if (it.key() == "OriginalVersion") // was added QCOMPARE(it.value().toInt(), startVersion); else if (it.key() == "Version") // was overridden QCOMPARE(it.value().toInt(), 8); - else if (input.contains(it.key())) // extra settings pass through unchanged! - QCOMPARE(it.value(), input.value(it.key())); + else if (input.data.contains(it.key())) // extra settings pass through unchanged! + QCOMPARE(it.value(), input.data.value(it.key())); else if (it.key() == "VERSION_7") QCOMPARE(it.value().toInt(), 7); else QVERIFY2(false, "Unexpected value found in upgraded result!"); } - QCOMPARE(result.size(), input.size() + 2); // OriginalVersion + VERSION_7 was added + QCOMPARE(result.data.size(), input.data.size() + 2); // OriginalVersion + VERSION_7 was added } void tst_SettingsAccessor::upgradeSettings_twoSteps() { const TestSettingsAccessor accessor; const int startVersion = 6; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData())); - const QVariantMap result = accessor.upgradeSettings(input, 8); - for (auto it = result.cbegin(); it != result.cend(); ++it) { + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 8); + + QVERIFY(!result.hasIssue()); + for (auto it = result.data.cbegin(); it != result.data.cend(); ++it) { if (it.key() == "OriginalVersion") // was added QCOMPARE(it.value().toInt(), startVersion); else if (it.key() == "Version") // was overridden QCOMPARE(it.value().toInt(), 8); - else if (input.contains(it.key())) // extra settings pass through unchanged! - QCOMPARE(it.value(), input.value(it.key())); + else if (input.data.contains(it.key())) // extra settings pass through unchanged! + QCOMPARE(it.value(), input.data.value(it.key())); else if (it.key() == "VERSION_6") // was added QCOMPARE(it.value().toInt(), 6); else if (it.key() == "VERSION_7") // was added @@ -426,30 +535,33 @@ void tst_SettingsAccessor::upgradeSettings_twoSteps() else QVERIFY2(false, "Unexpected value found in upgraded result!"); } - QCOMPARE(result.size(), input.size() + 3); // OriginalVersion + VERSION_6 + VERSION_7 was added + QCOMPARE(result.data.size(), input.data.size() + 3); // OriginalVersion + VERSION_6 + VERSION_7 was added } void tst_SettingsAccessor::upgradeSettings_partialUpdate() { const TestSettingsAccessor accessor; const int startVersion = 6; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData()); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, generateExtraData())); - const QVariantMap result = accessor.upgradeSettings(input, 7); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 7); - for (auto it = result.cbegin(); it != result.cend(); ++it) { + QVERIFY(!result.hasIssue()); + for (auto it = result.data.cbegin(); it != result.data.cend(); ++it) { if (it.key() == "OriginalVersion") // was added QCOMPARE(it.value().toInt(), startVersion); else if (it.key() == "Version") // was overridden QCOMPARE(it.value().toInt(), 7); - else if (input.contains(it.key())) // extra settings pass through unchanged! - QCOMPARE(it.value(), input.value(it.key())); + else if (input.data.contains(it.key())) // extra settings pass through unchanged! + QCOMPARE(it.value(), input.data.value(it.key())); else if (it.key() == "VERSION_6") QCOMPARE(it.value().toInt(), 6); else QVERIFY2(false, "Unexpected value found in upgraded result!"); } - QCOMPARE(result.size(), input.size() + 2); // OriginalVersion + VERSION_6 was added + QCOMPARE(result.data.size(), input.data.size() + 2); // OriginalVersion + VERSION_6 was added } void tst_SettingsAccessor::upgradeSettings_targetVersionTooOld() @@ -457,12 +569,15 @@ void tst_SettingsAccessor::upgradeSettings_targetVersionTooOld() const TestSettingsAccessor accessor; const QVariantMap extra = generateExtraData(); const int startVersion = 6; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, extra); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, extra)); - const QVariantMap result = accessor.upgradeSettings(input, 2); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 2); // result is unchanged! - QCOMPARE(result, input); + QVERIFY(!result.hasIssue()); + QCOMPARE(result.data, input.data); } void tst_SettingsAccessor::upgradeSettings_targetVersionTooNew() @@ -470,14 +585,19 @@ void tst_SettingsAccessor::upgradeSettings_targetVersionTooNew() const TestSettingsAccessor accessor; const QVariantMap extra = generateExtraData(); const int startVersion = 6; - const QVariantMap input = versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, extra); + const Utils::SettingsAccessor::RestoreData input + = restoreData(accessor.baseFilePath(), + versionedMap(startVersion, TESTACCESSOR_DEFAULT_ID, extra)); - const QVariantMap result = accessor.upgradeSettings(input, 42); + const Utils::SettingsAccessor::RestoreData result = accessor.upgradeSettings(input, 42); // result is unchanged! - QCOMPARE(result, input); + QVERIFY(!result.hasIssue()); + QCOMPARE(result.data, input.data); } +#if 0 +// FIXME: Test error conditions again. void tst_SettingsAccessor::findIssues_ok() { const TestSettingsAccessor accessor; @@ -543,18 +663,18 @@ void tst_SettingsAccessor::findIssues_nonDefaultPath() QVERIFY(bool(info)); } +#endif void tst_SettingsAccessor::saveSettings() { - const TestSettingsAccessor accessor(testPath(m_tempDir, "saveSettings")); + const Utils::FileName baseFile = Utils::FileName::fromString("/tmp/foo/saveSettings"); + const TestSettingsAccessor accessor(baseFile); const QVariantMap data = versionedMap(6, TESTACCESSOR_DEFAULT_ID); QVERIFY(accessor.saveSettings(data, nullptr)); - PersistentSettingsReader reader; - QVERIFY(reader.load(testPath(m_tempDir, "saveSettings.user"))); - - const QVariantMap read = reader.restoreValues(); + QCOMPARE(accessor.files().count(), 1); + const QVariantMap read = accessor.fileContents(baseFile); QVERIFY(!read.isEmpty()); for (auto it = read.cbegin(); it != read.cend(); ++it) { @@ -571,18 +691,13 @@ void tst_SettingsAccessor::saveSettings() void tst_SettingsAccessor::loadSettings() { const QVariantMap data = versionedMap(6, "loadSettings", generateExtraData()); - const Utils::FileName path = testPath(m_tempDir, "loadSettings"); - Utils::FileName fullPath = path; - fullPath.appendString(".user"); - - PersistentSettingsWriter writer(fullPath, "TestProfile"); - QString errorMessage; - writer.save(data, &errorMessage); - - QVERIFY(errorMessage.isEmpty()); - + const Utils::FileName path = Utils::FileName::fromString("/tmp/foo/loadSettings"); const TestSettingsAccessor accessor(path, "loadSettings"); + accessor.addFile(path, data); + QCOMPARE(accessor.files().count(), 1); // Catch changes early:-) + const QVariantMap read = accessor.restoreSettings(nullptr); + QCOMPARE(accessor.files().count(), 1); // no files were created QVERIFY(!read.isEmpty()); for (auto it = read.cbegin(); it != read.cend(); ++it) { @@ -602,6 +717,41 @@ void tst_SettingsAccessor::loadSettings() QCOMPARE(read.size(), data.size() + 3); } +void tst_SettingsAccessor::loadSettings_pickBest() +{ + const Utils::FileName path = Utils::FileName::fromString("/tmp/foo/loadSettings"); + const TestSettingsAccessor accessor(path, "loadSettings"); + + accessor.addFile(path, versionedMap(10, "loadSettings", generateExtraData())); // too new + const QVariantMap data = versionedMap(7, "loadSettings", generateExtraData()); + accessor.addFile(Utils::FileName::fromString("/tmp/foo/loadSettings.foo"), data); // pick this! + accessor.addFile(Utils::FileName::fromString("/tmp/foo/loadSettings.foo1"), + versionedMap(8, "fooSettings", generateExtraData())); // wrong environment + accessor.addFile(Utils::FileName::fromString("/tmp/foo/loadSettings.bar"), + versionedMap(6, "loadSettings", generateExtraData())); // too old + accessor.addFile(Utils::FileName::fromString("/tmp/foo/loadSettings.baz"), + versionedMap(1, "loadSettings", generateExtraData())); // much too old + QCOMPARE(accessor.files().count(), 5); // Catch changes early:-) + + const QVariantMap read = accessor.restoreSettings(nullptr); + QCOMPARE(accessor.files().count(), 5); // no new files + + QVERIFY(!read.isEmpty()); + for (auto it = read.cbegin(); it != read.cend(); ++it) { + if (it.key() == "Version") // was overridden + QCOMPARE(it.value().toInt(), 8); + else if (it.key() == "OriginalVersion") // was added + QCOMPARE(it.value().toInt(), 7); + else if (it.key() == "VERSION_7") // was added + QCOMPARE(it.value().toInt(), 7); + else if (data.contains(it.key())) + QCOMPARE(it.value(), data.value(it.key())); + else + QVERIFY2(false, "Unexpected value!"); + } + QCOMPARE(read.size(), data.size() + 2); +} + QTEST_MAIN(tst_SettingsAccessor) #include "tst_settings.moc" diff --git a/tests/auto/utils/utils.pro b/tests/auto/utils/utils.pro index 5fb9ef8c786..158b7c12e5a 100644 --- a/tests/auto/utils/utils.pro +++ b/tests/auto/utils/utils.pro @@ -4,7 +4,6 @@ SUBDIRS = \ fileutils \ ansiescapecodehandler \ fuzzymatcher \ - objectpool \ settings \ stringutils \ templateengine \ diff --git a/tests/auto/utils/utils.qbs b/tests/auto/utils/utils.qbs index 6c4032a86ef..edab157ae0c 100644 --- a/tests/auto/utils/utils.qbs +++ b/tests/auto/utils/utils.qbs @@ -8,7 +8,6 @@ Project { "fuzzymatcher/fuzzymatcher.qbs", "settings/settings.qbs", "stringutils/stringutils.qbs", - "objectpool/objectpool.qbs", "templateengine/templateengine.qbs", "treemodel/treemodel.qbs", ] diff --git a/tests/benchmarks/signals/signals.pro b/tests/benchmarks/signals/signals.pro new file mode 100644 index 00000000000..6ad94d9b84c --- /dev/null +++ b/tests/benchmarks/signals/signals.pro @@ -0,0 +1,5 @@ +TARGET = tst_bench_signals +QT = core testlib +CONFIG -= app_bundle + +SOURCES += tst_bench_signals.cpp diff --git a/tests/benchmarks/signals/tst_bench_signals.cpp b/tests/benchmarks/signals/tst_bench_signals.cpp new file mode 100644 index 00000000000..e1f873152aa --- /dev/null +++ b/tests/benchmarks/signals/tst_bench_signals.cpp @@ -0,0 +1,179 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** 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-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest> + +#include <functional> +#include <vector> + + +/* +Config: Using QtTest library 5.10.0, Qt 5.10.0 (x86_64-little_endian-lp64 shared (dynamic) + debug build; by GCC 7.2.1 20171205) + +PASS : BenchmarkSignals::qtMemfun() + 0.000068 msecs per iteration (total: 72, iterations: 1048576) +PASS : BenchmarkSignals::qtLambda() + 0.000066 msecs per iteration (total: 70, iterations: 1048576) +PASS : BenchmarkSignals::manualBind() + 0.00011 msecs per iteration (total: 60, iterations: 524288) +PASS : BenchmarkSignals::manualLambda() + 0.000043 msecs per iteration (total: 91, iterations: 2097152) + + +CONFIG += release + +********* Start testing of BenchmarkSignals ********* +PASS : BenchmarkSignals::qtMemfun() + 0.000061 msecs per iteration (total: 64, iterations: 1048576) +PASS : BenchmarkSignals::qtLambda() + 0.000058 msecs per iteration (total: 61, iterations: 1048576) + + // Not completely surprising, as all the top call can be inlined + +PASS : BenchmarkSignals::manualBind() + 0.0000078 msecs per iteration (total: 66, iterations: 8388608) +PASS : BenchmarkSignals::manualLambda() + 0.00000596 msecs per iteration (total: 100, iterations: 16777216) +PASS : BenchmarkSignals::cleanupTestCase() + + +The latter in instructions: + +PASS : BenchmarkSignals::qtMemfun() + 445 instruction reads per iteration (total: 445, iterations: 1) +PASS : BenchmarkSignals::qtLambda() + 440 instruction reads per iteration (total: 440, iterations: 1) +PASS : BenchmarkSignals::manualBind() + 113 instruction reads per iteration (total: 113, iterations: 1) +PASS : BenchmarkSignals::manualLambda() + 107 instruction reads per iteration (total: 107, iterations: 1) + +*/ + + +template <typename Type> +class NaiveSignal +{ +public: + using Callable = std::function<Type>; + + void connect(const Callable &callable) { m_callables.push_back(callable); } + + template <typename ...Args> + void operator()(Args ...args) const + { + for (const Callable &callable : m_callables) + callable(args...); + } + +private: + std::vector<Callable> m_callables; +}; + + +class BenchmarkSignals : public QObject +{ + Q_OBJECT + +public: + BenchmarkSignals() {} + +private slots: + void qtMemfun(); + void qtLambda(); + void manualBind(); + void manualLambda(); +}; + +class Tester : public QObject +{ + Q_OBJECT + +public: + NaiveSignal<void(int)> naiveSignal; + +signals: + void qtSignal(int); + +public: + void doit(int i) { sum += i; } + int sum = 0; +}; + +void BenchmarkSignals::qtMemfun() +{ + Tester tester; + connect(&tester, &Tester::qtSignal, &tester, &Tester::doit); + QBENCHMARK { + tester.qtSignal(1); + } +} + +void BenchmarkSignals::qtLambda() +{ + Tester tester; + connect(&tester, &Tester::qtSignal, [&](int x) { tester.sum += x; }); + QBENCHMARK { + tester.qtSignal(1); + } +} + +void BenchmarkSignals::manualBind() +{ + Tester tester; + tester.naiveSignal.connect(std::bind(&Tester::doit, &tester, std::placeholders::_1)); + QBENCHMARK { + tester.naiveSignal(1); + } +} + +void BenchmarkSignals::manualLambda() +{ + Tester tester; + tester.naiveSignal.connect([&](int x) { tester.sum += x; }); + QBENCHMARK { + tester.naiveSignal(1); + } +} + +QTEST_MAIN(BenchmarkSignals) + +#include "tst_bench_signals.moc" + diff --git a/tests/manual/fakevim/main.cpp b/tests/manual/fakevim/main.cpp index 7c364c09ad9..12d933e6934 100644 --- a/tests/manual/fakevim/main.cpp +++ b/tests/manual/fakevim/main.cpp @@ -74,105 +74,69 @@ public: } }; -class Proxy : public QObject +static void highlightMatches(QWidget *widget, const QString &pattern) { - Q_OBJECT - -public: - Proxy(QMainWindow *mw) - : m_mainWindow(mw) - {} - - void changeSelection(FakeVimHandler *handler, const QList<QTextEdit::ExtraSelection> &s) - { - QWidget *widget = handler->widget(); - if (auto ed = qobject_cast<QPlainTextEdit *>(widget)) - ed->setExtraSelections(s); - else if (auto ed = qobject_cast<QTextEdit *>(widget)) - ed->setExtraSelections(s); - } - - void changeStatusData(FakeVimHandler *, const QString &info) - { - m_statusData = info; - updateStatusBar(); - } - - void highlightMatches(FakeVimHandler *handler, const QString &pattern) - { - QWidget *widget = handler->widget(); - auto ed = qobject_cast<QTextEdit *>(widget); - if (!ed) - return; - - // Clear previous highlights. - ed->selectAll(); - QTextCursor cur = ed->textCursor(); - QTextCharFormat fmt = cur.charFormat(); - fmt.setBackground(Qt::transparent); - cur.setCharFormat(fmt); - - // Highlight matches. - QTextDocument *doc = ed->document(); - QRegExp re(pattern); - cur = doc->find(re); - - int a = cur.position(); - while ( !cur.isNull() ) { - if ( cur.hasSelection() ) { - fmt.setBackground(Qt::yellow); - cur.setCharFormat(fmt); - } else { - cur.movePosition(QTextCursor::NextCharacter); - } + auto ed = qobject_cast<QTextEdit *>(widget); + if (!ed) + return; + + // Clear previous highlights. + ed->selectAll(); + QTextCursor cur = ed->textCursor(); + QTextCharFormat fmt = cur.charFormat(); + fmt.setBackground(Qt::transparent); + cur.setCharFormat(fmt); + + // Highlight matches. + QTextDocument *doc = ed->document(); + QRegExp re(pattern); + cur = doc->find(re); + + int a = cur.position(); + while ( !cur.isNull() ) { + if ( cur.hasSelection() ) { + fmt.setBackground(Qt::yellow); + cur.setCharFormat(fmt); + } else { + cur.movePosition(QTextCursor::NextCharacter); + } + cur = doc->find(re, cur); + int b = cur.position(); + if (a == b) { + cur.movePosition(QTextCursor::NextCharacter); cur = doc->find(re, cur); - int b = cur.position(); - if (a == b) { - cur.movePosition(QTextCursor::NextCharacter); - cur = doc->find(re, cur); - b = cur.position(); - if (a == b) break; - } - a = b; + b = cur.position(); + if (a == b) break; } + a = b; } +} - void changeStatusMessage(FakeVimHandler *, const QString &contents, int cursorPos) +class StatusData +{ +public: + void setStatusMessage(const QString &msg, int pos) { - m_statusMessage = cursorPos == -1 ? contents - : contents.left(cursorPos) + QChar(10073) + contents.mid(cursorPos); - updateStatusBar(); + m_statusMessage = pos == -1 ? msg : msg.left(pos) + QChar(10073) + msg.mid(pos); } - void changeExtraInformation(FakeVimHandler *handler, const QString &info) + void setStatusInfo(const QString &info) { - QMessageBox::information(handler->widget(), tr("Information"), info); + m_statusData = info; } - void updateStatusBar() + QString currentStatusLine() const { - int slack = 80 - m_statusMessage.size() - m_statusData.size(); - QString msg = m_statusMessage + QString(slack, ' ') + m_statusData; - m_mainWindow->statusBar()->showMessage(msg); - } - - void handleExCommand(FakeVimHandler *, bool *handled, const ExCommand &cmd) - { - if (cmd.matches("q", "quit") || cmd.matches("qa", "qall")) { - QApplication::quit(); - *handled = true; - } else { - *handled = false; - } + const int slack = 80 - m_statusMessage.size() - m_statusData.size(); + return m_statusMessage + QString(slack, ' ') + m_statusData; } private: - QMainWindow *m_mainWindow; QString m_statusMessage; QString m_statusData; }; -QWidget *createEditorWidget(bool usePlainTextEdit) +static QWidget *createEditorWidget(bool usePlainTextEdit) { QWidget *editor = 0; if (usePlainTextEdit) @@ -185,7 +149,7 @@ QWidget *createEditorWidget(bool usePlainTextEdit) return editor; } -void initHandler(FakeVimHandler &handler) +static void initHandler(FakeVimHandler &handler) { // Set some Vim options. handler.handleCommand("set expandtab"); @@ -200,7 +164,7 @@ void initHandler(FakeVimHandler &handler) handler.setupWidget(); } -void initMainWindow(QMainWindow &mainWindow, QWidget *centralWidget, const QString &title) +static void initMainWindow(QMainWindow &mainWindow, QWidget *centralWidget, const QString &title) { mainWindow.setWindowTitle(QString("FakeVim (%1)").arg(title)); mainWindow.setCentralWidget(centralWidget); @@ -220,22 +184,6 @@ void readFile(FakeVimHandler &handler, const QString &editFileName) handler.handleCommand("r " + editFileName); } -void connectSignals(FakeVimHandler &handler, Proxy &proxy) -{ - QObject::connect(&handler, &FakeVimHandler::commandBufferChanged, - &proxy, &Proxy::changeStatusMessage); - QObject::connect(&handler, &FakeVimHandler::selectionChanged, - &proxy, &Proxy::changeSelection); - QObject::connect(&handler, &FakeVimHandler::extraInformationChanged, - &proxy, &Proxy::changeExtraInformation); - QObject::connect(&handler, &FakeVimHandler::statusDataChanged, - &proxy, &Proxy::changeStatusData); - QObject::connect(&handler, &FakeVimHandler::highlightMatches, - &proxy, &Proxy::highlightMatches); - QObject::connect(&handler, &FakeVimHandler::handleExCommandRequested, - &proxy, &Proxy::handleExCommand); -} - int main(int argc, char *argv[]) { QApplication app(argc, argv); @@ -250,16 +198,51 @@ int main(int argc, char *argv[]) // Create editor widget. QWidget *editor = createEditorWidget(usePlainTextEdit); - // Create FakeVimHandler instance which will emulate Vim behavior in editor widget. - FakeVimHandler handler(editor, nullptr); - // Create main window. QMainWindow mainWindow; initMainWindow(mainWindow, editor, usePlainTextEdit ? "QPlainTextEdit" : "QTextEdit"); - // Connect slots to FakeVimHandler signals. - Proxy proxy(&mainWindow); - connectSignals(handler, proxy); + // Keep track of status line related data. + StatusData statusData; + + // Create FakeVimHandler instance which will emulate Vim behavior in editor widget. + FakeVimHandler handler(editor, nullptr); + + handler.commandBufferChanged.connect([&](const QString &msg, int cursorPos, int, int) { + statusData.setStatusMessage(msg, cursorPos); + mainWindow.statusBar()->showMessage(statusData.currentStatusLine()); + }); + + handler.selectionChanged.connect([&handler](const QList<QTextEdit::ExtraSelection> &s) { + QWidget *widget = handler.widget(); + if (auto ed = qobject_cast<QPlainTextEdit *>(widget)) + ed->setExtraSelections(s); + else if (auto ed = qobject_cast<QTextEdit *>(widget)) + ed->setExtraSelections(s); + }); + + handler.extraInformationChanged.connect([&](const QString &info) { + statusData.setStatusInfo(info); + mainWindow.statusBar()->showMessage(statusData.currentStatusLine()); + }); + + handler.statusDataChanged.connect([&](const QString &info) { + statusData.setStatusInfo(info); + mainWindow.statusBar()->showMessage(statusData.currentStatusLine()); + }); + + handler.highlightMatches.connect([&](const QString &needle) { + highlightMatches(handler.widget(), needle); + }); + + handler.handleExCommandRequested.connect([](bool *handled, const ExCommand &cmd) { + if (cmd.matches("q", "quit") || cmd.matches("qa", "qall")) { + QApplication::quit(); + *handled = true; + } else { + *handled = false; + } + }); // Initialize FakeVimHandler. initHandler(handler); @@ -269,5 +252,3 @@ int main(int argc, char *argv[]) return app.exec(); } - -#include "main.moc" diff --git a/tests/manual/pluginview/plugins/plugin1/plugin1.cpp b/tests/manual/pluginview/plugins/plugin1/plugin1.cpp index f6fd28006b7..5308c8147e3 100644 --- a/tests/manual/pluginview/plugins/plugin1/plugin1.cpp +++ b/tests/manual/pluginview/plugins/plugin1/plugin1.cpp @@ -27,21 +27,20 @@ #include <extensionsystem/pluginmanager.h> -#include <QObject> - using namespace Plugin1; -MyPlugin1::MyPlugin1() - : initializeCalled(false) +MyPlugin1::~MyPlugin1() { + ExtensionSystem::PluginManager::removeObject(object1); + ExtensionSystem::PluginManager::removeObject(object2); } bool MyPlugin1::initialize(const QStringList & /*arguments*/, QString *errorString) { initializeCalled = true; - QObject *obj = new QObject(this); - obj->setObjectName("MyPlugin1"); - addAutoReleasedObject(obj); + object1 = new QObject(this); + object1->setObjectName("MyPlugin1"); + ExtensionSystem::PluginManager::addObject(object1); bool found2 = false; bool found3 = false; @@ -69,7 +68,7 @@ void MyPlugin1::extensionsInitialized() if (!initializeCalled) return; // don't do this at home, it's just done here for the test - QObject *obj = new QObject(this); - obj->setObjectName("MyPlugin1_running"); - addAutoReleasedObject(obj); + object2 = new QObject(this); + object2->setObjectName("MyPlugin1_running"); + ExtensionSystem::PluginManager::addObject(object2); } diff --git a/tests/manual/pluginview/plugins/plugin1/plugin1.h b/tests/manual/pluginview/plugins/plugin1/plugin1.h index 5621421aea6..68c819e1187 100644 --- a/tests/manual/pluginview/plugins/plugin1/plugin1.h +++ b/tests/manual/pluginview/plugins/plugin1/plugin1.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QString> - namespace Plugin1 { class MyPlugin1 : public ExtensionSystem::IPlugin @@ -38,13 +35,16 @@ class MyPlugin1 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin1.json") public: - MyPlugin1(); + MyPlugin1() = default; + ~MyPlugin1() final; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; private: - bool initializeCalled; + bool initializeCalled = false; + QObject *object1 = nullptr; + QObject *object2 = nullptr; }; } // namespace Plugin1 diff --git a/tests/manual/pluginview/plugins/plugin2/plugin2.cpp b/tests/manual/pluginview/plugins/plugin2/plugin2.cpp index 72e194fb910..19f63f57a72 100644 --- a/tests/manual/pluginview/plugins/plugin2/plugin2.cpp +++ b/tests/manual/pluginview/plugins/plugin2/plugin2.cpp @@ -27,22 +27,21 @@ #include <extensionsystem/pluginmanager.h> -#include <QObject> - using namespace Plugin2; -MyPlugin2::MyPlugin2() - : initializeCalled(false) +MyPlugin2::~MyPlugin2() { + ExtensionSystem::PluginManager::removeObject(object1); + ExtensionSystem::PluginManager::removeObject(object2); } bool MyPlugin2::initialize(const QStringList & /*arguments*/, QString *errorString) { Q_UNUSED(errorString) initializeCalled = true; - QObject *obj = new QObject(this); - obj->setObjectName("MyPlugin2"); - addAutoReleasedObject(obj); + object1 = new QObject(this); + object1->setObjectName("MyPlugin2"); + ExtensionSystem::PluginManager::addObject(object1); return true; } @@ -52,7 +51,7 @@ void MyPlugin2::extensionsInitialized() if (!initializeCalled) return; // don't do this at home, it's just done here for the test - QObject *obj = new QObject(this); - obj->setObjectName("MyPlugin2_running"); - addAutoReleasedObject(obj); + object2 = new QObject(this); + object2->setObjectName("MyPlugin2_running"); + ExtensionSystem::PluginManager::addObject(object2); } diff --git a/tests/manual/pluginview/plugins/plugin2/plugin2.h b/tests/manual/pluginview/plugins/plugin2/plugin2.h index c949b318f4f..df6d1893a2e 100644 --- a/tests/manual/pluginview/plugins/plugin2/plugin2.h +++ b/tests/manual/pluginview/plugins/plugin2/plugin2.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QString> - namespace Plugin2 { class MyPlugin2 : public ExtensionSystem::IPlugin @@ -38,13 +35,16 @@ class MyPlugin2 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin2.json") public: - MyPlugin2(); + MyPlugin2() = default; + ~MyPlugin2() final; - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; private: - bool initializeCalled; + bool initializeCalled = false; + QObject *object1 = nullptr; + QObject *object2 = nullptr; }; } // namespace Plugin2 diff --git a/tests/manual/pluginview/plugins/plugin3/plugin3.cpp b/tests/manual/pluginview/plugins/plugin3/plugin3.cpp index 10e44366fc8..0ba714709f5 100644 --- a/tests/manual/pluginview/plugins/plugin3/plugin3.cpp +++ b/tests/manual/pluginview/plugins/plugin3/plugin3.cpp @@ -27,24 +27,23 @@ #include <extensionsystem/pluginmanager.h> -#include <QObject> - using namespace Plugin3; -MyPlugin3::MyPlugin3() - : initializeCalled(false) +MyPlugin3::~MyPlugin3() { + ExtensionSystem::PluginManager::removeObject(object1); + ExtensionSystem::PluginManager::removeObject(object2); } bool MyPlugin3::initialize(const QStringList & /*arguments*/, QString *errorString) { initializeCalled = true; - QObject *obj = new QObject(this); - obj->setObjectName("MyPlugin3"); - addAutoReleasedObject(obj); + object1 = new QObject(this); + object1->setObjectName("MyPlugin3"); + ExtensionSystem::PluginManager::addObject(object1); bool found2 = false; - foreach (QObject *object, ExtensionSystem::PluginManager::instance()->allObjects()) { + foreach (QObject *object, ExtensionSystem::PluginManager::allObjects()) { if (object->objectName() == "MyPlugin2") found2 = true; } @@ -60,7 +59,7 @@ void MyPlugin3::extensionsInitialized() if (!initializeCalled) return; // don't do this at home, it's just done here for the test - QObject *obj = new QObject(this); - obj->setObjectName("MyPlugin3_running"); - addAutoReleasedObject(obj); + object2 = new QObject(this); + object2->setObjectName("MyPlugin3_running"); + ExtensionSystem::PluginManager::addObject(object2); } diff --git a/tests/manual/pluginview/plugins/plugin3/plugin3.h b/tests/manual/pluginview/plugins/plugin3/plugin3.h index 0678e698f08..8ce26fe575d 100644 --- a/tests/manual/pluginview/plugins/plugin3/plugin3.h +++ b/tests/manual/pluginview/plugins/plugin3/plugin3.h @@ -27,9 +27,6 @@ #include <extensionsystem/iplugin.h> -#include <QObject> -#include <QString> - namespace Plugin3 { class MyPlugin3 : public ExtensionSystem::IPlugin @@ -38,13 +35,16 @@ class MyPlugin3 : public ExtensionSystem::IPlugin Q_PLUGIN_METADATA(IID "plugin" FILE "plugin3.json") public: - MyPlugin3(); + MyPlugin3() = default; + ~MyPlugin3(); - bool initialize(const QStringList &arguments, QString *errorString); - void extensionsInitialized(); + bool initialize(const QStringList &arguments, QString *errorString) final; + void extensionsInitialized() final; private: - bool initializeCalled; + bool initializeCalled = false; + QObject *object1 = nullptr; + QObject *object2 = nullptr; }; } // namespace Plugin3 diff --git a/tests/system/objects.map b/tests/system/objects.map index a4d87ecba54..dc19df3739c 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -104,7 +104,7 @@ :Options.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Options.qt_tabwidget_stackedwidget_QStackedWidget {name='qt_tabwidget_stackedwidget' type='QStackedWidget' visible='1' window=':Options_Core::Internal::SettingsDialog'} :Options.qt_tabwidget_tabbar_QTabBar {name='qc_settings_main_tabbar' type='QTabBar' visible='1' window=':Options_Core::Internal::SettingsDialog'} -:Options_Core::Internal::SettingsDialog {type='Core::Internal::SettingsDialog' unnamed='1' visible='1' windowTitle~='(Options|Preferences)'} +:Options_Core::Internal::SettingsDialog {type='QDialog' unnamed='1' visible='1' windowTitle~='(Options|Preferences)'} :Options_QListView {type='QListView' unnamed='1' visible='1' window=':Options_Core::Internal::SettingsDialog'} :PasteSelectDialog.Cancel_QPushButton {text='Cancel' type='QPushButton' unnamed='1' visible='1' window=':PasteSelectDialog_CodePaster::PasteSelectDialog'} :PasteSelectDialog.OK_QPushButton {text='OK' type='QPushButton' unnamed='1' visible='1' window=':PasteSelectDialog_CodePaster::PasteSelectDialog'} diff --git a/tests/unit/unittest/clangcodemodelserver-test.cpp b/tests/unit/unittest/clangcodemodelserver-test.cpp index df4afa8004b..ebcb5dd3d3e 100644 --- a/tests/unit/unittest/clangcodemodelserver-test.cpp +++ b/tests/unit/unittest/clangcodemodelserver-test.cpp @@ -92,6 +92,19 @@ MATCHER_P5(HasDirtyDocument, } } +MATCHER_P(PartlyContains, token, "") +{ + for (const auto &item: arg) { + if (item.types == token.types && item.line == token.line && item.column == token.column + && item.length == token.length) { + return true; + } + } + return false; +} + +static constexpr int AnnotationJobsMultiplier = 2; + class ClangCodeModelServer : public ::testing::Test { protected: @@ -106,14 +119,14 @@ protected: void changeProjectPartArguments(); void registerProjectAndFile(const Utf8String &filePath, - int expectedDocumentAnnotationsChangedMessages = 1); + int expectedDocumentAnnotationsChangedMessages = AnnotationJobsMultiplier); void registerProjectAndFileAndWaitForFinished(const Utf8String &filePath, - int expectedDocumentAnnotationsChangedMessages = 1); - void registerProjectAndFilesAndWaitForFinished(int expectedDocumentAnnotationsChangedMessages = 2); + int expectedDocumentAnnotationsChangedMessages = AnnotationJobsMultiplier); + void registerProjectAndFilesAndWaitForFinished(int expectedDocumentAnnotationsChangedMessages = 2 * AnnotationJobsMultiplier); void registerFile(const Utf8String &filePath, - int expectedDocumentAnnotationsChangedMessages = 1); + int expectedDocumentAnnotationsChangedMessages = AnnotationJobsMultiplier); void registerFile(const Utf8String &filePath, const Utf8String &projectPartId, - int expectedDocumentAnnotationsChangedMessages = 1); + int expectedDocumentAnnotationsChangedMessages = AnnotationJobsMultiplier); void registerFiles(int expectedDocumentAnnotationsChangedMessages); void registerFileWithUnsavedContent(const Utf8String &filePath, const Utf8String &content); @@ -245,7 +258,7 @@ TEST_F(ClangCodeModelServerSlowTest, NoInitialDocumentAnnotationsForClosedDocume TEST_F(ClangCodeModelServerSlowTest, NoDocumentAnnotationsForClosedDocument) { - const int expectedDocumentAnnotationsChangedCount = 1; // Only for registration. + const int expectedDocumentAnnotationsChangedCount = AnnotationJobsMultiplier; // Only for registration. registerProjectAndFileAndWaitForFinished(filePathA, expectedDocumentAnnotationsChangedCount); updateUnsavedContent(filePathA, Utf8String(), 1); @@ -254,7 +267,7 @@ TEST_F(ClangCodeModelServerSlowTest, NoDocumentAnnotationsForClosedDocument) TEST_F(ClangCodeModelServerSlowTest, NoInitialDocumentAnnotationsForOutdatedDocumentRevision) { - const int expectedDocumentAnnotationsChangedCount = 1; // Only for registration. + const int expectedDocumentAnnotationsChangedCount = AnnotationJobsMultiplier; // Only for registration. registerProjectAndFile(filePathA, expectedDocumentAnnotationsChangedCount); updateUnsavedContent(filePathA, Utf8String(), 1); @@ -262,7 +275,7 @@ TEST_F(ClangCodeModelServerSlowTest, NoInitialDocumentAnnotationsForOutdatedDocu TEST_F(ClangCodeModelServerSlowTest, NoCompletionsForClosedDocument) { - const int expectedDocumentAnnotationsChangedCount = 1; // Only for registration. + const int expectedDocumentAnnotationsChangedCount = AnnotationJobsMultiplier; // Only for registration. registerProjectAndFileAndWaitForFinished(filePathA, expectedDocumentAnnotationsChangedCount); completeCodeInFileA(); @@ -271,7 +284,7 @@ TEST_F(ClangCodeModelServerSlowTest, NoCompletionsForClosedDocument) TEST_F(ClangCodeModelServerSlowTest, CodeCompletionDependingOnProject) { - const int expectedDocumentAnnotationsChangedCount = 2; // For registration and due to project change. + const int expectedDocumentAnnotationsChangedCount = 2 * AnnotationJobsMultiplier; // For registration and due to project change. registerProjectAndFileAndWaitForFinished(filePathB, expectedDocumentAnnotationsChangedCount); expectCompletionFromFileBEnabledByMacro(); @@ -282,7 +295,7 @@ TEST_F(ClangCodeModelServerSlowTest, CodeCompletionDependingOnProject) TEST_F(ClangCodeModelServerSlowTest, GetCodeCompletionForUnsavedFile) { registerProjectPart(); - expectDocumentAnnotationsChanged(1); + expectDocumentAnnotationsChanged(AnnotationJobsMultiplier); registerFileWithUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion1)); expectCompletionFromFileAUnsavedMethodVersion1(); @@ -291,7 +304,7 @@ TEST_F(ClangCodeModelServerSlowTest, GetCodeCompletionForUnsavedFile) TEST_F(ClangCodeModelServerSlowTest, GetNoCodeCompletionAfterRemovingUnsavedFile) { - const int expectedDocumentAnnotationsChangedCount = 2; // For registration and update/removal. + const int expectedDocumentAnnotationsChangedCount = 2 * AnnotationJobsMultiplier; // For registration and update/removal. registerProjectAndFileAndWaitForFinished(filePathA, expectedDocumentAnnotationsChangedCount); removeUnsavedFile(filePathA); @@ -301,7 +314,7 @@ TEST_F(ClangCodeModelServerSlowTest, GetNoCodeCompletionAfterRemovingUnsavedFile TEST_F(ClangCodeModelServerSlowTest, GetNewCodeCompletionAfterUpdatingUnsavedFile) { - const int expectedDocumentAnnotationsChangedCount = 2; // For registration and update/removal. + const int expectedDocumentAnnotationsChangedCount = 2 * AnnotationJobsMultiplier; // For registration and update/removal. registerProjectAndFileAndWaitForFinished(filePathA, expectedDocumentAnnotationsChangedCount); updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); @@ -311,7 +324,7 @@ TEST_F(ClangCodeModelServerSlowTest, GetNewCodeCompletionAfterUpdatingUnsavedFil TEST_F(ClangCodeModelServerSlowTest, TranslationUnitAfterCreationIsNotDirty) { - registerProjectAndFile(filePathA, 1); + registerProjectAndFile(filePathA, AnnotationJobsMultiplier); ASSERT_THAT(clangServer, HasDirtyDocument(filePathA, projectPartId, 0U, false, false)); } @@ -331,7 +344,7 @@ TEST_F(ClangCodeModelServerSlowTest, SetCurrentAndVisibleEditor) TEST_F(ClangCodeModelServerSlowTest, StartCompletionJobFirstOnEditThatTriggersCompletion) { - registerProjectAndFile(filePathA, 2); + registerProjectAndFile(filePathA, 2 * AnnotationJobsMultiplier); ASSERT_TRUE(waitUntilAllJobsFinished()); expectCompletionFromFileA(); @@ -345,7 +358,7 @@ TEST_F(ClangCodeModelServerSlowTest, StartCompletionJobFirstOnEditThatTriggersCo TEST_F(ClangCodeModelServerSlowTest, SupportiveTranslationUnitNotInitializedAfterRegister) { - registerProjectAndFile(filePathA, 1); + registerProjectAndFile(filePathA, AnnotationJobsMultiplier); ASSERT_TRUE(waitUntilAllJobsFinished()); ASSERT_FALSE(isSupportiveTranslationUnitInitialized(filePathA)); @@ -353,7 +366,7 @@ TEST_F(ClangCodeModelServerSlowTest, SupportiveTranslationUnitNotInitializedAfte TEST_F(ClangCodeModelServerSlowTest, SupportiveTranslationUnitIsSetupAfterFirstEdit) { - registerProjectAndFile(filePathA, 2); + registerProjectAndFile(filePathA, 2 * AnnotationJobsMultiplier); ASSERT_TRUE(waitUntilAllJobsFinished()); updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); @@ -364,7 +377,7 @@ TEST_F(ClangCodeModelServerSlowTest, SupportiveTranslationUnitIsSetupAfterFirstE TEST_F(ClangCodeModelServerSlowTest, DoNotRunDuplicateJobs) { - registerProjectAndFile(filePathA, 3); + registerProjectAndFile(filePathA, 3 * AnnotationJobsMultiplier); ASSERT_TRUE(waitUntilAllJobsFinished()); updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion2), 1); ASSERT_TRUE(waitUntilAllJobsFinished()); @@ -378,7 +391,7 @@ TEST_F(ClangCodeModelServerSlowTest, DoNotRunDuplicateJobs) TEST_F(ClangCodeModelServerSlowTest, OpenDocumentAndEdit) { - registerProjectAndFile(filePathA, 4); + registerProjectAndFile(filePathA, 4 * AnnotationJobsMultiplier); ASSERT_TRUE(waitUntilAllJobsFinished()); for (unsigned revision = 1; revision <= 3; ++revision) { @@ -404,7 +417,7 @@ TEST_F(ClangCodeModelServerSlowTest, IsNotCurrentCurrentAndVisibleEditorAnymore) TEST_F(ClangCodeModelServerSlowTest, TranslationUnitAfterUpdateNeedsReparse) { - registerProjectAndFileAndWaitForFinished(filePathA, 2); + registerProjectAndFileAndWaitForFinished(filePathA, 2 * AnnotationJobsMultiplier); updateUnsavedContent(filePathA, unsavedContent(filePathAUnsavedVersion1), 1U); ASSERT_THAT(clangServer, HasDirtyDocument(filePathA, projectPartId, 1U, true, true)); @@ -412,7 +425,7 @@ TEST_F(ClangCodeModelServerSlowTest, TranslationUnitAfterUpdateNeedsReparse) TEST_F(ClangCodeModelServerSlowTest, TakeOverJobsOnProjectPartChange) { - registerProjectAndFileAndWaitForFinished(filePathC, 2); + registerProjectAndFileAndWaitForFinished(filePathC, 2 * AnnotationJobsMultiplier); updateVisibilty(filePathB, filePathB); // Disable processing jobs requestReferences(); @@ -557,8 +570,8 @@ DocumentProcessor ClangCodeModelServer::documentProcessorForFile(const Utf8Strin void ClangCodeModelServer::expectCompletion(const CodeCompletion &completion) { EXPECT_CALL(mockClangCodeModelClient, - codeCompleted(Property(&CodeCompletedMessage::codeCompletions, - Contains(completion)))) + codeCompleted(Field(&CodeCompletedMessage::codeCompletions, + Contains(completion)))) .Times(1); } @@ -596,8 +609,8 @@ void ClangCodeModelServer::expectNoCompletionWithUnsavedMethod() CodeCompletion::FunctionCompletionKind); EXPECT_CALL(mockClangCodeModelClient, - codeCompleted(Property(&CodeCompletedMessage::codeCompletions, - Not(Contains(completion))))) + codeCompleted(Field(&CodeCompletedMessage::codeCompletions, + Not(Contains(completion))))) .Times(1); } @@ -610,8 +623,8 @@ void ClangCodeModelServer::expectReferences() EXPECT_CALL(mockClangCodeModelClient, references( - Property(&ReferencesMessage::references, - Eq(references)))) + Field(&ReferencesMessage::references, + Eq(references)))) .Times(1); } @@ -624,8 +637,8 @@ void ClangCodeModelServer::expectFollowSymbol() EXPECT_CALL(mockClangCodeModelClient, followSymbol( - Property(&FollowSymbolMessage::sourceRange, - Eq(classDefinition)))) + Field(&FollowSymbolMessage::sourceRange, + Eq(classDefinition)))) .Times(1); } @@ -669,14 +682,11 @@ void ClangCodeModelServer::expectDocumentAnnotationsChangedForFileBWithSpecificH types.mainHighlightingType = ClangBackEnd::HighlightingType::Function; types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::Declaration); types.mixinHighlightingTypes.push_back(ClangBackEnd::HighlightingType::FunctionDefinition); - const TokenInfoContainer tokenInfo(1, 6, 8, types, Utf8String("function", 8), - Utf8String("void (int)", 10), true, false, true, true); - + const TokenInfoContainer tokenInfo(1, 6, 8, types); EXPECT_CALL(mockClangCodeModelClient, documentAnnotationsChanged( - Property(&DocumentAnnotationsChangedMessage::tokenInfos, - Contains(tokenInfo)))) - .Times(1); + Field(&DocumentAnnotationsChangedMessage::tokenInfos, + PartlyContains(tokenInfo)))).Times(AnnotationJobsMultiplier); } void ClangCodeModelServer::updateUnsavedContent(const Utf8String &filePath, diff --git a/tests/unit/unittest/clangcompletecodejob-test.cpp b/tests/unit/unittest/clangcompletecodejob-test.cpp index 0c5d3082190..fd7113a2eb5 100644 --- a/tests/unit/unittest/clangcompletecodejob-test.cpp +++ b/tests/unit/unittest/clangcompletecodejob-test.cpp @@ -79,7 +79,7 @@ TEST_F(CompleteCodeJob, ForwardTicketNumber) job.setContext(jobContextWithMockClient); job.prepareAsyncRun(); EXPECT_CALL(mockIpcClient, - codeCompleted(Property(&CodeCompletedMessage::ticketNumber, + codeCompleted(Field(&CodeCompletedMessage::ticketNumber, Eq(jobRequest.ticketNumber)))) .Times(1); diff --git a/tests/unit/unittest/clangdocument-test.cpp b/tests/unit/unittest/clangdocument-test.cpp index a830dbbe1a6..0acce63717c 100644 --- a/tests/unit/unittest/clangdocument-test.cpp +++ b/tests/unit/unittest/clangdocument-test.cpp @@ -32,7 +32,7 @@ #include <clangtranslationunit.h> #include <commandlinearguments.h> #include <diagnosticset.h> -#include <tokeninfos.h> +#include <tokenprocessor.h> #include <filecontainer.h> #include <projectpart.h> #include <projectpartcontainer.h> @@ -195,7 +195,7 @@ TEST_F(Document, DocumentRevisionInFileContainerGetter) { document.setDocumentRevision(74); - ASSERT_THAT(document.fileContainer().documentRevision(), 74); + ASSERT_THAT(document.fileContainer().documentRevision, 74); } TEST_F(DocumentSlowTest, DependedFilePaths) diff --git a/tests/unit/unittest/clangquery-test.cpp b/tests/unit/unittest/clangquery-test.cpp index ec1984084ff..8c486a47d78 100644 --- a/tests/unit/unittest/clangquery-test.cpp +++ b/tests/unit/unittest/clangquery-test.cpp @@ -69,7 +69,7 @@ TEST_F(ClangQuery, NoSourceRangesForDefaultConstruction) { auto sourceRanges = simpleFunctionQuery.takeSourceRanges(); - ASSERT_THAT(sourceRanges.sourceRangeWithTextContainers(), IsEmpty()); + ASSERT_THAT(sourceRanges.sourceRangeWithTextContainers, IsEmpty()); } TEST_F(ClangQuerySlowTest, SourceRangesForSimpleFunctionDeclarationAreNotEmpty) @@ -78,7 +78,7 @@ TEST_F(ClangQuerySlowTest, SourceRangesForSimpleFunctionDeclarationAreNotEmpty) simpleFunctionQuery.findLocations(); - ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers(), Not(IsEmpty())); + ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers, Not(IsEmpty())); } TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange) @@ -87,7 +87,7 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFunctionDeclarationRange) simpleFunctionQuery.findLocations(); - ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers(), + ASSERT_THAT(simpleFunctionQuery.takeSourceRanges().sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 8, 2, "int function(int* pointer, int value)\n{\n if (pointer == nullptr) {\n return value + 1;\n } else {\n return value - 1;\n }\n}"))); } @@ -101,7 +101,7 @@ TEST_F(ClangQuerySlowTest, SourceRangeInUnsavedFileDeclarationRange) query.findLocations(); - ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), + ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();"))); } @@ -113,7 +113,7 @@ TEST_F(ClangQuerySlowTest, FileIsNotExistingButTheUnsavedDataIsParsed) query.findLocations(); - ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), + ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 12, "void f() {}"))); } @@ -127,7 +127,7 @@ TEST_F(ClangQuerySlowTest, DISABLED_SourceRangeInUnsavedFileDeclarationRangeOver query.findLocations(); - ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers(), + ASSERT_THAT(query.takeSourceRanges().sourceRangeWithTextContainers, Contains(IsSourceRangeWithText(1, 1, 1, 15, "void unsaved();"))); } @@ -137,7 +137,7 @@ TEST_F(ClangQuerySlowTest, RootSourceRangeForSimpleFieldDeclarationRange) simpleClassQuery.findLocations(); - ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers().at(0), + ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers.at(0), IsSourceRangeWithText(4, 5, 4, 10, " int x;")); } @@ -145,7 +145,7 @@ TEST_F(ClangQuerySlowTest, NoSourceRangesForEmptyQuery) { simpleClassQuery.findLocations(); - ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers(), IsEmpty()); + ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers, IsEmpty()); } TEST_F(ClangQuerySlowTest, NoSourceRangesForWrongQuery) @@ -154,7 +154,7 @@ TEST_F(ClangQuerySlowTest, NoSourceRangesForWrongQuery) simpleClassQuery.findLocations(); - ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers(), IsEmpty()); + ASSERT_THAT(simpleClassQuery.takeSourceRanges().sourceRangeWithTextContainers, IsEmpty()); } TEST_F(ClangQuerySlowTest, NoDiagnosticsForDefaultConstruction) diff --git a/tests/unit/unittest/clangquerygatherer-test.cpp b/tests/unit/unittest/clangquerygatherer-test.cpp index 59503bc61fa..9c575f6a0f5 100644 --- a/tests/unit/unittest/clangquerygatherer-test.cpp +++ b/tests/unit/unittest/clangquerygatherer-test.cpp @@ -48,13 +48,13 @@ using testing::Contains; using testing::Each; using testing::ElementsAre; using testing::Eq; +using testing::Field; using testing::Ge; using testing::IsEmpty; using testing::Le; using testing::NiceMock; using testing::Pair; using testing::PrintToString; -using testing::Property; using testing::SizeIs; using testing::UnorderedElementsAre; using testing::_; @@ -71,8 +71,8 @@ MATCHER_P2(Contains, line, column, + ")" ) { - return arg.line() == uint(line) - && arg.column() == uint(column); + return arg.line == uint(line) + && arg.column == uint(column); } class ClangQueryGatherer : public ::testing::Test @@ -111,9 +111,9 @@ TEST_F(ClangQueryGatherer, CreateSourceRanges) auto sourceRangesAndDiagnostics = gatherer.createSourceRangesForSource(&filePathCache, source.clone(), {unsaved}, query.clone()); ASSERT_THAT(sourceRangesAndDiagnostics, - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(2, 1, 2, 12, "void f() {}"))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(2, 1, 2, 12, "void f() {}"))))); } TEST_F(ClangQueryGatherer, CreateSourceRangessWithUnsavedContent) @@ -121,9 +121,9 @@ TEST_F(ClangQueryGatherer, CreateSourceRangessWithUnsavedContent) auto sourceRangesAndDiagnostics = gatherer.createSourceRangesForSource(&filePathCache, source.clone(), {unsaved}, query.clone()); ASSERT_THAT(sourceRangesAndDiagnostics, - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); } TEST_F(ClangQueryGatherer, CanCreateSourceRangesIfItHasSources) @@ -143,9 +143,9 @@ TEST_F(ClangQueryGatherer, CreateSourceRangesForNextSource) auto sourceRangesAndDiagnostics = gatherer.createNextSourceRanges(); ASSERT_THAT(sourceRangesAndDiagnostics, - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); } TEST_F(ClangQueryGatherer, CreateSourceRangesForNextSourcePopsSource) @@ -161,9 +161,9 @@ TEST_F(ClangQueryGatherer, StartCreateSourceRangesForNextSource) future.wait(); ASSERT_THAT(future.get(), - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 1, 9, "void f();"))))); } TEST_F(ClangQueryGatherer, StartCreateSourceRangesForNextSourcePopsSource) @@ -195,15 +195,15 @@ TEST_F(ClangQueryGatherer, AfterStartCreateSourceRangesMessagesGetCollected) ASSERT_THAT(manyGatherer.allCurrentProcessedMessages(), UnorderedElementsAre( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre(IsSourceRangeWithText(1, 1, 1, 9, "void f();"), + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre(IsSourceRangeWithText(1, 1, 1, 9, "void f();"), IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(1, 1, 1, 13, "int header();"), - IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(1, 1, 1, 13, "int header();"), + IsSourceRangeWithText(3, 1, 3, 15, "int function();")))))); } TEST_F(ClangQueryGatherer, GetFinishedMessages) @@ -216,16 +216,16 @@ TEST_F(ClangQueryGatherer, GetFinishedMessages) ASSERT_THAT(messages, AllOf(SizeIs(2), UnorderedElementsAre( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(1, 1, 1, 9, "void f();"), - IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(1, 1, 1, 13, "int header();"), - IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(1, 1, 1, 9, "void f();"), + IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(1, 1, 1, 13, "int header();"), + IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); } TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass) @@ -241,10 +241,10 @@ TEST_F(ClangQueryGatherer, GetFinishedMessagesAfterSecondPass) ASSERT_THAT(messages, AllOf(SizeIs(1), ElementsAre( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); } TEST_F(ClangQueryGatherer, FilterDuplicates) @@ -258,20 +258,20 @@ TEST_F(ClangQueryGatherer, FilterDuplicates) ASSERT_THAT(messages, AllOf(SizeIs(3), UnorderedElementsAre( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(1, 1, 1, 9, "void f();"), - IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(1, 1, 1, 13, "int header();"), - IsSourceRangeWithText(3, 1, 3, 15, "int function();")))), - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - UnorderedElementsAre( - IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(1, 1, 1, 9, "void f();"), + IsSourceRangeWithText(2, 1, 2, 12, "void f() {}")))), + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(1, 1, 1, 13, "int header();"), + IsSourceRangeWithText(3, 1, 3, 15, "int function();")))), + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + UnorderedElementsAre( + IsSourceRangeWithText(3, 1, 3, 15, "int function();"))))))); } TEST_F(ClangQueryGatherer, AfterGetFinishedMessagesFuturesAreReduced) diff --git a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp index 33268cd0022..1272a63da68 100644 --- a/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp +++ b/tests/unit/unittest/clangqueryprojectfindfilter-test.cpp @@ -41,9 +41,9 @@ namespace { using testing::_; using testing::AllOf; +using testing::Field; using testing::NiceMock; using testing::NotNull; -using testing::Property; using testing::Return; using testing::ReturnNew; using testing::DefaultValue; @@ -166,9 +166,9 @@ TEST_F(ClangQueryProjectFindFilter, CallingRequestSourceRangesAndDiagnostics) EXPECT_CALL(mockRefactoringServer, requestSourceRangesAndDiagnosticsForQueryMessage( AllOf( - Property(&Message::source, - Property(&FileContainer::unsavedFileContent, exampleContent)), - Property(&Message::query, queryText)))); + Field(&Message::source, + Field(&FileContainer::unsavedFileContent, exampleContent)), + Field(&Message::query, queryText)))); findFilter.requestSourceRangesAndDiagnostics(QString(queryText), QString(exampleContent)); } diff --git a/tests/unit/unittest/clangreferencescollector-test.cpp b/tests/unit/unittest/clangreferencescollector-test.cpp index d0077c475f2..fbc0e81bc3b 100644 --- a/tests/unit/unittest/clangreferencescollector-test.cpp +++ b/tests/unit/unittest/clangreferencescollector-test.cpp @@ -63,10 +63,10 @@ std::ostream &operator<<(std::ostream &os, const ReferencesResult &value) os << "ReferencesResult("; os << value.isLocalVariable << ", {"; for (const SourceRangeContainer &r : value.references) { - os << r.start().line() << ","; - os << r.start().column() << ","; - QTC_CHECK(r.start().line() == r.end().line()); - os << r.end().column() - r.start().column() << ","; + os << r.start.line << ","; + os << r.start.column << ","; + QTC_CHECK(r.start.line == r.end.line); + os << r.end.column - r.start.column << ","; } os << "})"; diff --git a/tests/unit/unittest/clangrequestreferencesjob-test.cpp b/tests/unit/unittest/clangrequestreferencesjob-test.cpp index 9105a660708..5f92c869ec2 100644 --- a/tests/unit/unittest/clangrequestreferencesjob-test.cpp +++ b/tests/unit/unittest/clangrequestreferencesjob-test.cpp @@ -79,7 +79,7 @@ TEST_F(RequestReferencesJob, ForwardTicketNumber) job.setContext(jobContextWithMockClient); job.prepareAsyncRun(); EXPECT_CALL(mockIpcClient, - references(Property(&ReferencesMessage::ticketNumber, Eq(jobRequest.ticketNumber)))) + references(Field(&ReferencesMessage::ticketNumber, Eq(jobRequest.ticketNumber)))) .Times(1); job.runAsync(); diff --git a/tests/unit/unittest/clangstring-test.cpp b/tests/unit/unittest/clangstring-test.cpp index bea70a7ab06..8e30da93e24 100644 --- a/tests/unit/unittest/clangstring-test.cpp +++ b/tests/unit/unittest/clangstring-test.cpp @@ -105,9 +105,9 @@ TEST(ClangString, NotEqualBetweenClangStrings) ClangString text(CXString{"text", 0}); ClangString text2(CXString{"text ", 0}); - bool textIsEqual = text == text2; + bool textIsNotEqual = text != text2; - ASSERT_FALSE(textIsEqual); + ASSERT_TRUE(textIsNotEqual); } TEST(ClangString, EqualClangStringAndCString) @@ -123,9 +123,9 @@ TEST(ClangString, NotEqualClangStringAndCString) { ClangString text(CXString{"text", 0}); - bool textIsEqual = text == "text "; + bool textIsNotEqual = text != "text "; - ASSERT_FALSE(textIsEqual); + ASSERT_TRUE(textIsNotEqual); } TEST(ClangString, EqualCStringAndClangString) @@ -137,6 +137,15 @@ TEST(ClangString, EqualCStringAndClangString) ASSERT_TRUE(textIsEqual); } +TEST(ClangString, NotEqualCStringAndClangString) +{ + ClangString text(CXString{"text", 0}); + + bool textIsNotEqual = "text " != text; + + ASSERT_TRUE(textIsNotEqual); +} + TEST(ClangString, EqualClangStringPointerAndCString) { ClangString text(CXString{"text", 0}); @@ -152,9 +161,9 @@ TEST(ClangString, NotEqualClangStringPointerAndCString) ClangString text(CXString{"text", 0}); const char *cString = "text "; - bool textIsEqual = cString == text; + bool textIsNotEqual = cString != text; - ASSERT_FALSE(textIsEqual); + ASSERT_TRUE(textIsNotEqual); } TEST(ClangString, EqualCStringAndClangStringPointer) @@ -167,6 +176,16 @@ TEST(ClangString, EqualCStringAndClangStringPointer) ASSERT_TRUE(textIsEqual); } +TEST(ClangString, NotEqualCStringAndClangStringPointer) +{ + ClangString text(CXString{"text", 0}); + const char *cString = "text "; + + bool textIsNotEqual = text != cString; + + ASSERT_TRUE(textIsNotEqual); +} + TEST(ClangString, NullStringHasNoContent) { ClangString text(CXString{nullptr, 0}); diff --git a/tests/unit/unittest/clangtooltipinfo-test.cpp b/tests/unit/unittest/clangtooltipinfo-test.cpp index c796932092a..8e941cf6c79 100644 --- a/tests/unit/unittest/clangtooltipinfo-test.cpp +++ b/tests/unit/unittest/clangtooltipinfo-test.cpp @@ -52,9 +52,9 @@ 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()); \ + if (actual.memberName != expected.memberName) { \ + *result_listener << #memberName " is " + PrintToString(actual.memberName) \ + << " and not " + PrintToString(expected.memberName); \ return false; \ } @@ -130,9 +130,9 @@ TEST_F(ToolTipInfo, LocalVariablePointerToConstInt) TEST_F(ToolTipInfo, LocalParameterVariableConstRefCustomType) { ::ToolTipInfo expected(Utf8StringLiteral("const Foo &")); - expected.setQdocIdCandidates({Utf8StringLiteral("Foo")}); - expected.setQdocMark(Utf8StringLiteral("Foo")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("Foo")}; + expected.qdocMark = Utf8StringLiteral("Foo"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(12, 12); @@ -142,9 +142,9 @@ TEST_F(ToolTipInfo, LocalParameterVariableConstRefCustomType) TEST_F(ToolTipInfo, LocalNonParameterVariableConstRefCustomType) { ::ToolTipInfo expected(Utf8StringLiteral("const Foo")); - expected.setQdocIdCandidates({Utf8StringLiteral("Foo")}); - expected.setQdocMark(Utf8StringLiteral("Foo")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("Foo")}; + expected.qdocMark = Utf8StringLiteral("Foo"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(14, 5); @@ -162,7 +162,7 @@ TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_Qualifi { const ::ToolTipInfo actual = tooltip(21, 9); - ASSERT_THAT(actual.text(), Utf8StringLiteral("int Bar::mem()")); + ASSERT_THAT(actual.text, Utf8StringLiteral("int Bar::mem()")); } // ChangeLog: Show extra specifiers. For functions e.g.: virtual, inline, explicit, const, volatile @@ -170,22 +170,22 @@ TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(MemberFunctionCall_ExtraSp { const ::ToolTipInfo actual = tooltip(22, 9); - ASSERT_THAT(actual.text(), Utf8StringLiteral("virtual int Bar::virtualConstMem() const")); + 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"))); + 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()")); + ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("mem()")); } // TODO: Check what is really needed for qdoc before implementing this one. @@ -193,14 +193,14 @@ TEST_F(ToolTipInfo, DISABLED_MemberFunctionCall_qdocMark_extraSpecifiers) { const ::ToolTipInfo actual = tooltip(22, 9); - ASSERT_THAT(actual.qdocMark(), Utf8StringLiteral("virtualConstMem() const")); + ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("virtualConstMem() const")); } TEST_F(ToolTipInfo, MemberFunctionCall_qdocCategory) { const ::ToolTipInfo actual = tooltip(21, 9); - ASSERT_THAT(actual.qdocCategory(), ::ToolTipInfo::Function); + ASSERT_THAT(actual.qdocCategory, ::ToolTipInfo::Function); } // TODO: Show the template parameter type, too: "template<typename T>...)" @@ -208,43 +208,43 @@ 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)")); + 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"))); + 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)")); + ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("t(int)")); } TEST_F(ToolTipInfo, TemplateFunctionCall_qdocCategory) { const ::ToolTipInfo actual = tooltip(30, 5); - ASSERT_THAT(actual.qdocCategory(), ::ToolTipInfo::Function); + 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.")); + 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); + expected.qdocIdCandidates = {Utf8StringLiteral("EnumType")}; + expected.qdocMark = Utf8StringLiteral("EnumType"); + expected.qdocCategory = ::ToolTipInfo::Enum; const ::ToolTipInfo actual = tooltip(49, 12); @@ -254,9 +254,9 @@ TEST_F(ToolTipInfo, Enum) TEST_F(ToolTipInfo, Enumerator) { ::ToolTipInfo expected(Utf8StringLiteral("6")); - expected.setQdocIdCandidates({Utf8StringLiteral("Custom")}); - expected.setQdocMark(Utf8StringLiteral("EnumType")); - expected.setQdocCategory(::ToolTipInfo::Enum); + expected.qdocIdCandidates = {Utf8StringLiteral("Custom")}; + expected.qdocMark = Utf8StringLiteral("EnumType"); + expected.qdocCategory = ::ToolTipInfo::Enum; const ::ToolTipInfo actual = tooltip(49, 22); @@ -266,9 +266,9 @@ TEST_F(ToolTipInfo, Enumerator) TEST_F(ToolTipInfo, TemplateTypeFromParameter) { ::ToolTipInfo expected(Utf8StringLiteral("const Baz<int> &")); - expected.setQdocIdCandidates({Utf8StringLiteral("Baz")}); - expected.setQdocMark(Utf8StringLiteral("Baz")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("Baz")}; + expected.qdocMark = Utf8StringLiteral("Baz"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(55, 25); @@ -278,9 +278,9 @@ TEST_F(ToolTipInfo, TemplateTypeFromParameter) TEST_F(ToolTipInfo, TemplateTypeFromNonParameter) { ::ToolTipInfo expected(Utf8StringLiteral("Baz<int>")); - expected.setQdocIdCandidates({Utf8StringLiteral("Baz")}); - expected.setQdocMark(Utf8StringLiteral("Baz")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("Baz")}; + expected.qdocMark = Utf8StringLiteral("Baz"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(56, 19); @@ -291,9 +291,9 @@ TEST_F(ToolTipInfo, IncludeDirective) { ::ToolTipInfo expected( QDir::toNativeSeparators(Utf8StringLiteral(TESTDATA_DIR "/tooltipinfo.h"))); - expected.setQdocIdCandidates({Utf8StringLiteral("tooltipinfo.h")}); - expected.setQdocMark(Utf8StringLiteral("tooltipinfo.h")); - expected.setQdocCategory(::ToolTipInfo::Brief); + expected.qdocIdCandidates = {Utf8StringLiteral("tooltipinfo.h")}; + expected.qdocMark = Utf8StringLiteral("tooltipinfo.h"); + expected.qdocCategory = ::ToolTipInfo::Brief; const ::ToolTipInfo actual = tooltip(59, 11); @@ -304,22 +304,22 @@ TEST_F(ToolTipInfo, MacroUse_WithMacroFromSameFile) { const ::ToolTipInfo actual = tooltip(66, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("#define MACRO_FROM_MAINFILE(x) x + 3")); + 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")); + 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); + expected.qdocIdCandidates = {Utf8StringLiteral("MACRO_FROM_MAINFILE")}; + expected.qdocMark = Utf8StringLiteral("MACRO_FROM_MAINFILE"); + expected.qdocCategory = ::ToolTipInfo::Macro; const ::ToolTipInfo actual = tooltip(66, 5); @@ -329,9 +329,9 @@ TEST_F(ToolTipInfo, MacroUse_qdoc) TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveIsQualified) { ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); - expected.setQdocIdCandidates({Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}); - expected.setQdocMark(Utf8StringLiteral("Muu")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}; + expected.qdocMark = Utf8StringLiteral("Muu"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(77, 5); @@ -341,9 +341,9 @@ TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveIsQualified) TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveOfAliasIsResolvedAndQualified) { ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); - expected.setQdocIdCandidates({Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}); - expected.setQdocMark(Utf8StringLiteral("Muu")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}; + expected.qdocMark = Utf8StringLiteral("Muu"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(82, 5); @@ -353,9 +353,9 @@ TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDirectiveOfAliasIsResolvedAndQualif TEST_F(ToolTipInfo, TypeNameIntroducedByUsingDeclarationIsQualified) { ::ToolTipInfo expected(Utf8StringLiteral("N::Muu")); - expected.setQdocIdCandidates({Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}); - expected.setQdocMark(Utf8StringLiteral("Muu")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("N::Muu"), Utf8StringLiteral("Muu")}; + expected.qdocMark = Utf8StringLiteral("Muu"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(87, 5); @@ -366,36 +366,36 @@ TEST_F(ToolTipInfo, SizeForClassDefinition) { const ::ToolTipInfo actual = tooltip(92, 8); - ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("2")); + ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("2")); } TEST_F(ToolTipInfo, SizeForMemberField) { const ::ToolTipInfo actual = tooltip(95, 10); - ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("1")); + ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("1")); } TEST_F(ToolTipInfo, SizeForEnum) { const ::ToolTipInfo actual = tooltip(97, 12); - ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("4")); + ASSERT_THAT(actual.sizeInBytes, Utf8StringLiteral("4")); } TEST_F(ToolTipInfo, SizeForUnion) { const ::ToolTipInfo actual = tooltip(98, 7); - ASSERT_THAT(actual.sizeInBytes(), Utf8StringLiteral("1")); + 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); + expected.qdocIdCandidates = {Utf8StringLiteral("X")}; + expected.qdocMark = Utf8StringLiteral("X"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(106, 11); @@ -405,9 +405,9 @@ TEST_F(ToolTipInfo, Namespace) TEST_F(ToolTipInfo, NamespaceQualified) { ::ToolTipInfo expected(Utf8StringLiteral("X::Y")); - expected.setQdocIdCandidates({Utf8StringLiteral("X::Y"), Utf8StringLiteral("Y")}); - expected.setQdocMark(Utf8StringLiteral("Y")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("X::Y"), Utf8StringLiteral("Y")}; + expected.qdocMark = Utf8StringLiteral("Y"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(107, 11); @@ -418,9 +418,9 @@ TEST_F(ToolTipInfo, NamespaceQualified) TEST_F(ToolTipInfo, TypeName_ResolveTypeDef) { ::ToolTipInfo expected(Utf8StringLiteral("Ptr<Nuu>")); - expected.setQdocIdCandidates({Utf8StringLiteral("PtrFromTypeDef")}); - expected.setQdocMark(Utf8StringLiteral("PtrFromTypeDef")); - expected.setQdocCategory(::ToolTipInfo::Typedef); + expected.qdocIdCandidates = {Utf8StringLiteral("PtrFromTypeDef")}; + expected.qdocMark = Utf8StringLiteral("PtrFromTypeDef"); + expected.qdocCategory = ::ToolTipInfo::Typedef; const ::ToolTipInfo actual = tooltip(122, 5); @@ -431,9 +431,9 @@ TEST_F(ToolTipInfo, TypeName_ResolveTypeDef) TEST_F(ToolTipInfo, TypeName_ResolveAlias) { ::ToolTipInfo expected(Utf8StringLiteral("Ptr<Nuu>")); - expected.setQdocIdCandidates({Utf8StringLiteral("PtrFromTypeAlias")}); - expected.setQdocMark(Utf8StringLiteral("PtrFromTypeAlias")); - expected.setQdocCategory(::ToolTipInfo::Typedef); + expected.qdocIdCandidates = {Utf8StringLiteral("PtrFromTypeAlias")}; + expected.qdocMark = Utf8StringLiteral("PtrFromTypeAlias"); + expected.qdocCategory = ::ToolTipInfo::Typedef; const ::ToolTipInfo actual = tooltip(123, 5); @@ -447,15 +447,15 @@ TEST_F(ToolTipInfo, DISABLED_TypeName_ResolveTemplateTypeAlias) { const ::ToolTipInfo actual = tooltip(124, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("Ptr<Nuu>")); + 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); + expected.qdocIdCandidates = {Utf8StringLiteral("PtrFromTemplateTypeAlias")}; + expected.qdocMark = Utf8StringLiteral("PtrFromTemplateTypeAlias"); + expected.qdocCategory = ::ToolTipInfo::Typedef; const ::ToolTipInfo actual = tooltip(124, 5); @@ -465,9 +465,9 @@ TEST_F(ToolTipInfo, TypeName_ResolveTemplateTypeAlias_qdoc) TEST_F(ToolTipInfo, TemplateClassReference) { ::ToolTipInfo expected(Utf8StringLiteral("Zii<T>")); - expected.setQdocIdCandidates({Utf8StringLiteral("Zii")}); - expected.setQdocMark(Utf8StringLiteral("Zii")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("Zii")}; + expected.qdocMark = Utf8StringLiteral("Zii"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(134, 5); @@ -477,9 +477,9 @@ TEST_F(ToolTipInfo, TemplateClassReference) 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); + expected.qdocIdCandidates = {Utf8StringLiteral("U::Yii"), Utf8StringLiteral("Yii")}; + expected.qdocMark = Utf8StringLiteral("Yii"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(135, 5); @@ -489,9 +489,9 @@ TEST_F(ToolTipInfo, TemplateClassQualified) TEST_F(ToolTipInfo, ResolveNamespaceAliasForType) { ::ToolTipInfo expected(Utf8StringLiteral("A::X")); - expected.setQdocIdCandidates({Utf8StringLiteral("A::X"), Utf8StringLiteral("X")}); - expected.setQdocMark(Utf8StringLiteral("X")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("A::X"), Utf8StringLiteral("X")}; + expected.qdocMark = Utf8StringLiteral("X"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(144, 8); @@ -502,9 +502,9 @@ TEST_F(ToolTipInfo, ResolveNamespaceAliasForType) TEST_F(ToolTipInfo, ResolveNamespaceAlias) { ::ToolTipInfo expected(Utf8StringLiteral("A")); - expected.setQdocIdCandidates({Utf8StringLiteral("B")}); - expected.setQdocMark(Utf8StringLiteral("B")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); + expected.qdocIdCandidates = {Utf8StringLiteral("B")}; + expected.qdocMark = Utf8StringLiteral("B"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; const ::ToolTipInfo actual = tooltip(144, 5); @@ -514,12 +514,12 @@ TEST_F(ToolTipInfo, ResolveNamespaceAlias) TEST_F(ToolTipInfo, QualificationForTemplateClassInClassInNamespace) { ::ToolTipInfo expected(Utf8StringLiteral("N::Outer::Inner<int>")); - expected.setQdocIdCandidates({Utf8StringLiteral("N::Outer::Inner"), + expected.qdocIdCandidates = {Utf8StringLiteral("N::Outer::Inner"), Utf8StringLiteral("Outer::Inner"), - Utf8StringLiteral("Inner")}); - expected.setQdocMark(Utf8StringLiteral("Inner")); - expected.setQdocCategory(::ToolTipInfo::ClassOrNamespace); - expected.setSizeInBytes(Utf8StringLiteral("1")); + Utf8StringLiteral("Inner")}; + expected.qdocMark = Utf8StringLiteral("Inner"); + expected.qdocCategory = ::ToolTipInfo::ClassOrNamespace; + expected.sizeInBytes = Utf8StringLiteral("1"); const ::ToolTipInfo actual = tooltip(153, 16); @@ -529,9 +529,9 @@ TEST_F(ToolTipInfo, QualificationForTemplateClassInClassInNamespace) TEST_F(ToolTipInfo, Function) { ::ToolTipInfo expected(Utf8StringLiteral("void f()")); - expected.setQdocIdCandidates({Utf8StringLiteral("f")}); - expected.setQdocMark(Utf8StringLiteral("f()")); - expected.setQdocCategory(::ToolTipInfo::Function); + expected.qdocIdCandidates = {Utf8StringLiteral("f")}; + expected.qdocMark = Utf8StringLiteral("f()"); + expected.qdocCategory = ::ToolTipInfo::Function; const ::ToolTipInfo actual = tooltip(165, 5); @@ -542,22 +542,22 @@ TEST_F(ToolTipInfo, Function_QualifiedName) { const ::ToolTipInfo actual = tooltip(166, 8); - ASSERT_THAT(actual.text(), Utf8StringLiteral("void R::f()")); + 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"))); + 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)")); + ASSERT_THAT(actual.text, Utf8StringLiteral("void f(int param)")); } // TODO: Implement with CXPrintingPolicy @@ -565,28 +565,28 @@ TEST_F(ToolTipInfo, DISABLED_Function_HasDefaultArgument) { const ::ToolTipInfo actual = tooltip(168, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("void z(int = 1)")); + 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)")); + 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)")); + ASSERT_THAT(actual.qdocMark, Utf8StringLiteral("z(int)")); } TEST_F(ToolTipInfo, AutoTypeBuiltin) { const ::ToolTipInfo actual = tooltip(176, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("int")); + ASSERT_THAT(actual.text, Utf8StringLiteral("int")); } // TODO: Test for qdoc entries, too. @@ -594,7 +594,7 @@ TEST_F(ToolTipInfo, AutoTypeEnum) { const ::ToolTipInfo actual = tooltip(177, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("EnumType")); + ASSERT_THAT(actual.text, Utf8StringLiteral("EnumType")); } // TODO: Test for qdoc entries, too. @@ -602,7 +602,7 @@ TEST_F(ToolTipInfo, AutoTypeClassType) { const ::ToolTipInfo actual = tooltip(178, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("Bar")); + ASSERT_THAT(actual.text, Utf8StringLiteral("Bar")); } // TODO: Test for qdoc entries, too. @@ -611,28 +611,28 @@ TEST_F(ToolTipInfo, AutoTypeClassTemplateType) { const ::ToolTipInfo actual = tooltip(179, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("Zii<int>")); + ASSERT_THAT(actual.text, Utf8StringLiteral("Zii<int>")); } TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_DefaultConstructor)) { const ::ToolTipInfo actual = tooltip(193, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("inline constexpr Con::Con() noexcept")); + ASSERT_THAT(actual.text, Utf8StringLiteral("inline constexpr Con::Con() noexcept")); } TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_ExplicitDefaultConstructor)) { const ::ToolTipInfo actual = tooltip(194, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("ExplicitCon::ExplicitCon() noexcept = default")); + ASSERT_THAT(actual.text, Utf8StringLiteral("ExplicitCon::ExplicitCon() noexcept = default")); } TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_CustomConstructor)) { const ::ToolTipInfo actual = tooltip(195, 5); - ASSERT_THAT(actual.text(), Utf8StringLiteral("ExplicitCon::ExplicitCon(int m)")); + ASSERT_THAT(actual.text, Utf8StringLiteral("ExplicitCon::ExplicitCon(int m)")); } // Overloads are problematic for the help system since the data base has not @@ -647,9 +647,9 @@ TEST_F(ToolTipInfo, DISABLED_WITHOUT_PRETTYDECL_PATCH(Function_CustomConstructor TEST_F(ToolTipInfo, Function_ConstructorQDoc) { ::ToolTipInfo expected; - expected.setQdocIdCandidates({Utf8StringLiteral("Con")}); - expected.setQdocMark(Utf8StringLiteral("Con")); - expected.setQdocCategory(::ToolTipInfo::Unknown); + expected.qdocIdCandidates = {Utf8StringLiteral("Con")}; + expected.qdocMark = Utf8StringLiteral("Con"); + expected.qdocCategory = ::ToolTipInfo::Unknown; const ::ToolTipInfo actual = tooltip(193, 5); diff --git a/tests/unit/unittest/clientserverinprocess-test.cpp b/tests/unit/unittest/clientserverinprocess-test.cpp index b02c519dad3..1b0743c558d 100644 --- a/tests/unit/unittest/clientserverinprocess-test.cpp +++ b/tests/unit/unittest/clientserverinprocess-test.cpp @@ -227,7 +227,9 @@ TEST_F(ClientServerInProcess, UpdateVisibleTranslationUnitsMessage) TEST_F(ClientServerInProcess, SendDocumentAnnotationsChangedMessage) { - ClangBackEnd::TokenInfoContainer tokenInfo(1, 1, 1, ClangBackEnd::HighlightingType::Keyword); + ClangBackEnd::HighlightingTypes types; + types.mainHighlightingType = ClangBackEnd::HighlightingType::Keyword; + ClangBackEnd::TokenInfoContainer tokenInfo(1, 1, 1, types); ClangBackEnd::DiagnosticContainer diagnostic(Utf8StringLiteral("don't do that"), Utf8StringLiteral("warning"), {Utf8StringLiteral("-Wpadded"), Utf8StringLiteral("-Wno-padded")}, diff --git a/tests/unit/unittest/codecompleter-test.cpp b/tests/unit/unittest/codecompleter-test.cpp index 76802d7ca2f..c55a9a0514a 100644 --- a/tests/unit/unittest/codecompleter-test.cpp +++ b/tests/unit/unittest/codecompleter-test.cpp @@ -54,13 +54,13 @@ MATCHER_P2(IsCodeCompletion, text, completionKind, + PrintToString(text) + " and kind " + PrintToString(completionKind) ) { - if (arg.text() != text) { - *result_listener << "text is " + PrintToString(arg.text()) + " and not " + PrintToString(text); + 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); + if (arg.completionKind != completionKind) { + *result_listener << "kind is " + PrintToString(arg.completionKind) + " and not " + PrintToString(completionKind); return false; } @@ -82,116 +82,116 @@ protected: QString targetHeaderPath{includeDirectory.path() + QStringLiteral("/complete_target_header.h")}; ClangBackEnd::ProjectPartContainer projectPart{Utf8StringLiteral("projectPartId"), {includePath}}; ClangBackEnd::FileContainer mainFileContainer{Utf8StringLiteral(TESTDATA_DIR"/complete_completer_main.cpp"), - projectPart.projectPartId()}; + projectPart.projectPartId}; ClangBackEnd::ProjectParts projects; ClangBackEnd::UnsavedFiles unsavedFiles; ClangBackEnd::Documents documents{projects, unsavedFiles}; ClangBackEnd::Document document; QScopedPointer<ClangBackEnd::CodeCompleter> completer; - ClangBackEnd::FileContainer unsavedMainFileContainer{mainFileContainer.filePath(), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_completer_main_unsaved.cpp")), + ClangBackEnd::FileContainer unsavedMainFileContainer{mainFileContainer.filePath, + projectPart.projectPartId, + readFileContent("/complete_completer_main_unsaved.cpp"), true}; ClangBackEnd::FileContainer unsavedTargetHeaderFileContainer{targetHeaderPath, - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_target_header_unsaved.h")), + projectPart.projectPartId, + readFileContent("/complete_target_header_unsaved.h"), true}; ClangBackEnd::FileContainer arrowFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_arrow.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_arrow.cpp")), + projectPart.projectPartId, + readFileContent("/complete_arrow.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointer.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withDotArrowCorrectionForPointer.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerBeforeTyping{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withDotArrowCorrectionForPointer_beforeTyping.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerAfterTyping{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointer_afterTyping.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withDotArrowCorrectionForPointer_afterTyping.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerInitial{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointerInitial.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withDotArrowCorrectionForPointerInitial.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForPointerFileContainerUpdated{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForPointerUpdated.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withDotArrowCorrectionForPointerUpdated.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForObjectFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForObject.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForObject.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForObject.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForFloatFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForFloat.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForFloat.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForFloat.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForObjectWithArrowOperatortFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForObjectWithArrowOperator.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForDotDotFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForDotDot.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForDotDot.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForDotDot.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForArrowDotFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForArrowDot.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForArrowDot.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForArrowDot.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForOnlyDotFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForOnlyDot.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForOnlyDot.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForOnlyDot.cpp"), true }; ClangBackEnd::FileContainer noDotArrowCorrectionForColonColonFileContainer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withNoDotArrowCorrectionForColonColon.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withNoDotArrowCorrectionForColonColon.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withNoDotArrowCorrectionForColonColon.cpp"), true }; ClangBackEnd::FileContainer dotArrowCorrectionForForwardDeclaredClassPointer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withDotArrowCorrectionForForwardDeclaredClassPointer.cpp"), true }; ClangBackEnd::FileContainer globalCompletionAfterForwardDeclaredClassPointer{ Utf8StringLiteral(TESTDATA_DIR"/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp")), + projectPart.projectPartId, + readFileContent("/complete_withGlobalCompletionAfterForwardDeclaredClassPointer.cpp"), true }; ClangBackEnd::FileContainer smartPointerCompletion{ Utf8StringLiteral(TESTDATA_DIR"/complete_smartpointer.cpp"), - projectPart.projectPartId(), - readFileContent(QStringLiteral("/complete_smartpointer.cpp")), + projectPart.projectPartId, + readFileContent("/complete_smartpointer.cpp"), true }; }; @@ -394,8 +394,8 @@ TEST_F(CodeCompleterSlowTest, DotToArrowCompletionForPointerInOutdatedDocument) auto fileContainerBeforeTyping = dotArrowCorrectionForPointerFileContainerBeforeTyping; documents.create({fileContainerBeforeTyping}); unsavedFiles.createOrUpdate({fileContainerBeforeTyping}); - auto document = documents.document(fileContainerBeforeTyping.filePath(), - fileContainerBeforeTyping.projectPartId()); + auto document = documents.document(fileContainerBeforeTyping.filePath, + fileContainerBeforeTyping.projectPartId); document.parse(); unsavedFiles.createOrUpdate({dotArrowCorrectionForPointerFileContainerAfterTyping}); ClangBackEnd::CodeCompleter myCompleter(documents.document(dotArrowCorrectionForPointerFileContainerAfterTyping).translationUnit(), diff --git a/tests/unit/unittest/codecompletionsextractor-test.cpp b/tests/unit/unittest/codecompletionsextractor-test.cpp index 194459f1794..553392700fc 100644 --- a/tests/unit/unittest/codecompletionsextractor-test.cpp +++ b/tests/unit/unittest/codecompletionsextractor-test.cpp @@ -64,16 +64,16 @@ MATCHER_P3(HasCompletion, name, kind, availability, { ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); while (extractor.next()) { - if (extractor.currentCodeCompletion().text() == name) { - if (extractor.currentCodeCompletion().completionKind() == kind) { - if (extractor.currentCodeCompletion().availability() == availability) { + if (extractor.currentCodeCompletion().text == name) { + if (extractor.currentCodeCompletion().completionKind == kind) { + if (extractor.currentCodeCompletion().availability == availability) { return true; } else if (!extractor.peek(name)) { - *result_listener << "availability is " << PrintToString(extractor.currentCodeCompletion().availability()) << " and not " << PrintToString(availability); + *result_listener << "availability is " << PrintToString(extractor.currentCodeCompletion().availability) << " and not " << PrintToString(availability); return false; } } else if (!extractor.peek(name)) { - *result_listener << "kind is " << PrintToString(extractor.currentCodeCompletion().completionKind()) << " and not " << PrintToString(kind); + *result_listener << "kind is " << PrintToString(extractor.currentCodeCompletion().completionKind) << " and not " << PrintToString(kind); return false; } } @@ -88,11 +88,11 @@ MATCHER_P2(HasCompletionChunks, name, chunks, { ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); while (extractor.next()) { - if (extractor.currentCodeCompletion().text() == name) { - if (extractor.currentCodeCompletion().chunks() == chunks) { + if (extractor.currentCodeCompletion().text == name) { + if (extractor.currentCodeCompletion().chunks == chunks) { return true; } else if (!extractor.peek(name)) { - *result_listener << "chunks are " << PrintToString(arg.currentCodeCompletion().chunks()) << " and not " << PrintToString(chunks); + *result_listener << "chunks are " << PrintToString(arg.currentCodeCompletion().chunks) << " and not " << PrintToString(chunks); return false; } } @@ -107,11 +107,11 @@ MATCHER_P2(HasBriefComment, name, briefComment, { ::CodeCompletionsExtractor &extractor = const_cast<::CodeCompletionsExtractor&>(arg); while (extractor.next()) { - if (extractor.currentCodeCompletion().text() == name) { - if (extractor.currentCodeCompletion().briefComment() == briefComment) { + if (extractor.currentCodeCompletion().text == name) { + if (extractor.currentCodeCompletion().briefComment == briefComment) { return true; } else if (!extractor.peek(name)) { - *result_listener << "briefComment is " << PrintToString(arg.currentCodeCompletion().briefComment()) << " and not " << PrintToString(briefComment); + *result_listener << "briefComment is " << PrintToString(arg.currentCodeCompletion().briefComment) << " and not " << PrintToString(briefComment); return false; } } @@ -417,7 +417,7 @@ TEST_F(CodeCompletionsExtractorSlowTest, Method) ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("Method"), CodeCompletion::FunctionCompletionKind, CodeCompletion::Available)); - ASSERT_FALSE(extractor.currentCodeCompletion().hasParameters()); + ASSERT_FALSE(extractor.currentCodeCompletion().hasParameters); } TEST_F(CodeCompletionsExtractorSlowTest, MethodWithParameters) @@ -429,7 +429,7 @@ TEST_F(CodeCompletionsExtractorSlowTest, MethodWithParameters) ASSERT_THAT(extractor, HasCompletion(Utf8StringLiteral("MethodWithParameters"), CodeCompletion::FunctionCompletionKind, CodeCompletion::Available)); - ASSERT_TRUE(extractor.currentCodeCompletion().hasParameters()); + ASSERT_TRUE(extractor.currentCodeCompletion().hasParameters); } TEST_F(CodeCompletionsExtractorSlowTest, Slot) diff --git a/tests/unit/unittest/conditionally-disabled-tests.h b/tests/unit/unittest/conditionally-disabled-tests.h index 3cac7591352..0b6f2799750 100644 --- a/tests/unit/unittest/conditionally-disabled-tests.h +++ b/tests/unit/unittest/conditionally-disabled-tests.h @@ -34,6 +34,12 @@ # define DISABLED_ON_WINDOWS(x) x #endif +#ifndef Q_OS_WIN +# define DISABLED_ON_NON_WINDOWS(x) DISABLED_##x +#else +# define DISABLED_ON_NON_WINDOWS(x) x +#endif + #ifdef IS_PRETTY_DECL_SUPPORTED # define DISABLED_WITHOUT_PRETTYDECL_PATCH(x) x #else diff --git a/tests/unit/unittest/cursor-test.cpp b/tests/unit/unittest/cursor-test.cpp index e229c6522a1..4aa2cf0bb9b 100644 --- a/tests/unit/unittest/cursor-test.cpp +++ b/tests/unit/unittest/cursor-test.cpp @@ -803,6 +803,96 @@ TEST_F(Cursor, ConstReferenceIsNotOutputArgument) ASSERT_FALSE(argument.isOutputArgument()); } +TEST_F(Cursor, ResultType) +{ + auto methodCursor = translationUnit.cursorAt(31, 18); + + Utf8String resultType = methodCursor.type().resultType().spelling(); + + ASSERT_THAT(resultType, Utf8String("bool", 4)); +} + +TEST_F(Cursor, PrivateMethodAccessSpecifier) +{ + auto methodCursor = translationUnit.cursorAt(16, 17); + + auto accessSpecifier = methodCursor.accessSpecifier(); + + ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Private); +} + +TEST_F(Cursor, PublicMethodAccessSpecifier) +{ + auto methodCursor = translationUnit.cursorAt(79, 25); + + auto accessSpecifier = methodCursor.accessSpecifier(); + + ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Public); +} + +TEST_F(Cursor, ProtectedMethodAccessSpecifier) +{ + auto methodCursor = translationUnit.cursorAt(131, 22); + + auto accessSpecifier = methodCursor.accessSpecifier(); + + ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Protected); +} + +TEST_F(Cursor, PrivateFieldAccessSpecifier) +{ + auto fieldCursor = translationUnit.cursorAt(21, 12); + + auto accessSpecifier = fieldCursor.accessSpecifier(); + + ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Private); +} + +TEST_F(Cursor, InvalidAccessSpecifier) +{ + auto localVarCursor = translationUnit.cursorAt(62, 9); + + auto accessSpecifier = localVarCursor.accessSpecifier(); + + ASSERT_THAT(accessSpecifier, ClangBackEnd::AccessSpecifier::Invalid); +} + +TEST_F(Cursor, NoStorageClass) +{ + auto localVarCursor = translationUnit.cursorAt(62, 9); + + auto storageClass = localVarCursor.storageClass(); + + ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::None); +} + +TEST_F(Cursor, ExternVarStorageClass) +{ + auto externalVarCursor = translationUnit.cursorAt(133, 12); + + auto storageClass = externalVarCursor.storageClass(); + + ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Extern); +} + +TEST_F(Cursor, StaticMethodStorageClass) +{ + auto methodCursor = translationUnit.cursorAt(135, 13); + + auto storageClass = methodCursor.storageClass(); + + ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Static); +} + +TEST_F(Cursor, InvalidStorageClass) +{ + auto functionTemplateCursor = translationUnit.cursorAt(137, 28); + + auto storageClass = functionTemplateCursor.storageClass(); + + ASSERT_THAT(storageClass, ClangBackEnd::StorageClass::Invalid); +} + Data *Cursor::d; void Cursor::SetUpTestCase() diff --git a/tests/unit/unittest/data/cursor.cpp b/tests/unit/unittest/data/cursor.cpp index a492867dd6b..218e6852f52 100644 --- a/tests/unit/unittest/data/cursor.cpp +++ b/tests/unit/unittest/data/cursor.cpp @@ -127,3 +127,11 @@ void PointerToConst(const int *); void Pointer(int *); void ConstantPointer(int *const); void ConstIntegerValue(const int); + +void NonFinalStruct::ProtectedMethodAccessSpecifier() {} + +extern int ExternVarStorageClass; + +static void StaticMethodStorageClass() {} + +template<class T> const T &InvalidStorageClass(const T &type) { return type; } diff --git a/tests/unit/unittest/data/cursor.h b/tests/unit/unittest/data/cursor.h index 3e9e9a2bfb9..7db9be6e97b 100644 --- a/tests/unit/unittest/data/cursor.h +++ b/tests/unit/unittest/data/cursor.h @@ -39,4 +39,6 @@ struct NonFinalStruct { virtual void FinalVirtualMethod() final; void function(); +protected: + void ProtectedMethodAccessSpecifier(); }; diff --git a/tests/unit/unittest/data/filestatuscache_header.cpp b/tests/unit/unittest/data/filestatuscache_header.cpp new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/unit/unittest/data/filestatuscache_header.cpp diff --git a/tests/unit/unittest/data/filestatuscache_header.h b/tests/unit/unittest/data/filestatuscache_header.h new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/unit/unittest/data/filestatuscache_header.h @@ -0,0 +1 @@ + diff --git a/tests/unit/unittest/data/highlightingmarks.cpp b/tests/unit/unittest/data/highlightingmarks.cpp index afe4d8a0f1e..858f0bbf2ab 100644 --- a/tests/unit/unittest/data/highlightingmarks.cpp +++ b/tests/unit/unittest/data/highlightingmarks.cpp @@ -331,7 +331,7 @@ void f14() using IntegerAlias = int; using SecondIntegerAlias = IntegerAlias; -using IntegerTypedef = int; +typedef int IntegerTypedef; using Function = void (*)(); @@ -589,4 +589,87 @@ class WithVirtualFunctionDefined { virtual void VirtualFunctionDefinition() {}; }; +namespace NFoo { namespace NBar { namespace NTest { class NamespaceTypeSpelling; } } } + Undeclared u; + +#include "../../../../share/qtcreator/cplusplus/wrappedQtHeaders/QtCore/qobjectdefs.h" + +class Property { + Q_PROPERTY(const volatile unsigned long long * prop READ getProp WRITE setProp NOTIFY propChanged) + Q_PROPERTY(const QString str READ getStr) +}; + +struct X { + void operator*(int) {} +}; + +void operator*(X, float) {} + +void CallSite() { + X x; + int y = 10; + float z = 10; + x * y; + x * z; +} + +struct Dummy { + Dummy operator<<=(int key); + Dummy operator()(int a); + int& operator[] (unsigned index); + void* operator new(unsigned size); + void operator delete(void* ptr); + void* operator new[](unsigned size); + void operator delete[](void* ptr); +}; + +void TryOverloadedOperators(Dummy object) +{ + object <<= 3; + + Dummy stacked; + stacked(4); + stacked[1]; + int *i = new int; + Dummy* use_new = new Dummy(); + delete use_new; + Dummy* many = new Dummy[10]; + delete [] many; +} + +enum { + Test = 0 +}; + +namespace { +class B { + struct { + int a; + }; +}; +} + +struct Dummy2 { + Dummy2 operator()(); + int operator*(); + Dummy2 operator=(int foo); +}; + +void TryOverloadedOperators2(Dummy object) +{ + Dummy2 dummy2; + dummy2(); + *dummy2; + dummy2 = 3; +} + +int OperatorTest() { + return 1 < 2 ? 20 : 30; +} + +int signalSlotTest() { + SIGNAL(something(QString)); + SLOT(something(QString)); + SIGNAL(something(QString (*func1)(QString))); +} diff --git a/tests/unit/unittest/data/includecollector_indirect_external.h b/tests/unit/unittest/data/includecollector_indirect_external.h index 6f70f09beec..bfd11c5d74c 100644 --- a/tests/unit/unittest/data/includecollector_indirect_external.h +++ b/tests/unit/unittest/data/includecollector_indirect_external.h @@ -1 +1,3 @@ #pragma once + +#include "includecollector_indirect_external2.h" diff --git a/tests/unit/unittest/data/includecollector_indirect_external2.h b/tests/unit/unittest/data/includecollector_indirect_external2.h new file mode 100644 index 00000000000..3f59c932d39 --- /dev/null +++ b/tests/unit/unittest/data/includecollector_indirect_external2.h @@ -0,0 +1,2 @@ +#pragma once + diff --git a/tests/unit/unittest/data/symbolindexer_header1.h b/tests/unit/unittest/data/symbolindexer_header1.h new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/unit/unittest/data/symbolindexer_header1.h diff --git a/tests/unit/unittest/data/symbolindexer_header2.h b/tests/unit/unittest/data/symbolindexer_header2.h new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/unit/unittest/data/symbolindexer_header2.h diff --git a/tests/unit/unittest/data/symbolindexer_main1.cpp b/tests/unit/unittest/data/symbolindexer_main1.cpp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/unit/unittest/data/symbolindexer_main1.cpp @@ -0,0 +1 @@ + diff --git a/tests/unit/unittest/data/symbolindexer_main2.cpp b/tests/unit/unittest/data/symbolindexer_main2.cpp new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/tests/unit/unittest/data/symbolindexer_main2.cpp diff --git a/tests/unit/unittest/data/symbolindexer_pathChanged.cpp b/tests/unit/unittest/data/symbolindexer_pathChanged.cpp new file mode 100644 index 00000000000..8b137891791 --- /dev/null +++ b/tests/unit/unittest/data/symbolindexer_pathChanged.cpp @@ -0,0 +1 @@ + diff --git a/tests/unit/unittest/data/symbolscollector_defines.h b/tests/unit/unittest/data/symbolscollector_defines.h new file mode 100644 index 00000000000..6cb2ee91ef9 --- /dev/null +++ b/tests/unit/unittest/data/symbolscollector_defines.h @@ -0,0 +1,42 @@ +#ifndef SYMBOLSCOLLECTOR_DEFINES_H +#define SYMBOLSCOLLECTOR_DEFINES_H + +#define IF_NOT_DEFINE 1 + +#ifndef IF_NOT_DEFINE +#endif + +#ifndef IF_NOT_DEFINE +#endif + +#ifndef COMPILER_ARGUMENT +#endif + +#define IF_DEFINE 1 + +#ifdef IF_DEFINE +#endif + +#define DEFINED 1 + +#if defined(DEFINED) +#endif + +#define MACRO_EXPANSION int + +void foo(MACRO_EXPANSION); + +#ifndef __clang__ +#endif + +#define UN_DEFINE + +#undef UN_DEFINE + +#define CLASS_EXPORT + +struct CLASS_EXPORT Foo +{ +}; + +#endif // SYMBOLSCOLLECTOR_DEFINES_H diff --git a/tests/unit/unittest/data/symbolscollector_header3.h b/tests/unit/unittest/data/symbolscollector_header3.h new file mode 100644 index 00000000000..bacb59d24a7 --- /dev/null +++ b/tests/unit/unittest/data/symbolscollector_header3.h @@ -0,0 +1,3 @@ +#pragma once + +#include "symbolscollector_header2.h" diff --git a/tests/unit/unittest/data/symbolscollector_main2.cpp b/tests/unit/unittest/data/symbolscollector_main2.cpp new file mode 100644 index 00000000000..71ea20e2b65 --- /dev/null +++ b/tests/unit/unittest/data/symbolscollector_main2.cpp @@ -0,0 +1,5 @@ +#include "symbolscollector_header1.h" +#include "symbolscollector_header3.h" + +void function(); + diff --git a/tests/unit/unittest/data/symbolscollector_symbolkind.cpp b/tests/unit/unittest/data/symbolscollector_symbolkind.cpp new file mode 100644 index 00000000000..e8f9bae5305 --- /dev/null +++ b/tests/unit/unittest/data/symbolscollector_symbolkind.cpp @@ -0,0 +1,13 @@ +class Class {}; +struct Struct {}; +enum Enumeration {}; +enum ScopedEnumeration {}; +union Union {}; + +#ifdef _MSC_VER +__interface MsvcInterface {}; +#endif + +void Function() {} + +int Variable; diff --git a/tests/unit/unittest/diagnosticcontainer-matcher.h b/tests/unit/unittest/diagnosticcontainer-matcher.h index f04e9e374bd..7b8032936fc 100644 --- a/tests/unit/unittest/diagnosticcontainer-matcher.h +++ b/tests/unit/unittest/diagnosticcontainer-matcher.h @@ -31,21 +31,21 @@ using ::testing::PrintToString; MATCHER_P(IsDiagnosticContainer, diagnosticContainer, "") { - if (arg.text() != diagnosticContainer.text()) { - *result_listener << "text is " + PrintToString(arg.text()) - + " and not " + PrintToString(diagnosticContainer.text()); + if (arg.text != diagnosticContainer.text) { + *result_listener << "text is " + PrintToString(arg.text) + + " and not " + PrintToString(diagnosticContainer.text); return false; } - if (arg.location() != diagnosticContainer.location()) { - *result_listener << "location is " + PrintToString(arg.location()) - + " and not " + PrintToString(diagnosticContainer.location()); + if (arg.location != diagnosticContainer.location) { + *result_listener << "location is " + PrintToString(arg.location) + + " and not " + PrintToString(diagnosticContainer.location); return false; } - if (arg.children() != diagnosticContainer.children()) { - *result_listener << "children are " + PrintToString(arg.children()) - + " and not " + PrintToString(diagnosticContainer.children()); + if (arg.children != diagnosticContainer.children) { + *result_listener << "children are " + PrintToString(arg.children) + + " and not " + PrintToString(diagnosticContainer.children); return false; } diff --git a/tests/unit/unittest/dynamicastmatcherdiagnosticcontainer-matcher.h b/tests/unit/unittest/dynamicastmatcherdiagnosticcontainer-matcher.h index 9a58f3b59ff..1df67d04bd2 100644 --- a/tests/unit/unittest/dynamicastmatcherdiagnosticcontainer-matcher.h +++ b/tests/unit/unittest/dynamicastmatcherdiagnosticcontainer-matcher.h @@ -41,19 +41,19 @@ MATCHER_P5(HasDiagnosticMessage, errorTypeText, startLine, startColumn, endLine, + ")}" ) { - if (!arg.empty() && arg.front().messages().empty()) { + if (!arg.empty() && arg.front().messages.empty()) { *result_listener << "no messages"; return false; } - auto message = arg.front().messages().front(); - auto sourceRange = message.sourceRange(); + auto message = arg.front().messages.front(); + auto sourceRange = message.sourceRange; return message.errorTypeText() == errorTypeText - && sourceRange.start().line() == uint(startLine) - && sourceRange.start().column() == uint(startColumn) - && sourceRange.end().line() == uint(endLine) - && sourceRange.end().column() == uint(endColumn); + && sourceRange.start.line == uint(startLine) + && sourceRange.start.column == uint(startColumn) + && sourceRange.end.line == uint(endLine) + && sourceRange.end.column == uint(endColumn); } MATCHER_P5(HasDiagnosticContext, contextTypeText, startLine, startColumn, endLine, endColumn, @@ -66,19 +66,19 @@ MATCHER_P5(HasDiagnosticContext, contextTypeText, startLine, startColumn, endLin + ")}" ) { - if (!arg.empty() && arg.front().messages().empty()) { + if (!arg.empty() && arg.front().messages.empty()) { *result_listener << "no context"; return false; } - auto context = arg.front().contexts().front(); - auto sourceRange = context.sourceRange(); + auto context = arg.front().contexts.front(); + auto sourceRange = context.sourceRange; return context.contextTypeText() == contextTypeText - && sourceRange.start().line() == uint(startLine) - && sourceRange.start().column() == uint(startColumn) - && sourceRange.end().line() == uint(endLine) - && sourceRange.end().column() == uint(endColumn); + && sourceRange.start.line == uint(startLine) + && sourceRange.start.column == uint(startColumn) + && sourceRange.end.line == uint(endLine) + && sourceRange.end.column == uint(endColumn); } } diff --git a/tests/unit/unittest/filepathcache-test.cpp b/tests/unit/unittest/filepathcache-test.cpp index a9cc33ba339..282654ad7b1 100644 --- a/tests/unit/unittest/filepathcache-test.cpp +++ b/tests/unit/unittest/filepathcache-test.cpp @@ -68,11 +68,11 @@ TEST_F(FilePathCache, DirectoryIdOfFilePathIdWithOutAnyEntry) ASSERT_THAT(filePathId.directoryId, 5); } -TEST_F(FilePathCache, FileNameIdOfFilePathIdWithOutAnyEntry) +TEST_F(FilePathCache, FilePathIdOfFilePathIdWithOutAnyEntry) { auto filePathId = cache.filePathId(FilePathView("/path/to/file.cpp")); - ASSERT_THAT(filePathId.fileNameId, 42); + ASSERT_THAT(filePathId.filePathId, 42); } TEST_F(FilePathCache, IfEntryExistsDontCallInStrorage) @@ -95,22 +95,22 @@ TEST_F(FilePathCache, IfDirectoryEntryExistsDontCallFetchDirectoryIdButStillCal cache.filePathId(FilePathView("/path/to/file.cpp")); } -TEST_F(FilePathCache, GetFileNameIdWithCachedValue) +TEST_F(FilePathCache, GetFilePathIdWithCachedValue) { cache.filePathId(FilePathView("/path/to/file.cpp")); auto filePathId = cache.filePathId(FilePathView("/path/to/file.cpp")); - ASSERT_THAT(filePathId.fileNameId, 42); + ASSERT_THAT(filePathId.filePathId, 42); } -TEST_F(FilePathCache, GetFileNameIdWithDirectoryIdCached) +TEST_F(FilePathCache, GetFilePathIdWithDirectoryIdCached) { cache.filePathId(FilePathView("/path/to/file.cpp")); auto filePathId = cache.filePathId(FilePathView("/path/to/file2.cpp")); - ASSERT_THAT(filePathId.fileNameId, 63); + ASSERT_THAT(filePathId.filePathId, 63); } TEST_F(FilePathCache, GetDirectyIdWithCachedValue) @@ -156,14 +156,36 @@ TEST_F(FilePathCache, GetAFilePathWithCachedFilePathId) ASSERT_THAT(filePath, Eq(FilePathView{"/path/to/file.cpp"})); } +TEST_F(FilePathCache, FileNamesAreUniqueForEveryDirectory) +{ + FilePathId filePathId = cache.filePathId(FilePathView("/path/to/file.cpp")); + + FilePathId filePath2Id = cache.filePathId(FilePathView("/path2/to/file.cpp")); + + ASSERT_THAT(filePath2Id.filePathId, Ne(filePathId.filePathId)); +} + +TEST_F(FilePathCache, DuplicateFilePathsAreEqual) +{ + FilePathId filePath1Id = cache.filePathId(FilePathView("/path/to/file.cpp")); + + FilePathId filePath2Id = cache.filePathId(FilePathView("/path/to/file.cpp")); + + ASSERT_THAT(filePath2Id, Eq(filePath1Id)); +} + void FilePathCache::SetUp() { ON_CALL(mockStorage, fetchDirectoryId(Eq("/path/to"))) .WillByDefault(Return(5)); + ON_CALL(mockStorage, fetchDirectoryId(Eq("/path2/to"))) + .WillByDefault(Return(6)); ON_CALL(mockStorage, fetchSourceId(5, Eq("file.cpp"))) .WillByDefault(Return(42)); ON_CALL(mockStorage, fetchSourceId(5, Eq("file2.cpp"))) .WillByDefault(Return(63)); + ON_CALL(mockStorage, fetchSourceId(6, Eq("file.cpp"))) + .WillByDefault(Return(72)); ON_CALL(mockStorage, fetchDirectoryPath(5)) .WillByDefault(Return(Utils::PathString("/path/to"))); ON_CALL(mockStorage, fetchSourceName(42)) diff --git a/tests/unit/unittest/filepathstorage-test.cpp b/tests/unit/unittest/filepathstorage-test.cpp index 11711583ed2..2692f9f79d0 100644 --- a/tests/unit/unittest/filepathstorage-test.cpp +++ b/tests/unit/unittest/filepathstorage-test.cpp @@ -35,9 +35,7 @@ namespace { -using StatementFactory = ClangBackEnd::FilePathStorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>, - MockSqliteReadStatement, - MockSqliteWriteStatement>; +using StatementFactory = ClangBackEnd::FilePathStorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>>; using Storage = ClangBackEnd::FilePathStorage<StatementFactory>; using ClangBackEnd::Sources::Directory; using ClangBackEnd::Sources::Source; @@ -48,8 +46,7 @@ protected: void SetUp(); protected: - NiceMock<MockMutex> mockMutex; - NiceMock<MockSqliteDatabase> mockDatabase{mockMutex}; + NiceMock<MockSqliteDatabase> mockDatabase; StatementFactory factory{mockDatabase}; MockSqliteReadStatement &selectDirectoryIdFromDirectoriesByDirectoryPath = factory.selectDirectoryIdFromDirectoriesByDirectoryPath; MockSqliteReadStatement &selectSourceIdFromSourcesByDirectoryIdAndSourceName = factory.selectSourceIdFromSourcesByDirectoryIdAndSourceName; @@ -134,14 +131,14 @@ TEST_F(FilePathStorage, FetchSourceIdForPathAndDirectoryId) TEST_F(FilePathStorage, CallWriteForWriteDirectory) { - EXPECT_CALL(insertIntoDirectories, write(Eq("/some/not/known/path"))); + EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/some/not/known/path"))); storage.writeDirectoryId("/some/not/known/path"); } TEST_F(FilePathStorage, CallWriteForWriteSource) { - EXPECT_CALL(insertIntoSources, write(5, Eq("unknownfile.h"))); + EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("unknownfile.h"))); storage.writeSourceId(5, "unknownfile.h"); } @@ -178,10 +175,10 @@ TEST_F(FilePathStorage, CallSelectForFetchingDirectoryIdForKnownPath) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, valueReturnInt32(Eq("/path/to"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchDirectoryId("/path/to"); } @@ -190,24 +187,24 @@ TEST_F(FilePathStorage, CallSelectForFetchingSourceIdForKnownPath) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, valueReturnInt32(5, Eq("file.h"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchSourceId(5, "file.h"); } TEST_F(FilePathStorage, CallNotWriteForFetchingDirectoryIdForKnownPath) { - EXPECT_CALL(insertIntoDirectories, write(_)).Times(0); + EXPECT_CALL(insertIntoDirectories, write(An<Utils::SmallStringView>())).Times(0); storage.fetchDirectoryId("/path/to"); } TEST_F(FilePathStorage, CallNotWriteForFetchingSoureIdForKnownEntry) { - EXPECT_CALL(insertIntoSources, write(_, _)).Times(0); + EXPECT_CALL(insertIntoSources, write(An<uint>(), An<Utils::SmallStringView>())).Times(0); storage.fetchSourceId(5, "file.h"); } @@ -216,11 +213,11 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdForUnknownPath) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, valueReturnInt32(Eq("/some/not/known/path"))); - EXPECT_CALL(insertIntoDirectories, write(Eq("/some/not/known/path"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/some/not/known/path"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchDirectoryId("/some/not/known/path"); } @@ -229,50 +226,115 @@ TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceIdForUnknownEntry) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, valueReturnInt32(5, Eq("unknownfile.h"))); - EXPECT_CALL(insertIntoSources, write(5, Eq("unknownfile.h"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("unknownfile.h"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchSourceId(5, "unknownfile.h"); } -TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheDatabaseIsBusyBecauseTheTableAlreadyChanged) +TEST_F(FilePathStorage, RestartFetchDirectoryIDIfTheDatabaseIsBusyInBeginBecauseTheTableAlreadyChanged) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(mockDatabase, rollback()).Times(0); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, valueReturnInt32(Eq("/other/unknow/path"))); - EXPECT_CALL(insertIntoDirectories, write(Eq("/other/unknow/path"))) + EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path"))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchDirectoryId("/other/unknow/path"); +} + +TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheDatabaseIsBusyInWriteBecauseTheTableAlreadyChanged) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, + valueReturnInt32(Eq("/other/unknow/path"))); + EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path"))) .WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); - EXPECT_CALL(mockDatabase, execute(Eq("ROLLBACK"))); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, + valueReturnInt32(Eq("/other/unknow/path"))); + EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path"))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchDirectoryId("/other/unknow/path"); +} + +TEST_F(FilePathStorage, CallSelectAndWriteForFetchingDirectoryIdTwoTimesIfTheIndexIsConstraintBecauseTheEntryExistsAlready) +{ + InSequence s; + + EXPECT_CALL(mockDatabase,deferredBegin()); EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, valueReturnInt32(Eq("/other/unknow/path"))); - EXPECT_CALL(insertIntoDirectories, write(Eq("/other/unknow/path"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(insertIntoDirectories, write(TypedEq<Utils::SmallStringView>("/other/unknow/path"))) + .WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy"))); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase,deferredBegin()); + EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, + valueReturnInt32(Eq("/other/unknow/path"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchDirectoryId("/other/unknow/path"); } +TEST_F(FilePathStorage, RestartFetchSourceIdIfTheDatabaseIsBusyInBeginBecauseTheTableAlreadyChanged) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(mockDatabase, rollback()).Times(0); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, + valueReturnInt32(5, Eq("otherunknownfile.h"))); + EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h"))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchSourceId(5, "otherunknownfile.h"); +} -TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheDatabaseIsBusyBecauseTheTableAlreadyChanged) +TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheDatabaseIsBusyInWriteBecauseTheTableAlreadyChanged) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, valueReturnInt32(5, Eq("otherunknownfile.h"))); - EXPECT_CALL(insertIntoSources, write(5, Eq("otherunknownfile.h"))) + EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h"))) .WillOnce(Throw(Sqlite::StatementIsBusy("busy")));; - EXPECT_CALL(mockDatabase, execute(Eq("ROLLBACK"))); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, + valueReturnInt32(5, Eq("otherunknownfile.h"))); + EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h"))); + EXPECT_CALL(mockDatabase, commit()); + + storage.fetchSourceId(5, "otherunknownfile.h"); +} + +TEST_F(FilePathStorage, CallSelectAndWriteForFetchingSourceTwoTimesIfTheIndexIsConstraintBecauseTheEntryExistsAlready) +{ + InSequence s; + + EXPECT_CALL(mockDatabase,deferredBegin()); + EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, + valueReturnInt32(5, Eq("otherunknownfile.h"))); + EXPECT_CALL(insertIntoSources, write(5, TypedEq<Utils::SmallStringView>("otherunknownfile.h"))) + .WillOnce(Throw(Sqlite::ConstraintPreventsModification("busy")));; + EXPECT_CALL(mockDatabase, rollback()); + EXPECT_CALL(mockDatabase,deferredBegin()); EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, valueReturnInt32(5, Eq("otherunknownfile.h"))); - EXPECT_CALL(insertIntoSources, write(5, Eq("otherunknownfile.h"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchSourceId(5, "otherunknownfile.h"); } @@ -295,27 +357,27 @@ TEST_F(FilePathStorage, SelectAllSources) TEST_F(FilePathStorage, CallSelectAllDirectories) { - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectAllDirectories, valuesReturnStdVectorDirectory(256)); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchAllDirectories(); } TEST_F(FilePathStorage, CallSelectAllSources) { - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectAllSources, valuesReturnStdVectorSource(8192)); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchAllSources(); } TEST_F(FilePathStorage, CallValueForFetchDirectoryPathForId) { - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectDirectoryPathFromDirectoriesByDirectoryId, valueReturnPathString(5)); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchDirectoryPath(5); } @@ -334,9 +396,9 @@ TEST_F(FilePathStorage, ThrowAsFetchingDirectoryPathForNonExistingId) TEST_F(FilePathStorage, CallValueForFetchSoureNameForId) { - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); + EXPECT_CALL(mockDatabase, deferredBegin()); EXPECT_CALL(selectSourceNameFromSourcesBySourceId, valueReturnSmallString(42)); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); + EXPECT_CALL(mockDatabase, commit()); storage.fetchSourceName(42); } @@ -353,6 +415,74 @@ TEST_F(FilePathStorage, ThrowAsFetchingSourceNameForNonExistingId) ASSERT_THROW(storage.fetchSourceName(12), ClangBackEnd::SourceNameIdDoesNotExists); } +TEST_F(FilePathStorage, RestartFetchSourceNameIfTheDatabaseIsBusyInBegin) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(mockDatabase, rollback()).Times(0); + EXPECT_CALL(mockDatabase, unlock()); + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectSourceNameFromSourcesBySourceId, valueReturnSmallString(42)); + EXPECT_CALL(mockDatabase, commit()); + EXPECT_CALL(mockDatabase, unlock()); + + storage.fetchSourceName(42); +} + +TEST_F(FilePathStorage, RestartFetchDirectoryPathIfTheDatabaseIsBusyInBegin) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(mockDatabase, rollback()).Times(0); + EXPECT_CALL(mockDatabase, unlock()); + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectDirectoryPathFromDirectoriesByDirectoryId, valueReturnPathString(5)); + EXPECT_CALL(mockDatabase, commit()); + EXPECT_CALL(mockDatabase, unlock()); + + storage.fetchDirectoryPath(5); +} + +TEST_F(FilePathStorage, RestartFetchAllDirectoriesIfBeginIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(mockDatabase, rollback()).Times(0); + EXPECT_CALL(mockDatabase, unlock()); + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectAllDirectories, valuesReturnStdVectorDirectory(256)); + EXPECT_CALL(mockDatabase, commit()); + EXPECT_CALL(mockDatabase, unlock()); + + storage.fetchAllDirectories(); +} + +TEST_F(FilePathStorage, RestartFetchAllSourcesIfBeginIsBusy) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(mockDatabase, rollback()).Times(0); + EXPECT_CALL(mockDatabase, unlock()); + EXPECT_CALL(mockDatabase, lock()); + EXPECT_CALL(mockDatabase, deferredBegin()); + EXPECT_CALL(selectAllSources, valuesReturnStdVectorSource(8192)); + EXPECT_CALL(mockDatabase, commit()); + EXPECT_CALL(mockDatabase, unlock()); + + storage.fetchAllSources(); +} + void FilePathStorage::SetUp() { ON_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, @@ -388,14 +518,13 @@ void FilePathStorage::SetUp() valueReturnSmallString(42)) .WillByDefault(Return(Utils::optional<Utils::SmallString>("file.cpp"))); - EXPECT_CALL(selectDirectoryIdFromDirectoriesByDirectoryPath, valueReturnInt32(_)) .Times(AnyNumber()); EXPECT_CALL(selectSourceIdFromSourcesByDirectoryIdAndSourceName, valueReturnInt32(_, _)) .Times(AnyNumber()); - EXPECT_CALL(insertIntoDirectories,write(_)) + EXPECT_CALL(insertIntoDirectories, write(An<Utils::SmallStringView>())) .Times(AnyNumber()); - EXPECT_CALL(insertIntoSources,write(_, _)) + EXPECT_CALL(insertIntoSources, write(An<uint>(), A<Utils::SmallStringView>())) .Times(AnyNumber()); EXPECT_CALL(selectAllDirectories, valuesReturnStdVectorDirectory(_)) .Times(AnyNumber()); diff --git a/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp b/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp index 79ee210a077..92ddc10a4a8 100644 --- a/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp +++ b/tests/unit/unittest/filepathstoragesqlitestatementfactory-test.cpp @@ -34,15 +34,12 @@ namespace { -using StatementFactory = ClangBackEnd::FilePathStorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>, - MockSqliteReadStatement, - MockSqliteWriteStatement>; +using StatementFactory = ClangBackEnd::FilePathStorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>>; class FilePathStorageSqliteStatementFactory : public testing::Test { protected: - NiceMock<MockMutex> mockMutex; - NiceMock<MockSqliteDatabase> mockDatabase{mockMutex}; + NiceMock<MockSqliteDatabase> mockDatabase; StatementFactory factory{mockDatabase}; }; diff --git a/tests/unit/unittest/filestatuscache-test.cpp b/tests/unit/unittest/filestatuscache-test.cpp new file mode 100644 index 00000000000..db13bc28a7c --- /dev/null +++ b/tests/unit/unittest/filestatuscache-test.cpp @@ -0,0 +1,164 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 <filepathcaching.h> +#include <filestatuscache.h> +#include <refactoringdatabaseinitializer.h> + +#include <QDateTime> +#include <QFileInfo> + +#include <fstream> + +namespace { + +using ClangBackEnd::FilePathId; + +class FileStatusCache : public testing::Test +{ +protected: + FilePathId filePathId(Utils::SmallStringView path) const + { + return filePathCache.filePathId(ClangBackEnd::FilePathView(path)); + } + + void touchFile(FilePathId filePathId) + { + std::ofstream ostream(std::string(filePathCache.filePath(filePathId)), std::ios::binary); + ostream.write("\n", 1); + ostream.close(); + } + +protected: + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; + ClangBackEnd::FileStatusCache cache{filePathCache}; + FilePathId header{filePathId(TESTDATA_DIR "/filestatuscache_header.h")}; + FilePathId source{filePathId(TESTDATA_DIR "/filestatuscache_header.cpp")}; + long long headerLastModifiedTime = QFileInfo(TESTDATA_DIR "/filestatuscache_header.h").lastModified().toSecsSinceEpoch(); + long long sourceLastModifiedTime = QFileInfo(TESTDATA_DIR "/filestatuscache_header.cpp").lastModified().toSecsSinceEpoch(); +}; + +TEST_F(FileStatusCache, CreateEntry) +{ + cache.lastModifiedTime(header); + + ASSERT_THAT(cache, SizeIs(1)); +} + +TEST_F(FileStatusCache, AskCreatedEntryForLastModifiedTime) +{ + auto lastModified = cache.lastModifiedTime(header); + + ASSERT_THAT(lastModified, headerLastModifiedTime); +} + +TEST_F(FileStatusCache, AskCachedEntryForLastModifiedTime) +{ + cache.lastModifiedTime(header); + + auto lastModified = cache.lastModifiedTime(header); + + ASSERT_THAT(lastModified, headerLastModifiedTime); +} + +TEST_F(FileStatusCache, DontAddEntryTwice) +{ + cache.lastModifiedTime(header); + + cache.lastModifiedTime(header); + + ASSERT_THAT(cache, SizeIs(1)); +} + +TEST_F(FileStatusCache, AddNewEntry) +{ + cache.lastModifiedTime(header); + + cache.lastModifiedTime(source); + + ASSERT_THAT(cache, SizeIs(2)); +} + +TEST_F(FileStatusCache, AskNewEntryForLastModifiedTime) +{ + cache.lastModifiedTime(header); + + auto lastModified = cache.lastModifiedTime(source); + + ASSERT_THAT(lastModified, sourceLastModifiedTime); +} + +TEST_F(FileStatusCache, AddNewEntryReverseOrder) +{ + cache.lastModifiedTime(source); + + cache.lastModifiedTime(header); + + ASSERT_THAT(cache, SizeIs(2)); +} + +TEST_F(FileStatusCache, AskNewEntryReverseOrderAddedForLastModifiedTime) +{ + cache.lastModifiedTime(source); + + auto lastModified = cache.lastModifiedTime(header); + + ASSERT_THAT(lastModified, headerLastModifiedTime); +} + +TEST_F(FileStatusCache, UpdateFile) +{ + auto oldLastModified = cache.lastModifiedTime(header); + touchFile(header); + + cache.update(header); + + ASSERT_THAT(cache.lastModifiedTime(header), Gt(oldLastModified)); +} + +TEST_F(FileStatusCache, UpdateFileDoesNotChangeEntryCount) +{ + cache.lastModifiedTime(header); + touchFile(header); + + cache.update(header); + + ASSERT_THAT(cache, SizeIs(1)); +} + +TEST_F(FileStatusCache, UpdateFileForNonExistingEntry) +{ + touchFile(header); + + cache.update(header); + + ASSERT_THAT(cache, SizeIs(0)); +} + +} diff --git a/tests/unit/unittest/google-using-declarations.h b/tests/unit/unittest/google-using-declarations.h index 4627e04427d..321cd1b540b 100644 --- a/tests/unit/unittest/google-using-declarations.h +++ b/tests/unit/unittest/google-using-declarations.h @@ -28,7 +28,9 @@ #include <gmock/gmock.h> using testing::_; +using testing::A; using testing::AllOf; +using testing::An; using testing::AnyNumber; using testing::AnyOf; using testing::Assign; @@ -38,6 +40,7 @@ using testing::Field; using testing::HasSubstr; using testing::InSequence; using testing::IsEmpty; +using testing::Matcher; using testing::Mock; using testing::MockFunction; using testing::NiceMock; @@ -47,10 +50,12 @@ using testing::PrintToString; using testing::Property; using testing::Return; using testing::ReturnRef; +using testing::SafeMatcherCast; using testing::Sequence; using testing::SizeIs; using testing::StrEq; using testing::Throw; +using testing::TypedEq; using testing::UnorderedElementsAre; using testing::Eq; diff --git a/tests/unit/unittest/gtest-creator-printing.cpp b/tests/unit/unittest/gtest-creator-printing.cpp index dc8edee24b4..c3e02240fe4 100644 --- a/tests/unit/unittest/gtest-creator-printing.cpp +++ b/tests/unit/unittest/gtest-creator-printing.cpp @@ -35,20 +35,29 @@ #include <clangcodemodelservermessages.h> #include <clangpathwatcher.h> #include <clangrefactoringmessages.h> +#include <filestatus.h> #include <filepath.h> +#include <fulltokeninfo.h> #include <nativefilepath.h> #include <precompiledheadersupdatedmessage.h> +#include <projectpartartefact.h> +#include <sourcedependency.h> #include <sourcelocationentry.h> #include <sourcelocationscontainer.h> -#include <tokeninfos.h> +#include <tokenprocessor.h> #include <filepathview.h> +#include <symbolentry.h> +#include <symbol.h> #include <tooltipinfo.h> +#include <projectpartentry.h> +#include <usedmacro.h> #include <cpptools/usages.h> #include <projectexplorer/projectmacro.h> #include <coreplugin/find/searchresultitem.h> +#include <coreplugin/locator/ilocatorfilter.h> void PrintTo(const Utf8String &text, ::std::ostream *os) { @@ -56,6 +65,20 @@ void PrintTo(const Utf8String &text, ::std::ostream *os) } namespace Core { + +std::ostream &operator<<(std::ostream &out, const LocatorFilterEntry &entry) +{ + out << "(" + << entry.displayName << ", "; + + if (entry.internalData.canConvert<ClangRefactoring::Symbol>()) + out << entry.internalData.value<ClangRefactoring::Symbol>(); + + out << ")"; + + return out; +} + namespace Search { using testing::PrintToString; @@ -114,6 +137,12 @@ std::ostream &operator<<(std::ostream &out, const Macro ¯o) } // namespace ProjectExplorer namespace Utils { + +std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn) +{ + return out << "(" << lineColumn.line << ", " << lineColumn.column << ")"; +} + void PrintTo(const Utils::SmallString &text, ::std::ostream *os) { *os << text; @@ -130,7 +159,7 @@ namespace ClangBackEnd { std::ostream &operator<<(std::ostream &out, const FilePathId &id) { - return out << "(" << id.directoryId << ", " << id.fileNameId << ")"; + return out << "(" << id.directoryId << ", " << id.filePathId << ")"; } std::ostream &operator<<(std::ostream &out, const FilePathView &filePathView) @@ -152,12 +181,30 @@ std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths) return out; } +#define RETURN_TEXT_FOR_CASE(enumValue) case SourceLocationKind::enumValue: return #enumValue +static const char *symbolTypeToCStringLiteral(ClangBackEnd::SourceLocationKind kind) +{ + switch (kind) { + RETURN_TEXT_FOR_CASE(None); + RETURN_TEXT_FOR_CASE(Declaration); + RETURN_TEXT_FOR_CASE(DeclarationReference); + RETURN_TEXT_FOR_CASE(Definition); + RETURN_TEXT_FOR_CASE(MacroDefinition); + RETURN_TEXT_FOR_CASE(MacroUsage); + RETURN_TEXT_FOR_CASE(MacroUndefinition); + } + + return ""; +} +#undef RETURN_TEXT_FOR_CASE + std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry) { out << "(" + << entry.symbolId << ", " << entry.filePathId << ", " - << entry.line << ", " - << entry.column << ")"; + << entry.lineColumn << ", " + << symbolTypeToCStringLiteral(entry.kind) << ")"; return out; } @@ -184,7 +231,7 @@ std::ostream &operator<<(std::ostream &os, const SourceLocationsContainer &conta std::ostream &operator<<(std::ostream &os, const RegisterProjectPartsForEditorMessage &message) { os << "(" - << message.projectContainers() + << message.projectContainers << ")"; return os; @@ -193,9 +240,9 @@ std::ostream &operator<<(std::ostream &os, const RegisterProjectPartsForEditorMe std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message) { os << "(" - << message.fileContainer() << ", " - << message.ticketNumber() << ", " - << message.sourceRange() << ", " + << message.fileContainer << ", " + << message.ticketNumber << ", " + << message.sourceRange << ", " << ")"; return os; @@ -204,13 +251,13 @@ std::ostream &operator<<(std::ostream &os, const FollowSymbolMessage &message) std::ostream &operator<<(std::ostream &os, const CompleteCodeMessage &message) { os << "(" - << message.filePath() << ", " - << message.line() << ", " - << message.column() << ", " - << message.projectPartId() << ", " - << message.ticketNumber() << ", " - << message.funcNameStartLine() << ", " - << message.funcNameStartColumn() + << message.filePath << ", " + << message.line << ", " + << message.column << ", " + << message.projectPartId << ", " + << message.ticketNumber << ", " + << message.funcNameStartLine << ", " + << message.funcNameStartColumn << ")"; @@ -220,9 +267,9 @@ std::ostream &operator<<(std::ostream &os, const CompleteCodeMessage &message) std::ostream &operator<<(std::ostream &os, const RegisterTranslationUnitForEditorMessage &message) { os << "RegisterTranslationUnitForEditorMessage(" - << message.fileContainers() << ", " - << message.currentEditorFilePath() << ", " - << message.visibleEditorFilePaths() << ")"; + << message.fileContainers << ", " + << message.currentEditorFilePath << ", " + << message.visibleEditorFilePaths << ")"; return os; } @@ -257,9 +304,9 @@ static const char *completionCorrectionToText(CompletionCorrection correction) std::ostream &operator<<(std::ostream &os, const CodeCompletedMessage &message) { os << "(" - << message.codeCompletions() << ", " - << completionCorrectionToText(message.neededCorrection()) << ", " - << message.ticketNumber() + << message.codeCompletions << ", " + << completionCorrectionToText(message.neededCorrection) << ", " + << message.ticketNumber << ")"; @@ -269,11 +316,11 @@ std::ostream &operator<<(std::ostream &os, const CodeCompletedMessage &message) std::ostream &operator<<(std::ostream &os, const DocumentAnnotationsChangedMessage &message) { os << "DocumentAnnotationsChangedMessage(" - << message.fileContainer() - << "," << message.diagnostics().size() - << "," << !message.firstHeaderErrorDiagnostic().text().isEmpty() - << "," << message.tokenInfos().size() - << "," << message.skippedPreprocessorRanges().size() + << message.fileContainer + << "," << message.diagnostics.size() + << "," << !message.firstHeaderErrorDiagnostic.text.isEmpty() + << "," << message.tokenInfos.size() + << "," << message.skippedPreprocessorRanges.size() << ")"; return os; @@ -282,10 +329,10 @@ std::ostream &operator<<(std::ostream &os, const DocumentAnnotationsChangedMessa std::ostream &operator<<(std::ostream &os, const ReferencesMessage &message) { os << "(" - << message.fileContainer() << ", " - << message.ticketNumber() << ", " - << message.isLocalVariable() << ", " - << message.references() << ", " + << message.fileContainer << ", " + << message.ticketNumber << ", " + << message.isLocalVariable << ", " + << message.references << ", " << ")"; return os; @@ -294,9 +341,9 @@ std::ostream &operator<<(std::ostream &os, const ReferencesMessage &message) std::ostream &operator<<(std::ostream &os, const ToolTipMessage &message) { os << "(" - << message.fileContainer() << ", " - << message.ticketNumber() << ", " - << message.toolTipInfo() << ", " + << message.fileContainer << ", " + << message.ticketNumber << ", " + << message.toolTipInfo << ", " << ")"; return os; @@ -310,7 +357,7 @@ std::ostream &operator<<(std::ostream &os, const EchoMessage &/*message*/) std::ostream &operator<<(std::ostream &os, const UnregisterProjectPartsForEditorMessage &message) { os << "(" - << message.projectPartIds() + << message.projectPartIds << ")"; return os; @@ -319,7 +366,7 @@ std::ostream &operator<<(std::ostream &os, const UnregisterProjectPartsForEditor std::ostream &operator<<(std::ostream &os, const UnregisterTranslationUnitsForEditorMessage &message) { os << "(" - << message.fileContainers() + << message.fileContainers << ")"; return os; @@ -328,11 +375,11 @@ std::ostream &operator<<(std::ostream &os, const UnregisterTranslationUnitsForEd std::ostream &operator<<(std::ostream &os, const CodeCompletion &message) { os << "(" - << message.text() << ", " - << message.priority() << ", " - << message.completionKind() << ", " - << message.availability() << ", " - << message.hasParameters() + << message.text << ", " + << message.priority << ", " + << message.completionKind << ", " + << message.availability << ", " + << message.hasParameters << ")"; return os; @@ -341,10 +388,10 @@ std::ostream &operator<<(std::ostream &os, const CodeCompletion &message) std::ostream &operator<<(std::ostream &os, const CodeCompletionChunk &chunk) { os << "(" - << chunk.kind() << ", " - << chunk.text(); + << chunk.kind << ", " + << chunk.text; - if (chunk.isOptional()) + if (chunk.isOptional) os << ", optional"; os << ")"; @@ -368,14 +415,14 @@ static const char *severityToText(DiagnosticSeverity severity) std::ostream &operator<<(std::ostream &os, const DiagnosticContainer &container) { os << "(" - << severityToText(container.severity()) << ": " - << container.text() << ", " - << container.category() << ", " - << container.enableOption() << ", " - << container.location() << ", " - << container.ranges() << ", " - << container.fixIts() << ", " - << container.children() << ")"; + << severityToText(container.severity) << ": " + << container.text << ", " + << container.category << ", " + << container.enableOption << ", " + << container.location << ", " + << container.ranges << ", " + << container.fixIts << ", " + << container.children << ")"; return os; } @@ -383,8 +430,8 @@ std::ostream &operator<<(std::ostream &os, const DiagnosticContainer &container) std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticContainer &container) { os << "(" - << container.messages() << ", " - << container.contexts() + << container.messages << ", " + << container.contexts << ")"; return os; @@ -394,8 +441,8 @@ std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticCont { os << "(" << container.contextTypeText() << ", " - << container.sourceRange() << ", " - << container.arguments() + << container.sourceRange << ", " + << container.arguments << ")"; return os; @@ -405,8 +452,8 @@ std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticMess { os << "(" << container.errorTypeText() << ", " - << container.sourceRange() << ", " - << container.arguments() + << container.sourceRange << ", " + << container.arguments << ")"; return os; @@ -415,15 +462,15 @@ std::ostream &operator<<(std::ostream &os, const DynamicASTMatcherDiagnosticMess std::ostream &operator<<(std::ostream &os, const FileContainer &container) { os << "(" - << container.filePath() << ", " - << container.projectPartId() << ", " - << container.fileArguments() << ", " - << container.documentRevision() << ", " - << container.textCodecName(); + << container.filePath << ", " + << container.projectPartId << ", " + << container.fileArguments << ", " + << container.documentRevision << ", " + << container.textCodecName; - if (container.hasUnsavedFileContent()) + if (container.hasUnsavedFileContent) os << ", " - << container.unsavedFileContent(); + << container.unsavedFileContent; os << ")"; @@ -433,8 +480,8 @@ std::ostream &operator<<(std::ostream &os, const FileContainer &container) std::ostream &operator<<(std::ostream &os, const FixItContainer &container) { os << "(" - << container.text() << ", " - << container.range() + << container.text << ", " + << container.range << ")"; return os; @@ -461,10 +508,26 @@ static const char *highlightingTypeToCStringLiteral(HighlightingType type) RETURN_TEXT_FOR_CASE(Label); RETURN_TEXT_FOR_CASE(FunctionDefinition); RETURN_TEXT_FOR_CASE(OutputArgument); + RETURN_TEXT_FOR_CASE(OverloadedOperator); RETURN_TEXT_FOR_CASE(PreprocessorDefinition); RETURN_TEXT_FOR_CASE(PreprocessorExpansion); RETURN_TEXT_FOR_CASE(PrimitiveType); RETURN_TEXT_FOR_CASE(Declaration); + RETURN_TEXT_FOR_CASE(Namespace); + RETURN_TEXT_FOR_CASE(Class); + RETURN_TEXT_FOR_CASE(Struct); + RETURN_TEXT_FOR_CASE(Enum); + RETURN_TEXT_FOR_CASE(Union); + RETURN_TEXT_FOR_CASE(TypeAlias); + RETURN_TEXT_FOR_CASE(Typedef); + RETURN_TEXT_FOR_CASE(QtProperty); + RETURN_TEXT_FOR_CASE(ObjectiveCClass); + RETURN_TEXT_FOR_CASE(ObjectiveCCategory); + RETURN_TEXT_FOR_CASE(ObjectiveCProtocol); + RETURN_TEXT_FOR_CASE(ObjectiveCInterface); + RETURN_TEXT_FOR_CASE(ObjectiveCImplementation); + RETURN_TEXT_FOR_CASE(ObjectiveCProperty); + RETURN_TEXT_FOR_CASE(ObjectiveCMethod); } return ""; @@ -489,15 +552,32 @@ std::ostream &operator<<(std::ostream &os, HighlightingTypes types) return os; } +std::ostream &operator<<(std::ostream &os, const ExtraInfo &extraInfo) +{ + os << "(" + << extraInfo.token << ", " + << extraInfo.typeSpelling << ", " + << extraInfo.semanticParentTypeSpelling << ", " + << static_cast<uint>(extraInfo.accessSpecifier) << ", " + << static_cast<uint>(extraInfo.storageClass) << ", " + << extraInfo.identifier << ", " + << extraInfo.includeDirectivePath << ", " + << extraInfo.declaration << ", " + << extraInfo.definition << ", " + << extraInfo.signal << ", " + << extraInfo.slot + << ")"; + return os; +} + std::ostream &operator<<(std::ostream &os, const TokenInfoContainer &container) { os << "(" - << container.line() << ", " - << container.column() << ", " - << container.length() << ", " - << container.types() << ", " - << container.isIdentifier() << ", " - << container.isIncludeDirectivePath() + << container.line << ", " + << container.column << ", " + << container.length << ", " + << container.types << ", " + << container.extraInfo << ", " << ")"; return os; @@ -511,7 +591,7 @@ std::ostream &operator<<(std::ostream &out, const NativeFilePath &filePath) std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessage &message) { out << "(" - << message.projectPartPchs() + << message.projectPartPchs << ")"; return out; @@ -520,9 +600,9 @@ std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessa std::ostream &operator<<(std::ostream &os, const ProjectPartContainer &container) { os << "(" - << container.projectPartId() + << container.projectPartId << "," - << container.arguments() + << container.arguments << ")"; return os; @@ -531,8 +611,8 @@ std::ostream &operator<<(std::ostream &os, const ProjectPartContainer &container std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch) { out << "(" - << projectPartPch.id() << ", " - << projectPartPch.path() << ")"; + << projectPartPch.projectPartId << ", " + << projectPartPch.pchPath << ")"; return out; } @@ -540,7 +620,7 @@ std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch std::ostream &operator<<(std::ostream &os, const RegisterUnsavedFilesForEditorMessage &message) { os << "(" - << message.fileContainers() + << message.fileContainers << ")"; return os; @@ -549,25 +629,25 @@ std::ostream &operator<<(std::ostream &os, const RegisterUnsavedFilesForEditorMe std::ostream &operator<<(std::ostream &os, const RequestDocumentAnnotationsMessage &message) { os << "(" - << message.fileContainer().filePath() << "," - << message.fileContainer().projectPartId() + << message.fileContainer.filePath << "," + << message.fileContainer.projectPartId << ")"; return os; } -std::ostream &operator<<(std::ostream &out, const RemovePchProjectPartsMessage &message) +std::ostream &operator<<(std::ostream &out, const RemoveProjectPartsMessage &message) { - return out << "(" << message.projectsPartIds() << ")"; + return out << "(" << message.projectsPartIds << ")"; } std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &message) { os << "(" - << message.fileContainer() << ", " - << message.ticketNumber() << ", " - << message.line() << ", " - << message.column() << ", " + << message.fileContainer << ", " + << message.ticketNumber << ", " + << message.line << ", " + << message.column << ", " << ")"; return os; @@ -576,11 +656,11 @@ std::ostream &operator<<(std::ostream &os, const RequestFollowSymbolMessage &mes std::ostream &operator<<(std::ostream &os, const RequestReferencesMessage &message) { os << "(" - << message.fileContainer() << ", " - << message.ticketNumber() << ", " - << message.line() << ", " - << message.column() << ", " - << message.local() << ", " + << message.fileContainer << ", " + << message.ticketNumber << ", " + << message.line << ", " + << message.column << ", " + << message.local << ", " << ")"; return os; @@ -589,10 +669,10 @@ std::ostream &operator<<(std::ostream &os, const RequestReferencesMessage &messa std::ostream &operator<<(std::ostream &out, const RequestToolTipMessage &message) { out << "(" - << message.fileContainer() << ", " - << message.ticketNumber() << ", " - << message.line() << ", " - << message.column() << ", " + << message.fileContainer << ", " + << message.ticketNumber << ", " + << message.line << ", " + << message.column << ", " << ")"; return out; @@ -606,12 +686,12 @@ std::ostream &operator<<(std::ostream &os, const ToolTipInfo::QdocCategory categ 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 << ", " + << info.text << ", " + << info.briefComment << ", " + << info.qdocIdCandidates << ", " + << info.qdocMark << ", " + << info.qdocCategory + << info.sizeInBytes << ", " << ")"; return out; @@ -619,13 +699,12 @@ std::ostream &operator<<(std::ostream &out, const ToolTipInfo &info) std::ostream &operator<<(std::ostream &os, const RequestSourceLocationsForRenamingMessage &message) { - os << "(" - << message.filePath() << ", " - << message.line() << ", " - << message.column() << ", " - << message.unsavedContent() << ", " - << message.commandLine() + << message.filePath << ", " + << message.line << ", " + << message.column << ", " + << message.unsavedContent << ", " + << message.commandLine << ")"; return os; @@ -634,8 +713,8 @@ std::ostream &operator<<(std::ostream &os, const RequestSourceLocationsForRenami std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosticsForQueryMessage &message) { os << "(" - << message.query() << ", " - << message.source() + << message.query << ", " + << message.source << ")"; return os; @@ -644,7 +723,7 @@ std::ostream &operator<<(std::ostream &os, const RequestSourceRangesAndDiagnosti std::ostream &operator<<(std::ostream &os, const RequestSourceRangesForQueryMessage &message) { os << "(" - << message.query() + << message.query << ")"; return os; @@ -653,9 +732,9 @@ std::ostream &operator<<(std::ostream &os, const RequestSourceRangesForQueryMess std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container) { os << "(" - << container.filePath() << ", " - << container.line() << ", " - << container.column() + << container.filePath << ", " + << container.line << ", " + << container.column << ")"; return os; @@ -664,9 +743,9 @@ std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &contai std::ostream &operator<<(std::ostream &os, const SourceLocationsForRenamingMessage &message) { os << "(" - << message.symbolName() << ", " - << message.textDocumentRevision() << ", " - << message.sourceLocations() + << message.symbolName << ", " + << message.textDocumentRevision << ", " + << message.sourceLocations << ")"; return os; @@ -675,8 +754,8 @@ std::ostream &operator<<(std::ostream &os, const SourceLocationsForRenamingMessa std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container) { os << "(" - << container.start() << ", " - << container.end() + << container.start << ", " + << container.end << ")"; return os; @@ -685,8 +764,8 @@ std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container std::ostream &operator<<(std::ostream &os, const SourceRangesAndDiagnosticsForQueryMessage &message) { os << "(" - << message.sourceRanges() << ", " - << message.diagnostics() + << message.sourceRanges << ", " + << message.diagnostics << ")"; return os; @@ -695,7 +774,7 @@ std::ostream &operator<<(std::ostream &os, const SourceRangesAndDiagnosticsForQu std::ostream &operator<<(std::ostream &os, const SourceRangesContainer &container) { os << "(" - << container.sourceRangeWithTextContainers() + << container.sourceRangeWithTextContainers << ")"; return os; @@ -704,7 +783,7 @@ std::ostream &operator<<(std::ostream &os, const SourceRangesContainer &containe std::ostream &operator<<(std::ostream &os, const SourceRangesForQueryMessage &message) { os << "(" - << message.sourceRanges() + << message.sourceRanges << ")"; return os; @@ -714,9 +793,9 @@ std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &c { os << "(" - << container.start() << ", " - << container.end() << ", " - << container.text() + << container.start << ", " + << container.end << ", " + << container.text << ")"; return os; @@ -725,23 +804,23 @@ std::ostream &operator<<(std::ostream &os, const SourceRangeWithTextContainer &c std::ostream &operator<<(std::ostream &os, const UnregisterUnsavedFilesForEditorMessage &message) { os << "(" - << message.fileContainers() + << message.fileContainers << ")"; return os; } -std::ostream &operator<<(std::ostream &out, const UpdatePchProjectPartsMessage &message) +std::ostream &operator<<(std::ostream &out, const UpdateProjectPartsMessage &message) { return out << "(" - << message.projectsParts() + << message.projectsParts << ")"; } std::ostream &operator<<(std::ostream &os, const UpdateTranslationUnitsForEditorMessage &message) { os << "UpdateTranslationUnitsForEditorMessage(" - << message.fileContainers() + << message.fileContainers << ")"; return os; @@ -750,14 +829,14 @@ std::ostream &operator<<(std::ostream &os, const UpdateTranslationUnitsForEditor std::ostream &operator<<(std::ostream &os, const UpdateVisibleTranslationUnitsMessage &message) { os << "(" - << message.currentEditorFilePath() << ", " - << message.visibleEditorFilePaths() + << message.currentEditorFilePath << ", " + << message.visibleEditorFilePaths << ")"; return os; } -std::ostream &operator<<(std::ostream &os, const TokenInfo& tokenInfo) +std::ostream &operator<<(std::ostream &os, const TokenInfo &tokenInfo) { os << "(type: " << tokenInfo.types() << ", " << " line: " << tokenInfo.line() << ", " @@ -768,11 +847,12 @@ std::ostream &operator<<(std::ostream &os, const TokenInfo& tokenInfo) return os; } -std::ostream &operator<<(std::ostream &out, const TokenInfos &tokenInfos) +template<class T> +std::ostream &operator<<(std::ostream &out, const TokenProcessor<T> &tokenInfos) { out << "["; - for (const TokenInfo &entry : tokenInfos) + for (const T &entry : tokenInfos) out << entry; out << "]"; @@ -780,11 +860,128 @@ std::ostream &operator<<(std::ostream &out, const TokenInfos &tokenInfos) return out; } +template +std::ostream &operator<<(std::ostream &out, const TokenProcessor<TokenInfo> &tokenInfos); +template +std::ostream &operator<<(std::ostream &out, const TokenProcessor<FullTokenInfo> &tokenInfos); + std::ostream &operator<<(std::ostream &out, const FilePath &filePath) { return out << "(" << filePath.path() << ", " << filePath.slashIndex() << ")"; } +std::ostream &operator<<(std::ostream &out, const ProjectPartEntry &projectPartEntry) +{ + return out << "(" + << projectPartEntry.projectPathName + << ", " + << projectPartEntry.filePathIds + << ")"; +} + +std::ostream &operator<<(std::ostream &out, const UsedMacro &usedMacro) +{ + return out << "(" + << usedMacro.filePathId + << ", " + << usedMacro.macroName + << ")"; +} + +std::ostream &operator<<(std::ostream &out, const FileStatus &fileStatus) +{ + return out << "(" + << fileStatus.filePathId + << ", " + << fileStatus.size + << ", " + << fileStatus.lastModified + << ")"; +} + +std::ostream &operator<<(std::ostream &out, const SourceDependency &sourceDependency) +{ + return out << "(" + << sourceDependency.filePathId + << ", " + << sourceDependency.dependencyFilePathId + << ")"; +} + +std::ostream &operator<<(std::ostream &out, const ProjectPartArtefact &projectPartArtefact) +{ + return out << "(" + << projectPartArtefact.compilerArguments << ", " + << projectPartArtefact.compilerMacros + <<")"; +} + +std::ostream &operator<<(std::ostream &out, const CompilerMacro &compilerMacro) +{ + return out << "(" + << compilerMacro.key << ", " + << compilerMacro.value + << ")"; +} + +std::ostream &operator<<(std::ostream &out, const SymbolEntry &entry) +{ + out << "(" + << entry.symbolName << ", " + << entry.usr << ", " + << entry.symbolKind <<")"; + + return out; +} + +const char *symbolKindString(SymbolKind symbolKind) +{ + using ClangBackEnd::SymbolKind; + + switch (symbolKind) { + case SymbolKind::None: return "None"; + case SymbolKind::Enumeration: return "Enumeration"; + case SymbolKind::Record: return "Record"; + case SymbolKind::Function: return "Function"; + case SymbolKind::Variable: return "Variable"; + case SymbolKind::Macro: return "Macro"; + } + + return ""; +} + +std::ostream &operator<<(std::ostream &out, SymbolKind symbolKind) +{ + return out << symbolKindString(symbolKind); +} + +const char *symbolTagString(SymbolTag symbolTag) +{ + using ClangBackEnd::SymbolTag; + + switch (symbolTag) { + case SymbolTag::None: return "None"; + case SymbolTag::Class: return "Class"; + case SymbolTag::Struct: return "Struct"; + case SymbolTag::Union: return "Union"; + case SymbolTag::MsvcInterface: return "MsvcInterface"; + } + + return ""; +} + +std::ostream &operator<<(std::ostream &out, SymbolTag symbolTag) +{ + return out << symbolTagString(symbolTag); +} + +std::ostream &operator<<(std::ostream &out, SymbolTags symbolTags) +{ + std::copy(symbolTags.cbegin(), symbolTags.cend(), std::ostream_iterator<SymbolTag>(out, ", ")); + + return out; +} + void PrintTo(const FilePath &filePath, ::std::ostream *os) { *os << filePath; @@ -795,18 +992,23 @@ void PrintTo(const FilePathView &filePathView, ::std::ostream *os) *os << filePathView; } +void PrintTo(const FilePathId &filePathId, ::std::ostream *os) +{ + *os << filePathId; +} + namespace V2 { std::ostream &operator<<(std::ostream &os, const FileContainer &container) { os << "(" - << container.filePath() << ", " - << container.commandLineArguments() << ", " - << container.documentRevision(); + << container.filePath << ", " + << container.commandLineArguments << ", " + << container.documentRevision; - if (container.unsavedFileContent().hasContent()) + if (container.unsavedFileContent.hasContent()) os << ", \"" - << container.unsavedFileContent(); + << container.unsavedFileContent; os << "\")"; @@ -816,10 +1018,11 @@ std::ostream &operator<<(std::ostream &os, const FileContainer &container) std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container) { out << "(" - << container.projectPartId() << ", " - << container.arguments() << ", " - << container.headerPaths() << ", " - << container.sourcePaths()<< ")"; + << container.projectPartId << ", " + << container.arguments << ", " + << container.headerPathIds << ", " + << container.compilerMacros << ", " + << container.includeSearchPaths << ")"; return out; } @@ -827,10 +1030,10 @@ std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &containe std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &container) { os << "((" - << container.filePathId().directoryId << ", " << container.filePathId().fileNameId << "), " - << container.line() << ", " - << container.column() << ", " - << container.offset() + << container.filePathId.directoryId << ", " << container.filePathId.filePathId << "), " + << container.line << ", " + << container.column << ", " + << container.offset << ")"; return os; @@ -839,8 +1042,8 @@ std::ostream &operator<<(std::ostream &os, const SourceLocationContainer &contai std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container) { os << "(" - << container.start() << ", " - << container.end() + << container.start << ", " + << container.end << ")"; return os; @@ -853,9 +1056,14 @@ std::ostream &operator<<(std::ostream &os, const SourceRangeContainer &container namespace ClangRefactoring { std::ostream &operator<<(std::ostream &out, const SourceLocation &location) { - return out << "(" << location.filePathId << ", " << location.line << ", " << location.column << ")"; + return out << "(" << location.filePathId << ", " << location.lineColumn << ")"; } -} // namespace ClangBackEnd + +std::ostream &operator<<(std::ostream &out, const Symbol &symbol) +{ + return out << "(" << symbol.name << ", " << symbol.symbolId << ", " << symbol.signature << ")"; +} +} // namespace ClangRefactoring namespace CppTools { diff --git a/tests/unit/unittest/gtest-creator-printing.h b/tests/unit/unittest/gtest-creator-printing.h index 73848ba8541..6404764544b 100644 --- a/tests/unit/unittest/gtest-creator-printing.h +++ b/tests/unit/unittest/gtest-creator-printing.h @@ -26,6 +26,7 @@ #pragma once #include <utils/smallstringio.h> +#include <utils/optional.h> #include <clangsupport_global.h> @@ -39,6 +40,10 @@ class Utf8String; void PrintTo(const Utf8String &text, ::std::ostream *os); namespace Core { +class LocatorFilterEntry; + +std::ostream &operator<<(std::ostream &out, const LocatorFilterEntry &entry); + namespace Search { class TextPosition; @@ -61,8 +66,28 @@ std::ostream &operator<<(std::ostream &out, const Macro ¯o); } // namespace ClangRefactoring namespace Utils { +class LineColumn; + +std::ostream &operator<<(std::ostream &out, const LineColumn &lineColumn); + +template <typename Type> +std::ostream &operator<<(std::ostream &out, const Utils::optional<Type> &optional) +{ + if (optional) + return out << "optional" << optional.value(); + else + return out << "empty optional()"; +} + +template <typename Type> +void PrintTo(const Utils::optional<Type> &optional, ::std::ostream *os) +{ + *os << optional; +} + void PrintTo(const Utils::SmallString &text, ::std::ostream *os); void PrintTo(const Utils::PathString &text, ::std::ostream *os); + } // namespace ProjectExplorer namespace ClangBackEnd { @@ -94,13 +119,14 @@ class DynamicASTMatcherDiagnosticContextContainer; class DynamicASTMatcherDiagnosticMessageContainer; class FileContainer; class FixItContainer; +class FullTokenInfo; class HighlightingMarkContainer; class NativeFilePath; class PrecompiledHeadersUpdatedMessage; class ProjectPartContainer; class ProjectPartPch; class RegisterUnsavedFilesForEditorMessage; -class RemovePchProjectPartsMessage; +class RemoveProjectPartsMessage; class RequestDocumentAnnotationsMessage; class RequestFollowSymbolMessage; class RequestReferencesMessage; @@ -115,18 +141,29 @@ class SourceRangesAndDiagnosticsForQueryMessage; class SourceRangesContainer; class SourceRangesForQueryMessage; class SourceRangeWithTextContainer; +class TokenInfo; +template<class T> +class TokenProcessor; class UnregisterUnsavedFilesForEditorMessage; -class UpdatePchProjectPartsMessage; +class UpdateProjectPartsMessage; class UpdateTranslationUnitsForEditorMessage; class UpdateVisibleTranslationUnitsMessage; class FilePath; -class TokenInfo; -class TokenInfos; template <char WindowsSlash> class AbstractFilePathView; using FilePathView = AbstractFilePathView<'/'>; using NativeFilePathView = AbstractFilePathView<'\\'>; class ToolTipInfo; +class ProjectPartEntry; +class UsedMacro; +class FileStatus; +class SourceDependency; +class ProjectPartArtefact; +class CompilerMacro; +class SymbolEntry; +enum class SymbolKind : uchar; +enum class SymbolTag : uchar; +using SymbolTags = Utils::SizedArray<SymbolTag, 7>; std::ostream &operator<<(std::ostream &out, const SourceLocationEntry &entry); std::ostream &operator<<(std::ostream &out, const IdPaths &idPaths); @@ -162,7 +199,7 @@ std::ostream &operator<<(std::ostream &out, const PrecompiledHeadersUpdatedMessa std::ostream &operator<<(std::ostream &out, const ProjectPartContainer &container); std::ostream &operator<<(std::ostream &out, const ProjectPartPch &projectPartPch); std::ostream &operator<<(std::ostream &out, const RegisterUnsavedFilesForEditorMessage &message); -std::ostream &operator<<(std::ostream &out, const RemovePchProjectPartsMessage &message); +std::ostream &operator<<(std::ostream &out, const RemoveProjectPartsMessage &message); 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); @@ -179,18 +216,34 @@ std::ostream &operator<<(std::ostream &out, const SourceRangesContainer &contain std::ostream &operator<<(std::ostream &out, const SourceRangesForQueryMessage &message); std::ostream &operator<<(std::ostream &out, const SourceRangeWithTextContainer &container); std::ostream &operator<<(std::ostream &out, const UnregisterUnsavedFilesForEditorMessage &message); -std::ostream &operator<<(std::ostream &out, const UpdatePchProjectPartsMessage &message); +std::ostream &operator<<(std::ostream &out, const UpdateProjectPartsMessage &message); std::ostream &operator<<(std::ostream &out, const UpdateTranslationUnitsForEditorMessage &message); std::ostream &operator<<(std::ostream &out, const UpdateVisibleTranslationUnitsMessage &message); std::ostream &operator<<(std::ostream &out, const FilePath &filePath); std::ostream &operator<<(std::ostream &out, const FilePathId &filePathId); std::ostream &operator<<(std::ostream &out, const TokenInfo& tokenInfo); -std::ostream &operator<<(std::ostream &out, const TokenInfos &tokenInfos); +template<class T> +std::ostream &operator<<(std::ostream &out, const TokenProcessor<T> &tokenInfos); +extern template +std::ostream &operator<<(std::ostream &out, const TokenProcessor<TokenInfo> &tokenInfos); +extern template +std::ostream &operator<<(std::ostream &out, const TokenProcessor<FullTokenInfo> &tokenInfos); std::ostream &operator<<(std::ostream &out, const FilePathView &filePathView); std::ostream &operator<<(std::ostream &out, const NativeFilePathView &nativeFilePathView); +std::ostream &operator<<(std::ostream &out, const ProjectPartEntry &projectPartEntry); +std::ostream &operator<<(std::ostream &out, const UsedMacro &usedMacro); +std::ostream &operator<<(std::ostream &out, const FileStatus &fileStatus); +std::ostream &operator<<(std::ostream &out, const SourceDependency &sourceDependency); +std::ostream &operator<<(std::ostream &out, const ProjectPartArtefact &projectPartArtefact); +std::ostream &operator<<(std::ostream &out, const CompilerMacro &compilerMacro); +std::ostream &operator<<(std::ostream &out, const SymbolEntry &symbolEntry); +std::ostream &operator<<(std::ostream &out, SymbolKind symbolKind); +std::ostream &operator<<(std::ostream &out, SymbolTag symbolTag); +std::ostream &operator<<(std::ostream &out, SymbolTags symbolTags); void PrintTo(const FilePath &filePath, ::std::ostream *os); void PrintTo(const FilePathView &filePathView, ::std::ostream *os); +void PrintTo(const FilePathId &filePathId, ::std::ostream *os); namespace V2 { class FileContainer; @@ -208,8 +261,10 @@ std::ostream &operator<<(std::ostream &out, const SourceRangeContainer &containe namespace ClangRefactoring { class SourceLocation; +class Symbol; std::ostream &operator<<(std::ostream &out, const SourceLocation &location); +std::ostream &operator<<(std::ostream &out, const Symbol &symbol); } // namespace ClangRefactoring diff --git a/tests/unit/unittest/tokeninfosreporter-test.cpp b/tests/unit/unittest/highlightingresultreporter-test.cpp index b6f4de0defc..906b334d166 100644 --- a/tests/unit/unittest/tokeninfosreporter-test.cpp +++ b/tests/unit/unittest/highlightingresultreporter-test.cpp @@ -31,14 +31,14 @@ #include <clangdocuments.h> #include <cursor.h> #include <tokeninfocontainer.h> -#include <tokeninfos.h> -#include <clangtokeninfosreporter.h> +#include <tokenprocessor.h> +#include <clanghighlightingresultreporter.h> #include <projectpart.h> #include <projects.h> #include <unsavedfiles.h> using ClangBackEnd::Cursor; -using ClangBackEnd::TokenInfos; +using ClangBackEnd::TokenProcessor; using ClangBackEnd::TokenInfoContainer; using ClangBackEnd::HighlightingType; using ClangBackEnd::Document; @@ -61,7 +61,7 @@ struct Data { documents}; }; -class TokenInfosReporter : public ::testing::Test +class HighlightingResultReporter : public ::testing::Test { public: static void SetUpTestCase(); @@ -82,15 +82,17 @@ QVector<TokenInfoContainer> generateTokenInfos(uint count) for (uint i = 0; i < count; ++i) { const uint line = i + 1; - container.append(TokenInfoContainer(line, 1, 1, HighlightingType::Type)); + ClangBackEnd::HighlightingTypes types; + types.mainHighlightingType = ClangBackEnd::HighlightingType::Type; + container.append(TokenInfoContainer(line, 1, 1, types)); } return container; } -TEST_F(TokenInfosReporter, StartAndFinish) +TEST_F(HighlightingResultReporter, StartAndFinish) { - auto reporter = new ClangCodeModel::TokenInfosReporter(noTokenInfos()); + auto reporter = new ClangCodeModel::HighlightingResultReporter(noTokenInfos()); auto future = reporter->start(); @@ -98,9 +100,9 @@ TEST_F(TokenInfosReporter, StartAndFinish) ASSERT_THAT(future.isFinished(), true); } -TEST_F(TokenInfosReporter, ReportNothingIfNothingToReport) +TEST_F(HighlightingResultReporter, ReportNothingIfNothingToReport) { - auto reporter = new ClangCodeModel::TokenInfosReporter(generateTokenInfos(0)); + auto reporter = new ClangCodeModel::HighlightingResultReporter(generateTokenInfos(0)); auto future = reporter->start(); @@ -108,9 +110,9 @@ TEST_F(TokenInfosReporter, ReportNothingIfNothingToReport) ASSERT_THAT(monitor.resultsReadyCounter(), 0L); } -TEST_F(TokenInfosReporter, ReportSingleResultAsOneChunk) +TEST_F(HighlightingResultReporter, ReportSingleResultAsOneChunk) { - auto reporter = new ClangCodeModel::TokenInfosReporter(generateTokenInfos(1)); + auto reporter = new ClangCodeModel::HighlightingResultReporter(generateTokenInfos(1)); reporter->setChunkSize(1); auto future = reporter->start(); @@ -119,9 +121,9 @@ TEST_F(TokenInfosReporter, ReportSingleResultAsOneChunk) ASSERT_THAT(monitor.resultsReadyCounter(), 1L); } -TEST_F(TokenInfosReporter, ReportRestIfChunkSizeNotReached) +TEST_F(HighlightingResultReporter, ReportRestIfChunkSizeNotReached) { - auto reporter = new ClangCodeModel::TokenInfosReporter(generateTokenInfos(1)); + auto reporter = new ClangCodeModel::HighlightingResultReporter(generateTokenInfos(1)); const int notReachedChunkSize = 100; reporter->setChunkSize(notReachedChunkSize); @@ -131,9 +133,9 @@ TEST_F(TokenInfosReporter, ReportRestIfChunkSizeNotReached) ASSERT_THAT(monitor.resultsReadyCounter(), 1L); } -TEST_F(TokenInfosReporter, ReportChunksWithoutRest) +TEST_F(HighlightingResultReporter, ReportChunksWithoutRest) { - auto reporter = new ClangCodeModel::TokenInfosReporter(generateTokenInfos(4)); + auto reporter = new ClangCodeModel::HighlightingResultReporter(generateTokenInfos(4)); reporter->setChunkSize(1); auto future = reporter->start(); @@ -142,9 +144,9 @@ TEST_F(TokenInfosReporter, ReportChunksWithoutRest) ASSERT_THAT(monitor.resultsReadyCounter(), 2L); } -TEST_F(TokenInfosReporter, ReportSingleChunkAndRest) +TEST_F(HighlightingResultReporter, ReportSingleChunkAndRest) { - auto reporter = new ClangCodeModel::TokenInfosReporter(generateTokenInfos(5)); + auto reporter = new ClangCodeModel::HighlightingResultReporter(generateTokenInfos(5)); reporter->setChunkSize(2); auto future = reporter->start(); @@ -153,14 +155,16 @@ TEST_F(TokenInfosReporter, ReportSingleChunkAndRest) ASSERT_THAT(monitor.resultsReadyCounter(), 2L); } -TEST_F(TokenInfosReporter, ReportCompleteLines) +TEST_F(HighlightingResultReporter, ReportCompleteLines) { + ClangBackEnd::HighlightingTypes types; + types.mainHighlightingType = ClangBackEnd::HighlightingType::Type; QVector<TokenInfoContainer> tokenInfos { - TokenInfoContainer(1, 1, 1, HighlightingType::Type), - TokenInfoContainer(1, 2, 1, HighlightingType::Type), - TokenInfoContainer(2, 1, 1, HighlightingType::Type), + TokenInfoContainer(1, 1, 1, types), + TokenInfoContainer(1, 2, 1, types), + TokenInfoContainer(2, 1, 1, types), }; - auto reporter = new ClangCodeModel::TokenInfosReporter(tokenInfos); + auto reporter = new ClangCodeModel::HighlightingResultReporter(tokenInfos); reporter->setChunkSize(1); auto future = reporter->start(); @@ -169,14 +173,14 @@ TEST_F(TokenInfosReporter, ReportCompleteLines) ASSERT_THAT(monitor.resultsReadyCounter(), 2L); } -Data *TokenInfosReporter::d; +Data *HighlightingResultReporter::d; -void TokenInfosReporter::SetUpTestCase() +void HighlightingResultReporter::SetUpTestCase() { d = new Data; } -void TokenInfosReporter::TearDownTestCase() +void HighlightingResultReporter::TearDownTestCase() { delete d; d = nullptr; diff --git a/tests/unit/unittest/includecollector-test.cpp b/tests/unit/unittest/includecollector-test.cpp index a9c925ef73e..0a823b52b7e 100644 --- a/tests/unit/unittest/includecollector-test.cpp +++ b/tests/unit/unittest/includecollector-test.cpp @@ -47,8 +47,21 @@ namespace { class IncludeCollector : public ::testing::Test { protected: - void SetUp(); - FilePathId id(const Utils::SmallStringView &path); + void SetUp() + { + collector.addFile(TESTDATA_DIR, "includecollector_main.cpp", "", {"cc", "includecollector_main.cpp"}); + collector.addFile(TESTDATA_DIR, "includecollector_main2.cpp", "", {"cc", "includecollector_main2.cpp"}); + + collector.addUnsavedFiles({{{TESTDATA_DIR, "includecollector_generated_file.h"}, "#pragma once", {}}}); + + collector.setExcludedIncludes(excludePaths.clone()); + emptyCollector.setExcludedIncludes(excludePaths.clone()); + } + + FilePathId id(const Utils::SmallStringView &path) + { + return filePathCache.filePathId(FilePathView{path}); + } protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; @@ -56,8 +69,8 @@ protected: ClangBackEnd::FilePathCaching filePathCache{database}; ClangBackEnd::IncludeCollector collector{filePathCache}; ClangBackEnd::IncludeCollector emptyCollector{filePathCache}; - Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector_main.h", - TESTDATA_DIR "/includecollector_main2.h", + Utils::PathStringVector excludePaths = {TESTDATA_DIR "/includecollector_main.cpp", + TESTDATA_DIR "/includecollector_main2.cpp", TESTDATA_DIR "/includecollector_header1.h", TESTDATA_DIR "/includecollector_header2.h", TESTDATA_DIR "/includecollector_generated_file.h"}; @@ -69,7 +82,9 @@ TEST_F(IncludeCollector, IncludesExternalHeader) ASSERT_THAT(collector.takeIncludeIds(), AllOf(Contains(id(TESTDATA_DIR "/includecollector_external1.h")), - Contains(id(TESTDATA_DIR "/includecollector_external2.h")))); + Contains(id(TESTDATA_DIR "/includecollector_external2.h")), + Contains(id(TESTDATA_DIR "/includecollector_indirect_external.h")), + Contains(id(TESTDATA_DIR "/includecollector_indirect_external2.h")))); } TEST_F(IncludeCollector, DoesNotIncludesInternalHeader) @@ -86,7 +101,9 @@ TEST_F(IncludeCollector, NoDuplicate) ASSERT_THAT(collector.takeIncludeIds(), UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"), id(TESTDATA_DIR "/includecollector_external2.h"), - id(TESTDATA_DIR "/includecollector_external3.h"))); + id(TESTDATA_DIR "/includecollector_external3.h"), + id(TESTDATA_DIR "/includecollector_indirect_external.h"), + id(TESTDATA_DIR "/includecollector_indirect_external2.h"))); } TEST_F(IncludeCollector, IncludesAreSorted) @@ -94,7 +111,7 @@ TEST_F(IncludeCollector, IncludesAreSorted) collector.collectIncludes(); ASSERT_THAT(collector.takeIncludeIds(), - SizeIs(3)); + SizeIs(5)); } TEST_F(IncludeCollector, If) @@ -116,7 +133,9 @@ TEST_F(IncludeCollector, LocalPath) ASSERT_THAT(emptyCollector.takeIncludeIds(), UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"), id(TESTDATA_DIR "/includecollector_external2.h"), - id(TESTDATA_DIR "/includecollector_external3.h"))); + id(TESTDATA_DIR "/includecollector_external3.h"), + id(TESTDATA_DIR "/includecollector_indirect_external.h"), + id(TESTDATA_DIR "/includecollector_indirect_external2.h"))); } TEST_F(IncludeCollector, IgnoreMissingFile) @@ -126,23 +145,53 @@ TEST_F(IncludeCollector, IgnoreMissingFile) emptyCollector.collectIncludes(); ASSERT_THAT(emptyCollector.takeIncludeIds(), - UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"))); + UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"), + id(TESTDATA_DIR "/includecollector_indirect_external.h"), + id(TESTDATA_DIR "/includecollector_indirect_external2.h"))); } -void IncludeCollector::SetUp() +TEST_F(IncludeCollector, IncludesOnlyTopExternalHeader) { - collector.addFile(TESTDATA_DIR, "includecollector_main.cpp", "", {"cc", "includecollector_main.cpp"}); - collector.addFile(TESTDATA_DIR, "includecollector_main2.cpp", "", {"cc", "includecollector_main2.cpp"}); + collector.collectIncludes(); - collector.addUnsavedFiles({{{TESTDATA_DIR, "includecollector_generated_file.h"}, "#pragma once", {}}}); + ASSERT_THAT(collector.takeTopIncludeIds(), + UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"), + id(TESTDATA_DIR "/includecollector_external2.h"), + id(TESTDATA_DIR "/includecollector_external3.h"))); +} + +TEST_F(IncludeCollector, TopIncludeInIfMacro) +{ + emptyCollector.addFile(TESTDATA_DIR, "includecollector_if.cpp", "", {"cc", "includecollector_if.cpp"}); + emptyCollector.setExcludedIncludes({"includecollector_if.cpp"}); + + emptyCollector.collectIncludes(); - collector.setExcludedIncludes(excludePaths.clone()); - emptyCollector.setExcludedIncludes(excludePaths.clone()); + ASSERT_THAT(emptyCollector.takeTopIncludeIds(), + ElementsAre(id(TESTDATA_DIR "/includecollector_true.h"))); +} + +TEST_F(IncludeCollector, TopIncludeWithLocalPath) +{ + emptyCollector.addFile(TESTDATA_DIR, "includecollector_main.cpp", "", {"cc", "includecollector_main.cpp"}); + + emptyCollector.collectIncludes(); + + ASSERT_THAT(emptyCollector.takeTopIncludeIds(), + UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"), + id(TESTDATA_DIR "/includecollector_external2.h"), + id(TESTDATA_DIR "/includecollector_external3.h"))); } -FilePathId IncludeCollector::id(const Utils::SmallStringView &path) +TEST_F(IncludeCollector, TopIncludesIgnoreMissingFile) { - return filePathCache.filePathId(FilePathView{path}); + emptyCollector.addFile(TESTDATA_DIR, "includecollector_missingfile.cpp", "", {"cc", "includecollector_missingfile.cpp"}); + emptyCollector.setExcludedIncludes({"includecollector_missingfile.cpp"}); + + emptyCollector.collectIncludes(); + + ASSERT_THAT(emptyCollector.takeTopIncludeIds(), + UnorderedElementsAre(id(TESTDATA_DIR "/includecollector_external1.h"))); } } diff --git a/tests/unit/unittest/locatorfilter-test.cpp b/tests/unit/unittest/locatorfilter-test.cpp new file mode 100644 index 00000000000..00bdbbd1aea --- /dev/null +++ b/tests/unit/unittest/locatorfilter-test.cpp @@ -0,0 +1,123 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "mockeditormanager.h" +#include "mocksymbolquery.h" + +#include <locatorfilter.h> +#include <sourcelocationentry.h> + +namespace { + +using ClangBackEnd::SymbolKind; +using ClangBackEnd::SourceLocationKind; +using ClangRefactoring::Symbol; + +MATCHER_P2(HasNameAndSymbol, name, symbol, + std::string(negation ? "hasn't " : "has ") + + PrintToString(name) + + " and " + + PrintToString(symbol)) +{ + const Core::LocatorFilterEntry &entry = arg; + + return entry.displayName == QString::fromUtf8(name) && entry.internalData.value<Symbol>() == symbol; +} + +class LocatorFilter : public ::testing::Test +{ +protected: + static Core::LocatorFilterEntry createSymbolLocatorFilterEntry() + { + ClangRefactoring::Symbol symbol{42, "symbolName"}; + Core::LocatorFilterEntry entry; + entry.internalData = QVariant::fromValue(symbol); + + return entry; + } + +protected: + MockEditorManager mockEditorManager; + NiceMock<MockSymbolQuery> mockSymbolQuery; + ClangRefactoring::LocatorFilter filter{mockSymbolQuery, mockEditorManager, {SymbolKind::Record}, "", "", ""}; + Core::LocatorFilterEntry entry{createSymbolLocatorFilterEntry()}; + int start = 0; + int length = 0; + QString newText; + Utils::LineColumn lineColumn{4, 3}; + ClangBackEnd::FilePathId filePathId{42, 64}; + ClangRefactoring::SourceLocation sourceLocation{filePathId, lineColumn}; +}; + +TEST_F(LocatorFilter, MatchesForCallSymbols) +{ + QFutureInterface<Core::LocatorFilterEntry> dummy; + + EXPECT_CALL(mockSymbolQuery, symbols(ElementsAre(ClangBackEnd::SymbolKind::Record), Eq("search%Term%"))); + + filter.matchesFor(dummy, "search*Term"); +} + +TEST_F(LocatorFilter, MatchesForReturnsLocatorFilterEntries) +{ + ClangRefactoring::Symbols symbols{{12, "Foo", "class Foo final : public Bar"}, + {22, "Poo", "class Poo final : public Bar"}}; + ON_CALL(mockSymbolQuery, symbols(ElementsAre(ClangBackEnd::SymbolKind::Record), Eq("search%Term%"))) + .WillByDefault(Return(symbols)); + QFutureInterface<Core::LocatorFilterEntry> dummy; + + auto entries = filter.matchesFor(dummy, "search*Term"); + + ASSERT_THAT(entries, + ElementsAre( + HasNameAndSymbol("Foo", symbols[0]), + HasNameAndSymbol("Poo", symbols[1]))); +} + +TEST_F(LocatorFilter, AcceptDontCallsLocationAndOpensEditorIfItGetInvalidResultFromDatabase) +{ + InSequence s; + + EXPECT_CALL(mockSymbolQuery, locationForSymbolId(42, SourceLocationKind::Definition)) + .WillOnce(Return(Utils::optional<ClangRefactoring::SourceLocation>{})); + EXPECT_CALL(mockEditorManager, openEditorAt(Eq(filePathId), Eq(lineColumn))).Times(0); + + filter.accept(entry, &newText, &start, &length); +} + +TEST_F(LocatorFilter, AcceptCallsLocationAndOpensEditor) +{ + InSequence s; + + EXPECT_CALL(mockSymbolQuery, locationForSymbolId(42, SourceLocationKind::Definition)) + .WillOnce(Return(sourceLocation)); + EXPECT_CALL(mockEditorManager, openEditorAt(Eq(filePathId), Eq(lineColumn))); + + filter.accept(entry, &newText, &start, &length); +} + +} diff --git a/tests/unit/unittest/matchingtext-test.cpp b/tests/unit/unittest/matchingtext-test.cpp index c07bfec49a9..081e356764e 100644 --- a/tests/unit/unittest/matchingtext-test.cpp +++ b/tests/unit/unittest/matchingtext-test.cpp @@ -256,6 +256,34 @@ TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeNestedName ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); } +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeClass) +{ + const Document document("class X @"); + + ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeStruct) +{ + const Document document("struct X @"); + + ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeEnum) +{ + const Document document("enum X @"); + + ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + +TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotBeforeUnion) +{ + const Document document("union X @"); + + ASSERT_FALSE(MT::contextAllowsAutoParentheses(document.cursor, "{")); +} + TEST_F(MatchingText, ContextAllowsAutoParentheses_CurlyBrace_NotWithinString) { const Document document("\"a@b\""); diff --git a/tests/unit/unittest/mockeditormanager.h b/tests/unit/unittest/mockeditormanager.h new file mode 100644 index 00000000000..25ead76e9b3 --- /dev/null +++ b/tests/unit/unittest/mockeditormanager.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#pragma once + +#include "googletest.h" + +#include <editormanagerinterface.h> + +namespace Core { +class IEditor {}; +} + +class MockEditorManager final : public ClangRefactoring::EditorManagerInterface +{ +public: + MOCK_METHOD2(openEditorAt, + Core::IEditor*(ClangBackEnd::FilePathId filePathId, Utils::LineColumn lineColumn)); + +}; + diff --git a/tests/unit/unittest/mockpchmanagernotifier.h b/tests/unit/unittest/mockpchmanagernotifier.h index 961d383caef..985dc3c1449 100644 --- a/tests/unit/unittest/mockpchmanagernotifier.h +++ b/tests/unit/unittest/mockpchmanagernotifier.h @@ -32,12 +32,12 @@ class MockPchManagerNotifier : public ClangPchManager::PchManagerNotifierInterface { public: - MockPchManagerNotifier(ClangPchManager::PchManagerClient &pchManagerClient) - : ClangPchManager::PchManagerNotifierInterface(pchManagerClient) + MockPchManagerNotifier(const ClangPchManager::PchManagerClient &pchManagerClient) + : ClangPchManager::PchManagerNotifierInterface(const_cast<ClangPchManager::PchManagerClient&>(pchManagerClient)) {} - MOCK_METHOD2(precompiledHeaderUpdated, - void (const QString &projectPartId, const QString &pchFilePath)); + MOCK_METHOD3(precompiledHeaderUpdated, + void (const QString &projectPartId, const QString &pchFilePath, long long lastModified)); MOCK_METHOD1(precompiledHeaderRemoved, void (const QString &projectPartId)); }; diff --git a/tests/unit/unittest/mockpchmanagerserver.h b/tests/unit/unittest/mockpchmanagerserver.h index f5c703afd1a..766abd95ab6 100644 --- a/tests/unit/unittest/mockpchmanagerserver.h +++ b/tests/unit/unittest/mockpchmanagerserver.h @@ -34,18 +34,18 @@ class MockPchManagerServer : public ClangBackEnd::PchManagerServerInterface public: MOCK_METHOD0(end, void()); - MOCK_METHOD1(updatePchProjectParts, - void (const ClangBackEnd::UpdatePchProjectPartsMessage&)); - MOCK_METHOD1(removePchProjectParts, - void (const ClangBackEnd::RemovePchProjectPartsMessage&)); + MOCK_METHOD1(updateProjectParts, + void (const ClangBackEnd::UpdateProjectPartsMessage&)); + MOCK_METHOD1(removeProjectParts, + void (const ClangBackEnd::RemoveProjectPartsMessage&)); - void updatePchProjectParts(ClangBackEnd::UpdatePchProjectPartsMessage &&message) override + void updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage &&message) override { - updatePchProjectParts(message); + updateProjectParts(message); } - void removePchProjectParts(ClangBackEnd::RemovePchProjectPartsMessage &&message) override + void removeProjectParts(ClangBackEnd::RemoveProjectPartsMessage &&message) override { - removePchProjectParts(message); + removeProjectParts(message); } }; diff --git a/tests/unit/unittest/mockprecompiledheaderstorage.h b/tests/unit/unittest/mockprecompiledheaderstorage.h new file mode 100644 index 00000000000..60ba3525842 --- /dev/null +++ b/tests/unit/unittest/mockprecompiledheaderstorage.h @@ -0,0 +1,41 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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. +** +****************************************************************************/ + +#pragma once + +#include "googletest.h" + +#include <precompiledheaderstorageinterface.h> + +class MockPrecompiledHeaderStorage : public ClangPchManager::PrecompiledHeaderStorageInterface +{ +public: + MOCK_METHOD3(insertPrecompiledHeader, + void (Utils::SmallStringView projectPartName, + Utils::SmallStringView pchPath, + long long pchBuildTime)); + + MOCK_METHOD1(deletePrecompiledHeader, void (Utils::SmallStringView projectPartName)); +}; diff --git a/tests/unit/unittest/mockprojectpartprovider.h b/tests/unit/unittest/mockprojectpartprovider.h new file mode 100644 index 00000000000..1bde9e082fd --- /dev/null +++ b/tests/unit/unittest/mockprojectpartprovider.h @@ -0,0 +1,39 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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. +** +****************************************************************************/ + +#pragma once + +#include "googletest.h" + +#include <projectpartproviderinterface.h> + +class MockProjectPartProvider : public ClangRefactoring::ProjectPartProviderInterface +{ +public: + MOCK_CONST_METHOD0(generatedFiles, + ClangBackEnd::V2::FileContainers()); + MOCK_CONST_METHOD1(projectPart, + CppTools::ProjectPart*(const QString &projectPartId)); +}; diff --git a/tests/unit/unittest/mockrefactoringserver.h b/tests/unit/unittest/mockrefactoringserver.h index c265f88cbcf..091807e2031 100644 --- a/tests/unit/unittest/mockrefactoringserver.h +++ b/tests/unit/unittest/mockrefactoringserver.h @@ -44,11 +44,11 @@ public: MOCK_METHOD1(requestSourceRangesForQueryMessage, void (const ClangBackEnd::RequestSourceRangesForQueryMessage&)); - MOCK_METHOD1(updatePchProjectParts, - void (const ClangBackEnd::UpdatePchProjectPartsMessage&)); + MOCK_METHOD1(updateProjectParts, + void (const ClangBackEnd::UpdateProjectPartsMessage&)); - MOCK_METHOD1(removePchProjectParts, - void (const ClangBackEnd::RemovePchProjectPartsMessage&)); + MOCK_METHOD1(removeProjectParts, + void (const ClangBackEnd::RemoveProjectPartsMessage&)); MOCK_METHOD0(cancel, void()); @@ -68,13 +68,13 @@ public: requestSourceRangesForQueryMessage(message); } - void updatePchProjectParts(ClangBackEnd::UpdatePchProjectPartsMessage &&message) override + void updateProjectParts(ClangBackEnd::UpdateProjectPartsMessage &&message) override { - updatePchProjectParts(message); + updateProjectParts(message); } - void removePchProjectParts(ClangBackEnd::RemovePchProjectPartsMessage &&message) override + void removeProjectParts(ClangBackEnd::RemoveProjectPartsMessage &&message) override { - removePchProjectParts(message); + removeProjectParts(message); } }; diff --git a/tests/unit/unittest/mocksqlitedatabase.h b/tests/unit/unittest/mocksqlitedatabase.h index ce903c5b626..36fb370e707 100644 --- a/tests/unit/unittest/mocksqlitedatabase.h +++ b/tests/unit/unittest/mocksqlitedatabase.h @@ -27,31 +27,28 @@ #include "googletest.h" -#include "mockmutex.h" +#include "mocksqlitereadstatement.h" +#include "mocksqlitetransactionbackend.h" +#include "mocksqlitewritestatement.h" #include <sqlitetable.h> +#include <sqlitetransaction.h> #include <utils/smallstringview.h> -class MockSqliteDatabase +class MockSqliteDatabase : public MockSqliteTransactionBackend { public: - using MutexType = MockMutex; - - MockSqliteDatabase() = default; - MockSqliteDatabase(const MockMutex &mockMutex) - { - ON_CALL(*this, databaseMutex()) - .WillByDefault(ReturnRef(const_cast<MockMutex &>(mockMutex))); - } + using ReadStatement = MockSqliteReadStatement; + using WriteStatement = MockSqliteWriteStatement; MOCK_METHOD1(execute, void (Utils::SmallStringView sqlStatement)); - MOCK_METHOD0(databaseMutex, - MockMutex &()); - MOCK_CONST_METHOD0(lastInsertedRowId, int64_t ()); + + MOCK_CONST_METHOD1(setLastInsertedRowId, + void (int64_t)); }; diff --git a/tests/unit/unittest/mocksqlitereadstatement.cpp b/tests/unit/unittest/mocksqlitereadstatement.cpp index 1848fea3b26..eb114e3a47a 100644 --- a/tests/unit/unittest/mocksqlitereadstatement.cpp +++ b/tests/unit/unittest/mocksqlitereadstatement.cpp @@ -47,6 +47,41 @@ MockSqliteReadStatement::values<CppTools::Usage, 3>( } template <> +Symbols +MockSqliteReadStatement::values<Symbol, 3>( + std::size_t reserveSize, + const int &symbolKind, + const Utils::SmallStringView &searchTerm) +{ + return valuesReturnSymbols(reserveSize, symbolKind, searchTerm); +} + +template <> +Symbols +MockSqliteReadStatement::values<Symbol, 3>( + std::size_t reserveSize, + const int &symbolKind1, + const int &symbolKind2, + const Utils::SmallStringView &searchTerm) +{ + return valuesReturnSymbols(reserveSize, symbolKind1, symbolKind2, searchTerm); + +} + +template <> +Symbols +MockSqliteReadStatement::values<Symbol, 3>( + std::size_t reserveSize, + const int &symbolKind1, + const int &symbolKind2, + const int &symbolKind3, + const Utils::SmallStringView &searchTerm) +{ + return valuesReturnSymbols(reserveSize, symbolKind1, symbolKind2, symbolKind3, searchTerm); + +} + +template <> std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize) { return valuesReturnStdVectorDirectory(reserveSize); @@ -67,12 +102,26 @@ MockSqliteReadStatement::value<int>(const Utils::SmallStringView &text) template <> Utils::optional<int> +MockSqliteReadStatement::value<int>(const Utils::PathString &text) +{ + return valueReturnInt32(text); +} + +template <> +Utils::optional<int> MockSqliteReadStatement::value<int>(const int &directoryId, const Utils::SmallStringView &text) { return valueReturnInt32(directoryId, text); } template <> +Utils::optional<long long> +MockSqliteReadStatement::value<long long>(const int &sourceId) +{ + return valueReturnInt64(sourceId); +} + +template <> Utils::optional<Utils::PathString> MockSqliteReadStatement::value<Utils::PathString>(const int &directoryId) { @@ -80,8 +129,36 @@ MockSqliteReadStatement::value<Utils::PathString>(const int &directoryId) } template <> +Utils::optional<ClangBackEnd::ProjectPartArtefact> +MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int& sourceId) +{ + return valueReturnProjectPartArtefact(sourceId); +} + +template <> +Utils::optional<ClangBackEnd::ProjectPartArtefact> +MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const Utils::SmallStringView &projectPartName) +{ + return valueReturnProjectPartArtefact(projectPartName); +} + +template <> +Utils::optional<ClangBackEnd::ProjectPartPch> +MockSqliteReadStatement::value<ClangBackEnd::ProjectPartPch, 2>(const int &projectPartId) +{ + return valueReturnProjectPartPch(projectPartId); +} + +template <> Utils::optional<Utils::SmallString> MockSqliteReadStatement::value<Utils::SmallString>(const int &sourceId) { return valueReturnSmallString(sourceId); } + +template <> +Utils::optional<SourceLocation> +MockSqliteReadStatement::value<SourceLocation, 4>(const long long &symbolId, const int &locationKind) +{ + return valueReturnSourceLocation(symbolId, locationKind); +} diff --git a/tests/unit/unittest/mocksqlitereadstatement.h b/tests/unit/unittest/mocksqlitereadstatement.h index ccec595455b..2ad17ee07f2 100644 --- a/tests/unit/unittest/mocksqlitereadstatement.h +++ b/tests/unit/unittest/mocksqlitereadstatement.h @@ -25,12 +25,15 @@ #pragma once -#include "mocksqlitedatabase.h" +#include "googletest.h" #include <sourcelocations.h> #include <filepathstoragesources.h> #include <stringcachefwd.h> +#include <projectpartartefact.h> +#include <projectpartpch.h> +#include <symbol.h> #include <cpptools/usages.h> @@ -45,6 +48,10 @@ using std::int64_t; using ClangRefactoring::SourceLocation; using ClangRefactoring::SourceLocations; namespace Sources = ClangBackEnd::Sources; +using ClangRefactoring::Symbol; +using ClangRefactoring::Symbols; + +class MockSqliteDatabase; class MockSqliteReadStatement { @@ -72,12 +79,36 @@ public: MOCK_METHOD2(valueReturnInt32, Utils::optional<int>(int, Utils::SmallStringView)); + MOCK_METHOD1(valueReturnInt64, + Utils::optional<long long>(int)); + MOCK_METHOD1(valueReturnPathString, Utils::optional<Utils::PathString>(int)); MOCK_METHOD1(valueReturnSmallString, Utils::optional<Utils::SmallString>(int)); + MOCK_METHOD1(valueReturnProjectPartArtefact, + Utils::optional<ClangBackEnd::ProjectPartArtefact>(int)); + + MOCK_METHOD1(valueReturnProjectPartArtefact, + Utils::optional<ClangBackEnd::ProjectPartArtefact>(Utils::SmallStringView)); + + MOCK_METHOD1(valueReturnProjectPartPch, + Utils::optional<ClangBackEnd::ProjectPartPch>(int)); + + MOCK_METHOD3(valuesReturnSymbols, + Symbols(std::size_t, int, Utils::SmallStringView)); + + MOCK_METHOD4(valuesReturnSymbols, + Symbols(std::size_t, int, int, Utils::SmallStringView)); + + MOCK_METHOD5(valuesReturnSymbols, + Symbols(std::size_t, int, int, int, Utils::SmallStringView)); + + MOCK_METHOD2(valueReturnSourceLocation, + SourceLocation(long long, int)); + template <typename ResultType, int ResultTypeCount = 1, typename... QueryType> @@ -96,6 +127,7 @@ public: const QueryContainerType<QueryElementType> &queryValues); template <typename ResultType, + int ResultTypeCount = 1, typename... QueryTypes> Utils::optional<ResultType> value(const QueryTypes&... queryValues); @@ -120,6 +152,30 @@ MockSqliteReadStatement::values<CppTools::Usage, 3>( const int &column); template <> +Symbols +MockSqliteReadStatement::values<Symbol, 3>( + std::size_t reserveSize, + const int&, + const Utils::SmallStringView&); + +template <> +Symbols +MockSqliteReadStatement::values<Symbol, 3>( + std::size_t reserveSize, + const int&, + const int&, + const Utils::SmallStringView&); + +template <> +Symbols +MockSqliteReadStatement::values<Symbol, 3>( + std::size_t reserveSize, + const int&, + const int&, + const int&, + const Utils::SmallStringView&); + +template <> std::vector<Sources::Directory> MockSqliteReadStatement::values<Sources::Directory, 2>(std::size_t reserveSize); template <> @@ -131,12 +187,36 @@ MockSqliteReadStatement::value<int>(const Utils::SmallStringView&); template <> Utils::optional<int> +MockSqliteReadStatement::value<int>(const Utils::PathString&); + +template <> +Utils::optional<int> MockSqliteReadStatement::value<int>(const int&, const Utils::SmallStringView&); template <> +Utils::optional<long long> +MockSqliteReadStatement::value<long long>(const ClangBackEnd::FilePathId&); + +template <> Utils::optional<Utils::PathString> MockSqliteReadStatement::value<Utils::PathString>(const int&); template <> +Utils::optional<ClangBackEnd::ProjectPartArtefact> +MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int&); + +template <> +Utils::optional<ClangBackEnd::ProjectPartArtefact> +MockSqliteReadStatement::value<ClangBackEnd::ProjectPartArtefact, 4>(const int&); + +template <> +Utils::optional<ClangBackEnd::ProjectPartPch> +MockSqliteReadStatement::value<ClangBackEnd::ProjectPartPch, 2>(const int&); + +template <> Utils::optional<Utils::SmallString> MockSqliteReadStatement::value<Utils::SmallString>(const int&); + +template <> +Utils::optional<SourceLocation> +MockSqliteReadStatement::value<SourceLocation, 4>(const long long &symbolId, const int &locationKind); diff --git a/tests/unit/unittest/mocksqlitestatement.h b/tests/unit/unittest/mocksqlitestatement.h index ab919b9f4e2..26f5b0de6e0 100644 --- a/tests/unit/unittest/mocksqlitestatement.h +++ b/tests/unit/unittest/mocksqlitestatement.h @@ -35,7 +35,6 @@ class BaseMockSqliteStatement public: MOCK_METHOD0(next, bool ()); MOCK_METHOD0(step, void ()); - MOCK_METHOD0(execute, void ()); MOCK_METHOD0(reset, void ()); MOCK_CONST_METHOD1(fetchIntValue, int (int)); @@ -53,6 +52,7 @@ public: MOCK_METHOD2(bind, void (int, double)); MOCK_METHOD2(bind, void (int, Utils::SmallStringView)); MOCK_METHOD2(bind, void (int, long)); + MOCK_CONST_METHOD1(bindingIndexForName, int (Utils::SmallStringView name)); MOCK_METHOD1(prepare, void (Utils::SmallStringView sqlStatement)); }; diff --git a/tests/unit/unittest/mocksqlitetransactionbackend.h b/tests/unit/unittest/mocksqlitetransactionbackend.h new file mode 100644 index 00000000000..0cfeee2892d --- /dev/null +++ b/tests/unit/unittest/mocksqlitetransactionbackend.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** 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. +** +****************************************************************************/ + +#pragma once + + +#include "googletest.h" + +#include <sqlitetransaction.h> + +class MockSqliteTransactionBackend : public Sqlite::TransactionInterface +{ +public: + MOCK_METHOD0(deferredBegin, void ()); + MOCK_METHOD0(immediateBegin, void ()); + MOCK_METHOD0(exclusiveBegin, void ()); + MOCK_METHOD0(commit, void ()); + MOCK_METHOD0(rollback, void ()); + MOCK_METHOD0(lock, void ()); + MOCK_METHOD0(unlock, void ()); +}; diff --git a/tests/unit/unittest/mocksqlitewritestatement.h b/tests/unit/unittest/mocksqlitewritestatement.h index 159077c8060..05d2404d914 100644 --- a/tests/unit/unittest/mocksqlitewritestatement.h +++ b/tests/unit/unittest/mocksqlitewritestatement.h @@ -25,10 +25,12 @@ #pragma once -#include "mocksqlitedatabase.h" +#include "googletest.h" #include <utils/smallstring.h> +class MockSqliteDatabase; + class MockSqliteWriteStatement { public: @@ -46,17 +48,56 @@ public: MOCK_METHOD2(bindValues, void (Utils::SmallStringView, Utils::SmallStringView)); - MOCK_METHOD3(write, - void (uint, Utils::SmallStringView, Utils::SmallStringView)); + MOCK_METHOD4(write, + void (uint, Utils::SmallStringView, Utils::SmallStringView, uint)); MOCK_METHOD4(write, void (uint, uint, uint, uint)); + MOCK_METHOD4(write, + void (long long, int, int, int)); + + MOCK_METHOD5(write, + void (long long, int, int, int, int)); + MOCK_METHOD2(write, void (uint, Utils::SmallStringView)); + MOCK_METHOD2(write, + void (Utils::SmallStringView, Utils::SmallStringView)); + + MOCK_METHOD3(write, + void (Utils::SmallStringView, Utils::SmallStringView, long long)); + + MOCK_METHOD3(write, + void (Utils::SmallStringView, Utils::SmallStringView, Utils::SmallStringView)); + + MOCK_METHOD4(write, + void (Utils::SmallStringView, + Utils::SmallStringView, + Utils::SmallStringView, + Utils::SmallStringView)); + MOCK_METHOD1(write, void (Utils::SmallStringView)); + MOCK_METHOD1(write, + void (long long)); + + MOCK_METHOD1(write, + void (int)); + + MOCK_METHOD2(write, + void (int, int)); + + MOCK_METHOD3(write, + void (uint, uint, uint)); + + MOCK_METHOD4(write, + void (int, off_t, time_t, bool)); + + MOCK_METHOD2(write, + void (uint, uint)); + Utils::SmallString sqlStatement; }; diff --git a/tests/unit/unittest/mocksymbolquery.h b/tests/unit/unittest/mocksymbolquery.h index 25543b2b751..0b3f4d59843 100644 --- a/tests/unit/unittest/mocksymbolquery.h +++ b/tests/unit/unittest/mocksymbolquery.h @@ -32,6 +32,12 @@ class MockSymbolQuery : public ClangRefactoring::SymbolQueryInterface { public: - MOCK_CONST_METHOD3(locationsAt, ClangRefactoring::SourceLocations(ClangBackEnd::FilePathId filePathId, int line, int utf8Column)); - MOCK_CONST_METHOD3(sourceUsagesAt, CppTools::Usages(ClangBackEnd::FilePathId filePathId, int line, int utf8Column)); + MOCK_CONST_METHOD3(locationsAt, + ClangRefactoring::SourceLocations(ClangBackEnd::FilePathId filePathId, int line, int utf8Column)); + MOCK_CONST_METHOD3(sourceUsagesAt, + CppTools::Usages(ClangBackEnd::FilePathId filePathId, int line, int utf8Column)); + MOCK_CONST_METHOD2(symbols, + ClangRefactoring::Symbols(const ClangBackEnd::SymbolKinds &symbolKinds, Utils::SmallStringView searchTerm)); + MOCK_CONST_METHOD2(locationForSymbolId, + Utils::optional<ClangRefactoring::SourceLocation>(ClangRefactoring::SymbolId symbolId, ClangBackEnd::SourceLocationKind kind)); }; diff --git a/tests/unit/unittest/mocksymbolscollector.h b/tests/unit/unittest/mocksymbolscollector.h index 2c332dc1a83..9d8edb4bc30 100644 --- a/tests/unit/unittest/mocksymbolscollector.h +++ b/tests/unit/unittest/mocksymbolscollector.h @@ -36,7 +36,7 @@ public: void()); MOCK_METHOD2(addFiles, - void(const Utils::PathStringVector &filePaths, + void(const ClangBackEnd::FilePathIds &filePathIds, const Utils::SmallStringVector &arguments)); MOCK_METHOD1(addUnsavedFiles, @@ -53,4 +53,13 @@ public: MOCK_CONST_METHOD0(sourceFiles, const ClangBackEnd::FilePathIds &()); + + MOCK_CONST_METHOD0(usedMacros, + const ClangBackEnd::UsedMacros &()); + + MOCK_CONST_METHOD0(fileStatuses, + const ClangBackEnd::FileStatuses &()); + + MOCK_CONST_METHOD0(sourceDependencies, + const ClangBackEnd::SourceDependencies &()); }; diff --git a/tests/unit/unittest/mocksymbolstorage.h b/tests/unit/unittest/mocksymbolstorage.h index 84bf012f8ae..90142fe9ee1 100644 --- a/tests/unit/unittest/mocksymbolstorage.h +++ b/tests/unit/unittest/mocksymbolstorage.h @@ -27,6 +27,8 @@ #include "googletest.h" +#include "mocksqlitedatabase.h" + #include <symbolstorageinterface.h> class MockSymbolStorage : public ClangBackEnd::SymbolStorageInterface @@ -35,4 +37,29 @@ public: MOCK_METHOD2(addSymbolsAndSourceLocations, void(const ClangBackEnd::SymbolEntries &symbolEentries, const ClangBackEnd::SourceLocationEntries &sourceLocations)); + MOCK_METHOD4(insertOrUpdateProjectPart, + void(Utils::SmallStringView projectPartName, + const Utils::SmallStringVector &commandLineArgument, + const ClangBackEnd::CompilerMacros &compilerMacros, + const Utils::SmallStringVector &includeSearchPaths)); + MOCK_METHOD2(updateProjectPartSources, + void(Utils::SmallStringView projectPartName, + const ClangBackEnd::FilePathIds &sourceFilePathIds)); + MOCK_METHOD2(updateProjectPartSources, + void(int projectPartId, + const ClangBackEnd::FilePathIds &sourceFilePathIds)); + MOCK_METHOD1(insertOrUpdateUsedMacros, + void (const ClangBackEnd::UsedMacros &usedMacros)); + MOCK_METHOD1(insertFileStatuses, + void (const ClangBackEnd::FileStatuses &fileStatuses)); + MOCK_METHOD1(insertOrUpdateSourceDependencies, + void (const ClangBackEnd::SourceDependencies &sourceDependencies)); + MOCK_CONST_METHOD1(fetchProjectPartArtefact, + Utils::optional<ClangBackEnd::ProjectPartArtefact> (ClangBackEnd::FilePathId sourceId)); + MOCK_CONST_METHOD1(fetchProjectPartArtefact, + Utils::optional<ClangBackEnd::ProjectPartArtefact> (Utils::SmallStringView projectPartName)); + MOCK_CONST_METHOD1(fetchLowestLastModifiedTime, + long long (ClangBackEnd::FilePathId sourceId)); + MOCK_CONST_METHOD1(fetchPrecompiledHeader, + Utils::optional<ClangBackEnd::ProjectPartPch> (int projectPartId)); }; diff --git a/tests/unit/unittest/pchcreator-test.cpp b/tests/unit/unittest/pchcreator-test.cpp index b1812ddc368..f5990593f21 100644 --- a/tests/unit/unittest/pchcreator-test.cpp +++ b/tests/unit/unittest/pchcreator-test.cpp @@ -26,13 +26,17 @@ #include "googletest.h" #include "fakeprocess.h" -#include "mockfilepathcaching.h" + #include "mockpchgeneratornotifier.h" #include "testenvironment.h" +#include <refactoringdatabaseinitializer.h> +#include <filepathcaching.h> #include <pchcreator.h> #include <pchgenerator.h> +#include <sqlitedatabase.h> + #include <QFileInfo> namespace { @@ -43,6 +47,7 @@ using ClangBackEnd::ProjectPartPch; using ClangBackEnd::V2::ProjectPartContainer; using ClangBackEnd::V2::FileContainer; using ClangBackEnd::FilePath; +using ClangBackEnd::FilePathIds; using ClangBackEnd::FilePathView; using Utils::PathString; @@ -53,11 +58,15 @@ using UnitTests::EndsWith; class PchCreator: public ::testing::Test { protected: - void SetUp(); - ClangBackEnd::FilePathId id(Utils::SmallStringView path); + ClangBackEnd::FilePathId id(ClangBackEnd::FilePathView path) + { + return filePathCache.filePathId(path); + } protected: - NiceMock<MockFilePathCaching> filePathCache; + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; FilePath main1Path = TESTDATA_DIR "/includecollector_main3.cpp"; FilePath main2Path = TESTDATA_DIR "/includecollector_main2.cpp"; FilePath header1Path = TESTDATA_DIR "/includecollector_header1.h"; @@ -66,12 +75,16 @@ protected: FilePath generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h"; ProjectPartContainer projectPart1{"project1", {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, - {header1Path}, - {main1Path}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {id(header1Path)}, + {id(main1Path)}}; ProjectPartContainer projectPart2{"project2", {"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"}, - {header2Path}, - {main2Path}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {id(header2Path)}, + {id(main2Path)}}; TestEnvironment environment; FileContainer generatedFile{{TESTDATA_DIR, generatedFileName}, "#pragma once", {}}; NiceMock<MockPchGeneratorNotifier> mockPchGeneratorNotifier; @@ -203,19 +216,27 @@ TEST_F(PchCreator, CreateProjectPartHeaderAndSources) TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludes) { + using IncludePair = decltype(creator.generateProjectPartPchIncludes(projectPart1)); + auto includeIds = creator.generateProjectPartPchIncludes(projectPart1); ASSERT_THAT(includeIds, - AllOf(Contains(id(TESTDATA_DIR "/includecollector_external1.h")), - Contains(id(TESTDATA_DIR "/includecollector_external2.h")), - Contains(id(TESTDATA_DIR "/includecollector_header2.h")))); + AllOf( + Field(&IncludePair::first, + AllOf(Contains(id(TESTDATA_DIR "/includecollector_external1.h")), + Contains(id(TESTDATA_DIR "/includecollector_external2.h")), + Contains(id(TESTDATA_DIR "/includecollector_header2.h")))), + Field(&IncludePair::second, + AllOf(Contains(id(TESTDATA_DIR "/includecollector_external1.h")), + Contains(id(TESTDATA_DIR "/includecollector_external2.h")))))); } TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent) { - auto includes = creator.generateProjectPartPchIncludes(projectPart1); + FilePathIds topExternalIncludes; + std::tie(std::ignore, topExternalIncludes) = creator.generateProjectPartPchIncludes(projectPart1); - auto content = creator.generatePchIncludeFileContent(includes); + auto content = creator.generatePchIncludeFileContent(topExternalIncludes); ASSERT_THAT(std::string(content), AllOf(HasSubstr("#include \"" TESTDATA_DIR "/includecollector_header2.h\"\n"), @@ -225,8 +246,9 @@ TEST_F(PchCreatorSlowTest, CreateProjectPartPchFileContent) TEST_F(PchCreatorSlowTest, CreateProjectPartPchIncludeFile) { - auto includeIds = creator.generateProjectPartPchIncludes(projectPart1); - auto content = creator.generatePchIncludeFileContent(includeIds); + FilePathIds topExternalIncludes; + std::tie(std::ignore, topExternalIncludes) = creator.generateProjectPartPchIncludes(projectPart1); + auto content = creator.generatePchIncludeFileContent(topExternalIncludes); auto pchIncludeFilePath = creator.generateProjectPathPchHeaderFilePath(projectPart1); auto file = creator.generateFileWithContent(pchIncludeFilePath, content); file->open(QIODevice::ReadOnly); @@ -280,7 +302,7 @@ TEST_F(PchCreatorVerySlowTest, DISABLED_CreatePartPchs) auto includePaths = creator.generateProjectPartPch(projectPart1); - ASSERT_THAT(includePaths.id, projectPart1.projectPartId()); + ASSERT_THAT(includePaths.id, projectPart1.projectPartId); ASSERT_THAT(includePaths.filePathIds, AllOf(Contains(FilePathId{1, 1}), Contains(FilePathId{1, 2}), @@ -300,10 +322,10 @@ TEST_F(PchCreatorVerySlowTest, ProjectPartPchsForCreatePchsForProjectParts) { EXPECT_CALL(mockPchGeneratorNotifier, taskFinished(ClangBackEnd::TaskFinishStatus::Successfully, - Property(&ProjectPartPch::id, "project1"))); + Field(&ProjectPartPch::projectPartId, "project1"))); EXPECT_CALL(mockPchGeneratorNotifier, taskFinished(ClangBackEnd::TaskFinishStatus::Successfully, - Property(&ProjectPartPch::id, "project2"))); + Field(&ProjectPartPch::projectPartId, "project2"))); creator.generatePchs(); } @@ -332,32 +354,5 @@ TEST_F(PchCreator, CreateProjectPartHeaderAndSourcesContent) "#include \"" TESTDATA_DIR "/includecollector_main3.cpp\"\n")); } -void PchCreator::SetUp() -{ - ON_CALL(filePathCache, filePathId(Eq(FilePathView{TESTDATA_DIR "/includecollector_external1.h"}))) - .WillByDefault(Return(FilePathId{1, 1})); - ON_CALL(filePathCache, filePathId(Eq(FilePathView{TESTDATA_DIR "/includecollector_external2.h"}))) - .WillByDefault(Return(FilePathId{1, 2})); - ON_CALL(filePathCache, filePathId(Eq(FilePathView{TESTDATA_DIR "/includecollector_external3.h"}))) - .WillByDefault(Return(FilePathId{1, 3})); - ON_CALL(filePathCache, filePathId(Eq(header1Path))) - .WillByDefault(Return(FilePathId{1, 4})); - ON_CALL(filePathCache, filePathId(Eq(header2Path))) - .WillByDefault(Return(FilePathId{1, 5})); - ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 1}))) - .WillByDefault(Return(FilePath{TESTDATA_DIR "/includecollector_external1.h"})); - ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 2}))) - .WillByDefault(Return(FilePath{TESTDATA_DIR "/includecollector_external2.h"})); - ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 3}))) - .WillByDefault(Return(FilePath{TESTDATA_DIR "/includecollector_external3.h"})); - ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 4}))) - .WillByDefault(Return(FilePath{header1Path})); - ON_CALL(filePathCache, filePath(Eq(FilePathId{1, 5}))) - .WillByDefault(Return(FilePath{header2Path})); -} -ClangBackEnd::FilePathId PchCreator::id(Utils::SmallStringView path) -{ - return filePathCache.filePathId(ClangBackEnd::FilePathView(path)); -} } diff --git a/tests/unit/unittest/pchgenerator-test.cpp b/tests/unit/unittest/pchgenerator-test.cpp index d7b1980064c..2bce237833c 100644 --- a/tests/unit/unittest/pchgenerator-test.cpp +++ b/tests/unit/unittest/pchgenerator-test.cpp @@ -61,7 +61,7 @@ protected: NiceMock<MockPchGeneratorNotifier> mockNotifier; ClangBackEnd::PchGenerator<FakeProcess> generator{environment, &mockNotifier}; Utils::SmallStringVector compilerArguments = {"-DXXXX", "-Ifoo"}; - ClangBackEnd::ProjectPartPch projectPartPch{"projectPartId", "/path/to/pch"}; + ClangBackEnd::ProjectPartPch projectPartPch{"projectPartId", "/path/to/pch", 1}; }; TEST_F(PchGenerator, ProcessFinished) diff --git a/tests/unit/unittest/pchmanagerclient-test.cpp b/tests/unit/unittest/pchmanagerclient-test.cpp index 53a544841d6..9e40a21249d 100644 --- a/tests/unit/unittest/pchmanagerclient-test.cpp +++ b/tests/unit/unittest/pchmanagerclient-test.cpp @@ -27,13 +27,16 @@ #include "mockpchmanagernotifier.h" #include "mockpchmanagerserver.h" +#include "mockprecompiledheaderstorage.h" #include <pchmanagerclient.h> #include <pchmanagerprojectupdater.h> +#include <filepathcaching.h> +#include <refactoringdatabaseinitializer.h> #include <precompiledheadersupdatedmessage.h> -#include <removepchprojectpartsmessage.h> -#include <updatepchprojectpartsmessage.h> +#include <removeprojectpartsmessage.h> +#include <updateprojectpartsmessage.h> namespace { @@ -46,13 +49,20 @@ using testing::Not; class PchManagerClient : public ::testing::Test { protected: - MockPchManagerServer mockPchManagerServer; - ClangPchManager::PchManagerClient client; - MockPchManagerNotifier mockPchManagerNotifier{client}; - ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer, client}; + NiceMock<MockPchManagerServer> mockPchManagerServer; + NiceMock<MockPrecompiledHeaderStorage> mockPrecompiledHeaderStorage; + ClangPchManager::PchManagerClient client{mockPrecompiledHeaderStorage}; + NiceMock<MockPchManagerNotifier> mockPchManagerNotifier{client}; + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; + ClangPchManager::PchManagerProjectUpdater projectUpdater{mockPchManagerServer, client, filePathCache}; Utils::SmallString projectPartId{"projectPartId"}; Utils::SmallString pchFilePath{"/path/to/pch"}; - PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone()}}}; + PrecompiledHeadersUpdatedMessage message{{{projectPartId.clone(), pchFilePath.clone(), 1}}}; + Utils::SmallString projectPartId2{"projectPartId2"}; + Utils::SmallString pchFilePath2{"/path/to/pch2"}; + PrecompiledHeadersUpdatedMessage message2{{{projectPartId2.clone(), pchFilePath2.clone(), 1}}}; }; TEST_F(PchManagerClient, NotifierAttached) @@ -76,7 +86,7 @@ TEST_F(PchManagerClient, NotifierDetached) TEST_F(PchManagerClient, Update) { - EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderUpdated(projectPartId.toQString(), pchFilePath.toQString())); + EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderUpdated(projectPartId.toQString(), pchFilePath.toQString(), Eq(1))); client.precompiledHeadersUpdated(message.clone()); } @@ -90,4 +100,75 @@ TEST_F(PchManagerClient, Remove) QString(projectPartId.clone())}); } +TEST_F(PchManagerClient, GetNoProjectPartPchForWrongProjectPartId) +{ + auto optional = client.projectPartPch("foo"); + + ASSERT_FALSE(optional); +} + +TEST_F(PchManagerClient, GetProjectPartPchForProjectPartId) +{ + client.precompiledHeadersUpdated(std::move(message)); + + auto optional = client.projectPartPch(projectPartId); + + ASSERT_TRUE(optional); +} + +TEST_F(PchManagerClient, ProjectPartPchRemoved) +{ + client.precompiledHeadersUpdated(std::move(message)); + + client.precompiledHeaderRemoved(QString(projectPartId)); + + ASSERT_FALSE(client.projectPartPch(projectPartId)); +} + +TEST_F(PchManagerClient, ProjectPartPchHasNoDublicateEntries) +{ + client.precompiledHeadersUpdated(message.clone()); + client.precompiledHeadersUpdated(message2.clone()); + + client.precompiledHeadersUpdated(message.clone()); + + ASSERT_THAT(client.projectPartPchs(), SizeIs(2)); +} + +TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdLastModified) +{ + client.precompiledHeadersUpdated(std::move(message)); + + ASSERT_THAT(client.projectPartPch(projectPartId).value().lastModified, + 1); +} + +TEST_F(PchManagerClient, ProjectPartPchForProjectPartIdIsUpdated) +{ + client.precompiledHeadersUpdated(message.clone()); + PrecompiledHeadersUpdatedMessage updateMessage{{{projectPartId.clone(), pchFilePath.clone(), 42}}}; + + client.precompiledHeadersUpdated(updateMessage.clone()); + + ASSERT_THAT(client.projectPartPch(projectPartId).value().lastModified, + 42); +} + +TEST_F(PchManagerClient, ProjectPartPchAddedToDatabase) +{ + EXPECT_CALL(mockPrecompiledHeaderStorage, insertPrecompiledHeader(TypedEq<Utils::SmallStringView>(projectPartId), + TypedEq<Utils::SmallStringView>(pchFilePath), + TypedEq<long long>(1))); + + client.precompiledHeadersUpdated(message.clone()); +} + +TEST_F(PchManagerClient, ProjectPartPchRemovedFromDatabase) +{ + EXPECT_CALL(mockPrecompiledHeaderStorage, deletePrecompiledHeader(TypedEq<Utils::SmallStringView>(projectPartId))); + + + projectUpdater.removeProjectParts({QString(projectPartId)}); +} + } diff --git a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp index ed2ced23111..f37fe2ae5e0 100644 --- a/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp +++ b/tests/unit/unittest/pchmanagerclientserverinprocess-test.cpp @@ -32,8 +32,8 @@ #include <pchmanagerclientproxy.h> #include <pchmanagerserverproxy.h> #include <precompiledheadersupdatedmessage.h> -#include <removepchprojectpartsmessage.h> -#include <updatepchprojectpartsmessage.h> +#include <removeprojectpartsmessage.h> +#include <updateprojectpartsmessage.h> #include <QBuffer> #include <QString> @@ -41,10 +41,10 @@ #include <vector> -using ClangBackEnd::UpdatePchProjectPartsMessage; +using ClangBackEnd::UpdateProjectPartsMessage; using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::ProjectPartContainer; -using ClangBackEnd::RemovePchProjectPartsMessage; +using ClangBackEnd::RemoveProjectPartsMessage; using ClangBackEnd::PrecompiledHeadersUpdatedMessage; using ::testing::Args; @@ -90,34 +90,36 @@ TEST_F(PchManagerClientServerInProcess, SendAliveMessage) scheduleClientMessages(); } -TEST_F(PchManagerClientServerInProcess, SendUpdatePchProjectPartsMessage) +TEST_F(PchManagerClientServerInProcess, SendUpdateProjectPartsMessage) { ProjectPartContainer projectPart2{"projectPartId", {"-x", "c++-header", "-Wno-pragma-once-outside-header"}, - {TESTDATA_DIR "/includecollector_header.h"}, - {TESTDATA_DIR "/includecollector_main.cpp"}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {{1, 1}}, + {{1, 2}}}; FileContainer fileContainer{{"/path/to/", "file"}, "content", {}}; - UpdatePchProjectPartsMessage message{{projectPart2}, {fileContainer}}; + UpdateProjectPartsMessage message{{projectPart2}, {fileContainer}}; - EXPECT_CALL(mockPchManagerServer, updatePchProjectParts(message)); + EXPECT_CALL(mockPchManagerServer, updateProjectParts(message)); - serverProxy.updatePchProjectParts(message.clone()); + serverProxy.updateProjectParts(message.clone()); scheduleServerMessages(); } -TEST_F(PchManagerClientServerInProcess, SendRemovePchProjectPartsMessage) +TEST_F(PchManagerClientServerInProcess, SendRemoveProjectPartsMessage) { - RemovePchProjectPartsMessage message{{"projectPartId1", "projectPartId2"}}; + RemoveProjectPartsMessage message{{"projectPartId1", "projectPartId2"}}; - EXPECT_CALL(mockPchManagerServer, removePchProjectParts(message)); + EXPECT_CALL(mockPchManagerServer, removeProjectParts(message)); - serverProxy.removePchProjectParts(message.clone()); + serverProxy.removeProjectParts(message.clone()); scheduleServerMessages(); } TEST_F(PchManagerClientServerInProcess, SendPrecompiledHeaderUpdatedMessage) { - PrecompiledHeadersUpdatedMessage message{{{"projectPartId", "/path/to/pch"}}}; + PrecompiledHeadersUpdatedMessage message{{{"projectPartId", "/path/to/pch", 1}}}; EXPECT_CALL(mockPchManagerClient, precompiledHeadersUpdated(message)); diff --git a/tests/unit/unittest/pchmanagerserver-test.cpp b/tests/unit/unittest/pchmanagerserver-test.cpp index a01facb02cb..995045d0ff0 100644 --- a/tests/unit/unittest/pchmanagerserver-test.cpp +++ b/tests/unit/unittest/pchmanagerserver-test.cpp @@ -30,21 +30,14 @@ #include "mockpchcreator.h" #include "mockprojectparts.h" +#include <filepathcaching.h> #include <pchmanagerserver.h> #include <precompiledheadersupdatedmessage.h> -#include <removepchprojectpartsmessage.h> -#include <updatepchprojectpartsmessage.h> +#include <refactoringdatabaseinitializer.h> +#include <removeprojectpartsmessage.h> +#include <updateprojectpartsmessage.h> namespace { - -using testing::ElementsAre; -using testing::UnorderedElementsAre; -using testing::ByMove; -using testing::NiceMock; -using testing::Return; -using testing::_; -using testing::IsEmpty; - using Utils::PathString; using Utils::SmallString; using ClangBackEnd::V2::FileContainer; @@ -54,12 +47,18 @@ using ClangBackEnd::TaskFinishStatus; class PchManagerServer : public ::testing::Test { void SetUp() override; + ClangBackEnd::FilePathId id(Utils::SmallStringView path) const + { + return filePathCache.filePathId(ClangBackEnd::FilePathView(path)); + } protected: NiceMock<MockPchCreator> mockPchCreator; NiceMock<MockClangPathWatcher> mockClangPathWatcher; NiceMock<MockProjectParts> mockProjectParts; - + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; ClangBackEnd::PchManagerServer server{mockClangPathWatcher, mockPchCreator, mockProjectParts}; NiceMock<MockPchManagerClient> mockPchManagerClient; SmallString projectPartId1 = "project1"; @@ -71,23 +70,27 @@ protected: std::vector<ClangBackEnd::IdPaths> idPaths = {{projectPartId1, {{1, 1}, {1, 2}}}}; ProjectPartContainer projectPart1{projectPartId1.clone(), {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, - {header1Path.clone()}, - {main1Path.clone()}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {id(header1Path)}, + {id(main1Path)}}; ProjectPartContainer projectPart2{projectPartId2.clone(), {"-x", "c++-header", "-Wno-pragma-once-outside-header"}, - {header2Path.clone()}, - {main2Path.clone()}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {id(header2Path)}, + {id(main2Path)}}; std::vector<ProjectPartContainer> projectParts{projectPart1, projectPart2}; FileContainer generatedFile{{"/path/to/", "file"}, "content", {}}; - ClangBackEnd::UpdatePchProjectPartsMessage updatePchProjectPartsMessage{Utils::clone(projectParts), + ClangBackEnd::UpdateProjectPartsMessage UpdateProjectPartsMessage{Utils::clone(projectParts), {generatedFile}}; - ClangBackEnd::ProjectPartPch projectPartPch1{projectPart1.projectPartId().clone(), "/path1/to/pch"}; - ClangBackEnd::ProjectPartPch projectPartPch2{projectPart2.projectPartId().clone(), "/path2/to/pch"}; + ClangBackEnd::ProjectPartPch projectPartPch1{projectPart1.projectPartId.clone(), "/path1/to/pch", 1}; + ClangBackEnd::ProjectPartPch projectPartPch2{projectPart2.projectPartId.clone(), "/path2/to/pch", 1}; std::vector<ClangBackEnd::ProjectPartPch> projectPartPchs{projectPartPch1, projectPartPch2}; ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage1{{projectPartPch1}}; ClangBackEnd::PrecompiledHeadersUpdatedMessage precompiledHeaderUpdatedMessage2{{projectPartPch2}}; - ClangBackEnd::RemovePchProjectPartsMessage removePchProjectPartsMessage{{projectPart1.projectPartId().clone(), - projectPart2.projectPartId().clone()}}; + ClangBackEnd::RemoveProjectPartsMessage RemoveProjectPartsMessage{{projectPart1.projectPartId.clone(), + projectPart2.projectPartId.clone()}}; }; TEST_F(PchManagerServer, CallPrecompiledHeadersForSuccessfullyFinishedTask) @@ -108,39 +111,39 @@ TEST_F(PchManagerServer, DoNotCallPrecompiledHeadersForUnsuccessfullyFinishedTas TEST_F(PchManagerServer, CallBuildInPchCreator) { auto &&callSetGeneratedFiles = EXPECT_CALL(mockPchCreator, - setGeneratedFiles(updatePchProjectPartsMessage.generatedFiles())); - EXPECT_CALL(mockPchCreator, generatePchs(updatePchProjectPartsMessage.projectsParts())) + setGeneratedFiles(UpdateProjectPartsMessage.generatedFiles)); + EXPECT_CALL(mockPchCreator, generatePchs(UpdateProjectPartsMessage.projectsParts)) .After(callSetGeneratedFiles); - server.updatePchProjectParts(updatePchProjectPartsMessage.clone()); + server.updateProjectParts(UpdateProjectPartsMessage.clone()); } TEST_F(PchManagerServer, UpdateIncludesOfFileWatcher) { EXPECT_CALL(mockClangPathWatcher, updateIdPaths(idPaths)); - server.updatePchProjectParts(updatePchProjectPartsMessage.clone()); + server.updateProjectParts(UpdateProjectPartsMessage.clone()); } TEST_F(PchManagerServer, GetChangedProjectPartsFromProjectParts) { EXPECT_CALL(mockProjectParts, update(_)); - server.updatePchProjectParts(updatePchProjectPartsMessage.clone()); + server.updateProjectParts(UpdateProjectPartsMessage.clone()); } TEST_F(PchManagerServer, RemoveIncludesFromFileWatcher) { - EXPECT_CALL(mockClangPathWatcher, removeIds(removePchProjectPartsMessage.projectsPartIds())); + EXPECT_CALL(mockClangPathWatcher, removeIds(RemoveProjectPartsMessage.projectsPartIds)); - server.removePchProjectParts(removePchProjectPartsMessage.clone()); + server.removeProjectParts(RemoveProjectPartsMessage.clone()); } TEST_F(PchManagerServer, RemoveProjectPartsFromProjectParts) { - EXPECT_CALL(mockProjectParts, remove(removePchProjectPartsMessage.projectsPartIds())); + EXPECT_CALL(mockProjectParts, remove(RemoveProjectPartsMessage.projectsPartIds)); - server.removePchProjectParts(removePchProjectPartsMessage.clone()); + server.removeProjectParts(RemoveProjectPartsMessage.clone()); } TEST_F(PchManagerServer, SetPathWatcherNotifier) @@ -152,16 +155,16 @@ TEST_F(PchManagerServer, SetPathWatcherNotifier) TEST_F(PchManagerServer, CallProjectsInProjectPartsForIncludeChange) { - server.updatePchProjectParts(updatePchProjectPartsMessage.clone()); + server.updateProjectParts(UpdateProjectPartsMessage.clone()); - EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId()))); + EXPECT_CALL(mockProjectParts, projects(ElementsAre(projectPart1.projectPartId))); server.pathsWithIdsChanged({projectPartId1}); } TEST_F(PchManagerServer, CallGeneratePchsInPchCreatorForIncludeChange) { - server.updatePchProjectParts(updatePchProjectPartsMessage.clone()); + server.updateProjectParts(UpdateProjectPartsMessage.clone()); EXPECT_CALL(mockPchCreator, generatePchs(ElementsAre(projectPart1))); @@ -170,7 +173,7 @@ TEST_F(PchManagerServer, CallGeneratePchsInPchCreatorForIncludeChange) TEST_F(PchManagerServer, CallUpdateIdPathsInFileSystemWatcherForIncludeChange) { - server.updatePchProjectParts(updatePchProjectPartsMessage.clone()); + server.updateProjectParts(UpdateProjectPartsMessage.clone()); EXPECT_CALL(mockClangPathWatcher, updateIdPaths(idPaths)); diff --git a/tests/unit/unittest/precompiledheaderstorage-test.cpp b/tests/unit/unittest/precompiledheaderstorage-test.cpp new file mode 100644 index 00000000000..86f46156cf1 --- /dev/null +++ b/tests/unit/unittest/precompiledheaderstorage-test.cpp @@ -0,0 +1,139 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 "mocksqlitedatabase.h" + +#include <precompiledheaderstorage.h> +#include <refactoringdatabaseinitializer.h> +#include <sqlitedatabase.h> +#include <sqlitewritestatement.h> +#include <sqlitetransaction.h> + +namespace { + +using Storage = ClangPchManager::PrecompiledHeaderStorage<NiceMock<MockSqliteDatabase>>; + +class PrecompiledHeaderStorage : public testing::Test +{ +protected: + NiceMock<MockSqliteDatabase> database; + Storage storage{database}; + MockSqliteWriteStatement &insertPrecompiledHeaderStatement = storage.m_insertPrecompiledHeaderStatement; + MockSqliteWriteStatement &insertProjectPartStatement = storage.m_insertProjectPartStatement; + MockSqliteWriteStatement &deletePrecompiledHeaderStatement = storage.m_deletePrecompiledHeaderStatement; +}; + +TEST_F(PrecompiledHeaderStorage, UseTransaction) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(database, commit()); + + Storage storage{database}; +} + +TEST_F(PrecompiledHeaderStorage, InsertPrecompiledHeader) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(insertProjectPartStatement, write(TypedEq<Utils::SmallStringView>("project1"))); + EXPECT_CALL(insertPrecompiledHeaderStatement, + write(TypedEq<Utils::SmallStringView>("project1"), + TypedEq<Utils::SmallStringView>("/path/to/pch"), + TypedEq<long long>(22))); + EXPECT_CALL(database, commit()); + + storage.insertPrecompiledHeader("project1", "/path/to/pch", 22); +} + +TEST_F(PrecompiledHeaderStorage, InsertPrecompiledHeaderStatementIsBusy) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(insertProjectPartStatement, write(TypedEq<Utils::SmallStringView>("project1"))); + EXPECT_CALL(insertPrecompiledHeaderStatement, + write(TypedEq<Utils::SmallStringView>("project1"), + TypedEq<Utils::SmallStringView>("/path/to/pch"), + TypedEq<long long>(22))); + EXPECT_CALL(database, commit()); + + storage.insertPrecompiledHeader("project1", "/path/to/pch", 22); +} + +TEST_F(PrecompiledHeaderStorage, DeletePrecompiledHeader) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(deletePrecompiledHeaderStatement, write(TypedEq<Utils::SmallStringView>("project1"))); + EXPECT_CALL(database, commit()); + + storage.deletePrecompiledHeader("project1"); +} + +TEST_F(PrecompiledHeaderStorage, DeletePrecompiledHeaderStatementIsBusy) +{ + InSequence s; + + EXPECT_CALL(database, immediateBegin()).WillOnce(Throw(Sqlite::StatementIsBusy("busy"))); + EXPECT_CALL(database, immediateBegin()); + EXPECT_CALL(deletePrecompiledHeaderStatement, write(TypedEq<Utils::SmallStringView>("project1"))); + EXPECT_CALL(database, commit()); + + storage.deletePrecompiledHeader("project1"); +} + +TEST_F(PrecompiledHeaderStorage, InsertPrecompiledHeaderStatement) +{ + ASSERT_THAT(insertPrecompiledHeaderStatement.sqlStatement, + Eq("INSERT OR REPLACE INTO precompiledHeaders(projectPartId, pchPath, pchBuildTime) VALUES((SELECT projectPartId FROM projectParts WHERE projectPartName = ?),?,?)")); +} + +TEST_F(PrecompiledHeaderStorage, InsertProjectPartStatement) +{ + ASSERT_THAT(insertProjectPartStatement.sqlStatement, + Eq("INSERT OR IGNORE INTO projectParts(projectPartName) VALUES (?)")); +} + +TEST_F(PrecompiledHeaderStorage, DeletePrecompiledHeaderStatement) +{ + ASSERT_THAT(deletePrecompiledHeaderStatement.sqlStatement, + Eq("DELETE FROM precompiledHeaders WHERE projectPartId = (SELECT projectPartId FROM projectParts WHERE projectPartName = ?)")); +} + +TEST_F(PrecompiledHeaderStorage, CompilePrecompiledHeaderStatements) +{ + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database}; + + ASSERT_NO_THROW(ClangPchManager::PrecompiledHeaderStorage<>{database}); +} + +} diff --git a/tests/unit/unittest/projectpart-test.cpp b/tests/unit/unittest/projectpart-test.cpp index 3b515be5e7f..f1e40299389 100644 --- a/tests/unit/unittest/projectpart-test.cpp +++ b/tests/unit/unittest/projectpart-test.cpp @@ -104,8 +104,8 @@ TEST(ProjectPart, AddProjectParts) projects.createOrUpdate({projectContainer}); - ASSERT_THAT(projects.project(projectContainer.projectPartId()), ClangBackEnd::ProjectPart(projectContainer)); - ASSERT_THAT(projects.project(projectContainer.projectPartId()).arguments(), ElementsAre(Utf8StringLiteral("-O"))); + ASSERT_THAT(projects.project(projectContainer.projectPartId), ClangBackEnd::ProjectPart(projectContainer)); + ASSERT_THAT(projects.project(projectContainer.projectPartId).arguments(), ElementsAre(Utf8StringLiteral("-O"))); } TEST(ProjectPart, UpdateProjectParts) @@ -117,8 +117,8 @@ TEST(ProjectPart, UpdateProjectParts) projects.createOrUpdate({projectContainerWithNewArguments}); - ASSERT_THAT(projects.project(projectContainer.projectPartId()), ClangBackEnd::ProjectPart(projectContainer)); - ASSERT_THAT(projects.project(projectContainer.projectPartId()).arguments(), ElementsAre(Utf8StringLiteral("-fast"))); + ASSERT_THAT(projects.project(projectContainer.projectPartId), ClangBackEnd::ProjectPart(projectContainer)); + ASSERT_THAT(projects.project(projectContainer.projectPartId).arguments(), ElementsAre(Utf8StringLiteral("-fast"))); } TEST(ProjectPart, ThrowExceptionForAccesingRemovedProjectParts) @@ -127,9 +127,9 @@ TEST(ProjectPart, ThrowExceptionForAccesingRemovedProjectParts) ClangBackEnd::ProjectParts projects; projects.createOrUpdate({projectContainer}); - projects.remove({projectContainer.projectPartId()}); + projects.remove({projectContainer.projectPartId}); - ASSERT_THROW(projects.project(projectContainer.projectPartId()), ClangBackEnd::ProjectPartDoNotExistException); + ASSERT_THROW(projects.project(projectContainer.projectPartId), ClangBackEnd::ProjectPartDoNotExistException); } TEST(ProjectPart, ProjectPartProjectPartIdIsEmptyfterRemoving) @@ -137,9 +137,9 @@ TEST(ProjectPart, ProjectPartProjectPartIdIsEmptyfterRemoving) ClangBackEnd::ProjectPartContainer projectContainer(Utf8StringLiteral("pathToProjectPart.pro"), {Utf8StringLiteral("-O")}); ClangBackEnd::ProjectParts projects; projects.createOrUpdate({projectContainer}); - ClangBackEnd::ProjectPart project(projects.project(projectContainer.projectPartId())); + ClangBackEnd::ProjectPart project(projects.project(projectContainer.projectPartId)); - projects.remove({projectContainer.projectPartId()}); + projects.remove({projectContainer.projectPartId}); ASSERT_TRUE(project.id().isEmpty()); } @@ -151,7 +151,7 @@ TEST(ProjectPart, ThrowsForNotExistingProjectPartButRemovesAllExistingProject) projects.createOrUpdate({projectContainer}); ClangBackEnd::ProjectPart project = *projects.findProjectPart(Utf8StringLiteral("pathToProjectPart.pro")); - EXPECT_THROW(projects.remove({Utf8StringLiteral("doesnotexist.pro"), projectContainer.projectPartId()}), ClangBackEnd::ProjectPartDoNotExistException); + EXPECT_THROW(projects.remove({Utf8StringLiteral("doesnotexist.pro"), projectContainer.projectPartId}), ClangBackEnd::ProjectPartDoNotExistException); ASSERT_THAT(projects.projects(), Not(Contains(project))); } @@ -161,11 +161,11 @@ TEST(ProjectPart, ProjectPartIsClearedAfterRemove) ClangBackEnd::ProjectPartContainer projectContainer(Utf8StringLiteral("pathToProjectPart.pro")); ClangBackEnd::ProjectParts projects; projects.createOrUpdate({projectContainer}); - ClangBackEnd::ProjectPart project = *projects.findProjectPart(projectContainer.projectPartId()); + ClangBackEnd::ProjectPart project = *projects.findProjectPart(projectContainer.projectPartId); const auto lastChangeTimePoint = project.lastChangeTimePoint(); std::this_thread::sleep_for(ClangBackEnd::Duration(1)); - projects.remove({projectContainer.projectPartId()}); + projects.remove({projectContainer.projectPartId}); ASSERT_THAT(project.id(), Utf8String()); ASSERT_THAT(project.arguments().count(), 0); @@ -178,7 +178,7 @@ TEST(ProjectPart, HasProjectPart) ClangBackEnd::ProjectParts projects; projects.createOrUpdate({projectContainer}); - ASSERT_TRUE(projects.hasProjectPart(projectContainer.projectPartId())); + ASSERT_TRUE(projects.hasProjectPart(projectContainer.projectPartId)); } TEST(ProjectPart, DoNotHasProjectPart) @@ -190,5 +190,4 @@ TEST(ProjectPart, DoNotHasProjectPart) ASSERT_FALSE(projects.hasProjectPart(Utf8StringLiteral("doesnotexist.pro"))); } - } diff --git a/tests/unit/unittest/projectpartartefact-test.cpp b/tests/unit/unittest/projectpartartefact-test.cpp new file mode 100644 index 00000000000..065af771a76 --- /dev/null +++ b/tests/unit/unittest/projectpartartefact-test.cpp @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 <projectpartartefact.h> + +namespace { + +using ClangBackEnd::CompilerMacro; + +TEST(ProjectPartArtefact, CompilerArguments) +{ + ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFoo\",\"-DBar\"]", "", "", 1}; + + ASSERT_THAT(artefact.compilerArguments, ElementsAre(Eq("-DFoo"), Eq("-DBar"))); +} + +TEST(ProjectPartArtefact, EmptyCompilerArguments) +{ + ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1}; + + ASSERT_THAT(artefact.compilerArguments, IsEmpty()); +} + +TEST(ProjectPartArtefact, CompilerArgumentsParseError) +{ + ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("\"-DFoo\",\"-DBar\"]", "", "", 1), + ClangBackEnd::ProjectPartArtefactParseError); +} + +TEST(ProjectPartArtefact, CompilerMacros) +{ + ClangBackEnd::ProjectPartArtefact artefact{"", "{\"Foo\":\"1\",\"Bar\":\"42\"}", "", 1}; + + ASSERT_THAT(artefact.compilerMacros, + UnorderedElementsAre(Eq(CompilerMacro{"Foo", "1"}), Eq(CompilerMacro{"Bar", "42"}))); +} + +TEST(ProjectPartArtefact, EmptyCompilerMacros) +{ + ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1}; + + ASSERT_THAT(artefact.compilerMacros, IsEmpty()); +} + +TEST(ProjectPartArtefact, CompilerMacrosParseError) +{ + ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", "\"Foo\":\"1\",\"Bar\":\"42\"}", "", 1), + ClangBackEnd::ProjectPartArtefactParseError); +} + +TEST(ProjectPartArtefact, IncludeSearchPaths) +{ + ClangBackEnd::ProjectPartArtefact artefact{"", "", "[\"/includes\",\"/other/includes\"]", 1}; + + ASSERT_THAT(artefact.includeSearchPaths, ElementsAre(Eq("/includes"), Eq("/other/includes"))); +} + +TEST(ProjectPartArtefact, EmptyIncludeSearchPaths) +{ + ClangBackEnd::ProjectPartArtefact artefact{"", "", "", 1}; + + ASSERT_THAT(artefact.includeSearchPaths, IsEmpty()); +} + +TEST(ProjectPartArtefact, IncludeSearchPathsParseError) +{ + ASSERT_THROW(ClangBackEnd::ProjectPartArtefact("", "", "\"/includes\",\"/other/includes\"]", 1), + ClangBackEnd::ProjectPartArtefactParseError); +} + +} diff --git a/tests/unit/unittest/projectparts-test.cpp b/tests/unit/unittest/projectparts-test.cpp index e8680dbcccc..50b838ca501 100644 --- a/tests/unit/unittest/projectparts-test.cpp +++ b/tests/unit/unittest/projectparts-test.cpp @@ -36,23 +36,35 @@ using testing::UnorderedElementsAre; using testing::IsEmpty; using ClangBackEnd::V2::ProjectPartContainer; +using ClangBackEnd::FilePathId; class ProjectParts : public testing::Test { protected: ClangBackEnd::ProjectParts projectParts; + FilePathId firstHeader{1, 1}; + FilePathId secondHeader{1, 2}; + FilePathId firstSource{1, 11}; + FilePathId secondSource{1, 12}; + FilePathId thirdSource{1, 13}; ProjectPartContainer projectPartContainer1{"id", {"-DUNIX", "-O2"}, - {"headers1.h", "header2.h"}, - {"source1.cpp", "source2.cpp"}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {firstHeader, secondHeader}, + {firstSource, secondSource}}; ProjectPartContainer updatedProjectPartContainer1{"id", {"-DUNIX", "-O2"}, - {"headers1.h", "header2.h"}, - {"source1.cpp", "source2.cpp", "source3.cpp" }}; + {{"DEFINE", "1"}}, + {"/includes"}, + {firstHeader, secondHeader}, + {firstSource, secondSource, thirdSource}}; ProjectPartContainer projectPartContainer2{"id2", {"-DUNIX", "-O2"}, - {"headers1.h", "header2.h"}, - {"source1.cpp", "source2.cpp"}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {firstHeader, secondHeader}, + {firstSource, secondSource}}; }; TEST_F(ProjectParts, GetNoProjectPartsForAddingEmptyProjectParts) @@ -162,7 +174,7 @@ TEST_F(ProjectParts, Remove) { projectParts.update({projectPartContainer1, projectPartContainer2}); - projectParts.remove({projectPartContainer1.projectPartId()}); + projectParts.remove({projectPartContainer1.projectPartId}); ASSERT_THAT(projectParts.projectParts(), ElementsAre(projectPartContainer2)); } @@ -171,7 +183,7 @@ TEST_F(ProjectParts, GetProjectById) { projectParts.update({projectPartContainer1, projectPartContainer2}); - auto projectPartContainers = projectParts.projects({projectPartContainer1.projectPartId()}); + auto projectPartContainers = projectParts.projects({projectPartContainer1.projectPartId}); ASSERT_THAT(projectPartContainers, ElementsAre(projectPartContainer1)); } @@ -181,7 +193,7 @@ TEST_F(ProjectParts, GetProjectsByIds) { projectParts.update({projectPartContainer1, projectPartContainer2}); - auto projectPartContainers = projectParts.projects({projectPartContainer1.projectPartId(), projectPartContainer2.projectPartId()}); + auto projectPartContainers = projectParts.projects({projectPartContainer1.projectPartId, projectPartContainer2.projectPartId}); ASSERT_THAT(projectPartContainers, UnorderedElementsAre(projectPartContainer1, projectPartContainer2)); } diff --git a/tests/unit/unittest/projectupdater-test.cpp b/tests/unit/unittest/projectupdater-test.cpp index 0589115901f..a77dfc0b5b9 100644 --- a/tests/unit/unittest/projectupdater-test.cpp +++ b/tests/unit/unittest/projectupdater-test.cpp @@ -28,17 +28,23 @@ #include "mockpchmanagerclient.h" #include "mockpchmanagernotifier.h" #include "mockpchmanagerserver.h" +#include "mockprecompiledheaderstorage.h" #include <pchmanagerprojectupdater.h> +#include <filepathcaching.h> #include <pchmanagerclient.h> +#include <precompiledheaderstorage.h> #include <precompiledheadersupdatedmessage.h> -#include <removepchprojectpartsmessage.h> -#include <updatepchprojectpartsmessage.h> +#include <refactoringdatabaseinitializer.h> +#include <removeprojectpartsmessage.h> +#include <updateprojectpartsmessage.h> #include <cpptools/compileroptionsbuilder.h> #include <cpptools/projectpart.h> +#include <utils/algorithm.h> + namespace { using testing::_; @@ -47,24 +53,62 @@ using testing::SizeIs; using testing::NiceMock; using testing::AnyNumber; +using ClangBackEnd::CompilerMacro; using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::ProjectPartContainer; using CppTools::CompilerOptionsBuilder; +using CppTools::ProjectPartHeaderPath; class ProjectUpdater : public testing::Test { protected: - void SetUp() override; + ClangBackEnd::FilePathId filePathId(Utils::SmallStringView path) + { + return filePathCache.filePathId(ClangBackEnd::FilePathView{path}); + } + + ClangBackEnd::FilePathIds filePathIds(const Utils::PathStringVector &paths) + { + return filePathCache.filePathIds(Utils::transform(paths, [] (const Utils::PathString &path) { + return ClangBackEnd::FilePathView(path); + })); + } + + void SetUp() override + { + projectPart.files.push_back(header1ProjectFile); + projectPart.files.push_back(header2ProjectFile); + projectPart.files.push_back(source1ProjectFile); + projectPart.files.push_back(source2ProjectFile); + projectPart.displayName = QString(projectPartId); + projectPart.projectMacros.push_back({"DEFINE", "1"}); + + + Utils::SmallStringVector arguments{ClangPchManager::ProjectUpdater::compilerArguments( + &projectPart)}; + + expectedContainer = {projectPartId.clone(), + arguments.clone(), + Utils::clone(compilerMacros), + {}, + {filePathId(headerPaths[1])}, + {filePathIds(sourcePaths)}}; + } protected: - ClangPchManager::PchManagerClient pchManagerClient; + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; + MockPrecompiledHeaderStorage mockPrecompiledHeaderStorage; + ClangPchManager::PchManagerClient pchManagerClient{mockPrecompiledHeaderStorage}; MockPchManagerNotifier mockPchManagerNotifier{pchManagerClient}; NiceMock<MockPchManagerServer> mockPchManagerServer; - ClangPchManager::ProjectUpdater updater{mockPchManagerServer}; + ClangPchManager::ProjectUpdater updater{mockPchManagerServer, filePathCache}; Utils::SmallString projectPartId{"project1"}; Utils::SmallString projectPartId2{"project2"}; Utils::PathStringVector headerPaths = {"/path/to/header1.h", "/path/to/header2.h"}; Utils::PathStringVector sourcePaths = {"/path/to/source1.cpp", "/path/to/source2.cpp"}; + ClangBackEnd::CompilerMacros compilerMacros = {{"DEFINE", "1"}}; CppTools::ProjectFile header1ProjectFile{QString(headerPaths[0]), CppTools::ProjectFile::CXXHeader}; CppTools::ProjectFile header2ProjectFile{QString(headerPaths[1]), CppTools::ProjectFile::CXXHeader}; CppTools::ProjectFile source1ProjectFile{QString(sourcePaths[0]), CppTools::ProjectFile::CXXSource}; @@ -74,31 +118,30 @@ protected: FileContainer generatedFile{{"/path/to", "header1.h"}, "content", {}}; }; -TEST_F(ProjectUpdater, CallUpdatePchProjectParts) +TEST_F(ProjectUpdater, CallUpdateProjectParts) { std::vector<CppTools::ProjectPart*> projectParts = {&projectPart, &projectPart}; - ClangBackEnd::UpdatePchProjectPartsMessage message{{expectedContainer.clone(), expectedContainer.clone()}, - {generatedFile}}; + ClangBackEnd::UpdateProjectPartsMessage message{{expectedContainer.clone(), expectedContainer.clone()}, + {generatedFile}}; - EXPECT_CALL(mockPchManagerServer, updatePchProjectParts(message)); + EXPECT_CALL(mockPchManagerServer, updateProjectParts(message)); updater.updateProjectParts(projectParts, {generatedFile}); } -TEST_F(ProjectUpdater, CallRemovePchProjectParts) +TEST_F(ProjectUpdater, CallRemoveProjectParts) { + ClangBackEnd::RemoveProjectPartsMessage message{{projectPartId, projectPartId2}}; - ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}}; - - EXPECT_CALL(mockPchManagerServer, removePchProjectParts(message)); + EXPECT_CALL(mockPchManagerServer, removeProjectParts(message)); updater.removeProjectParts({QString(projectPartId), QString(projectPartId2)}); } TEST_F(ProjectUpdater, CallPrecompiledHeaderRemovedInPchManagerProjectUpdater) { - ClangPchManager::PchManagerProjectUpdater pchUpdater{mockPchManagerServer, pchManagerClient}; - ClangBackEnd::RemovePchProjectPartsMessage message{{projectPartId, projectPartId2}}; + ClangPchManager::PchManagerProjectUpdater pchUpdater{mockPchManagerServer, pchManagerClient, filePathCache}; + ClangBackEnd::RemoveProjectPartsMessage message{{projectPartId, projectPartId2}}; EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId.toQString())); EXPECT_CALL(mockPchManagerNotifier, precompiledHeaderRemoved(projectPartId2.toQString())); @@ -129,21 +172,23 @@ TEST_F(ProjectUpdater, CreateExcludedPaths) ASSERT_THAT(excludedPaths, ElementsAre("/path/to/header1.h")); } -void ProjectUpdater::SetUp() +TEST_F(ProjectUpdater, CreateCompilerMacros) { - projectPart.files.push_back(header1ProjectFile); - projectPart.files.push_back(header2ProjectFile); - projectPart.files.push_back(source1ProjectFile); - projectPart.files.push_back(source2ProjectFile); - projectPart.displayName = QString(projectPartId); - - Utils::SmallStringVector arguments{ClangPchManager::ProjectUpdater::compilerArguments( - &projectPart)}; - - expectedContainer = {projectPartId.clone(), - arguments.clone(), - {headerPaths[1]}, - sourcePaths.clone()}; + auto paths = updater.createCompilerMacros({{"DEFINE", "1"}}); + + ASSERT_THAT(paths, ElementsAre(CompilerMacro{"DEFINE", "1"})); } + +TEST_F(ProjectUpdater, CreateIncludeSearchPaths) +{ + ProjectPartHeaderPath includePath{"/to/path", ProjectPartHeaderPath::IncludePath}; + ProjectPartHeaderPath invalidPath; + ProjectPartHeaderPath frameworkPath{"/framework/path", ProjectPartHeaderPath::FrameworkPath}; + + auto paths = updater.createIncludeSearchPaths({includePath, invalidPath, frameworkPath}); + + ASSERT_THAT(paths, ElementsAre(includePath.path, frameworkPath.path)); +} + } diff --git a/tests/unit/unittest/readandwritemessageblock-test.cpp b/tests/unit/unittest/readandwritemessageblock-test.cpp index 8f3d1e848c7..9a1bebb0788 100644 --- a/tests/unit/unittest/readandwritemessageblock-test.cpp +++ b/tests/unit/unittest/readandwritemessageblock-test.cpp @@ -122,6 +122,64 @@ TEST_F(ReadAndWriteMessageBlock, ReadThreeMessagesAndTestCount) ASSERT_THAT(readMessageBlock.readAll(), SizeIs(3)); } +TEST_F(ReadAndWriteMessageBlock, WriteMessagesToWriteBlockWithoutIoDeviceAndNoMessagesAreSent) +{ + ClangBackEnd::WriteMessageBlock writeMessageBlock; + + writeMessageBlock.write(ClangBackEnd::EndMessage()); + writeMessageBlock.write(ClangBackEnd::EndMessage()); + buffer.seek(0); + + ASSERT_THAT(readMessageBlock.readAll(), IsEmpty()); +} + +TEST_F(ReadAndWriteMessageBlock, WriteMessagesToWriteBlockWithoutIoDeviceAndSetIoDeviceToNullPointerLater) +{ + ClangBackEnd::WriteMessageBlock writeMessageBlock; + writeMessageBlock.write(ClangBackEnd::EndMessage()); + writeMessageBlock.write(ClangBackEnd::EndMessage()); + + writeMessageBlock.setIoDevice(nullptr); + buffer.seek(0); + + ASSERT_THAT(readMessageBlock.readAll(), IsEmpty()); +} + +TEST_F(ReadAndWriteMessageBlock, WriteMessagesToWriteBlockWithoutIoDeviceAndSetIoDeviceLater) +{ + ClangBackEnd::WriteMessageBlock writeMessageBlock; + writeMessageBlock.write(ClangBackEnd::EndMessage()); + writeMessageBlock.write(ClangBackEnd::EndMessage()); + + writeMessageBlock.setIoDevice(&buffer); + buffer.seek(0); + + ASSERT_THAT(readMessageBlock.readAll(), SizeIs(2)); +} + +TEST_F(ReadAndWriteMessageBlock, ResetStateResetsCounter) +{ + writeMessageBlock.write(ClangBackEnd::EndMessage()); + writeMessageBlock.write(ClangBackEnd::EndMessage()); + buffer.seek(0); + + writeMessageBlock.resetState(); + + ASSERT_THAT(writeMessageBlock.counter(), 0); +} + +TEST_F(ReadAndWriteMessageBlock, ResetStateResetsWritingBlock) +{ + ClangBackEnd::WriteMessageBlock writeMessageBlock; + writeMessageBlock.write(ClangBackEnd::EndMessage()); + + writeMessageBlock.resetState(); + + writeMessageBlock.setIoDevice(&buffer); + buffer.seek(0); + ASSERT_THAT(readMessageBlock.readAll(), IsEmpty()); +} + TEST_F(ReadAndWriteMessageBlock, CompareEndMessage) { CompareMessage(ClangBackEnd::EndMessage()); @@ -174,7 +232,9 @@ TEST_F(ReadAndWriteMessageBlock, CompareDocumentAnnotationsChangedMessage) {}, {}); - ClangBackEnd::TokenInfoContainer tokenInfo(1, 1, 1, ClangBackEnd::HighlightingType::Keyword); + ClangBackEnd::HighlightingTypes types; + types.mainHighlightingType = ClangBackEnd::HighlightingType::Keyword; + ClangBackEnd::TokenInfoContainer tokenInfo(1, 1, 1, types); CompareMessage(ClangBackEnd::DocumentAnnotationsChangedMessage(fileContainer, {diagnostic}, @@ -212,8 +272,8 @@ TEST_F(ReadAndWriteMessageBlock, CompareReferences) { const QVector<ClangBackEnd::SourceRangeContainer> references{ true, - {{fileContainer.filePath(), 12, 34}, - {fileContainer.filePath(), 56, 78}} + {{fileContainer.filePath, 12, 34}, + {fileContainer.filePath, 56, 78}} }; CompareMessage(ClangBackEnd::ReferencesMessage(fileContainer, references, true, 1)); } diff --git a/tests/unit/unittest/refactoringclient-test.cpp b/tests/unit/unittest/refactoringclient-test.cpp index 936b51a94e7..36ce0392219 100644 --- a/tests/unit/unittest/refactoringclient-test.cpp +++ b/tests/unit/unittest/refactoringclient-test.cpp @@ -96,9 +96,9 @@ TEST_F(RefactoringClient, SourceLocationsForRenaming) { client.setLocalRenamingCallback(mockLocalRenaming.AsStdFunction()); - EXPECT_CALL(mockLocalRenaming, Call(renameMessage.symbolName().toQString(), - renameMessage.sourceLocations(), - renameMessage.textDocumentRevision())); + EXPECT_CALL(mockLocalRenaming, Call(renameMessage.symbolName.toQString(), + renameMessage.sourceLocations, + renameMessage.textDocumentRevision)); client.sourceLocationsForRenamingMessage(std::move(renameMessage)); } diff --git a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp index f1ce7a9f5f1..a5658ab1788 100644 --- a/tests/unit/unittest/refactoringclientserverinprocess-test.cpp +++ b/tests/unit/unittest/refactoringclientserverinprocess-test.cpp @@ -47,10 +47,10 @@ using ::testing::Args; using ::testing::Property; using ::testing::Eq; -using ClangBackEnd::UpdatePchProjectPartsMessage; +using ClangBackEnd::UpdateProjectPartsMessage; using ClangBackEnd::V2::FileContainer; using ClangBackEnd::V2::ProjectPartContainer; -using ClangBackEnd::RemovePchProjectPartsMessage; +using ClangBackEnd::RemoveProjectPartsMessage; class RefactoringClientServerInProcess : public ::testing::Test { @@ -174,28 +174,30 @@ TEST_F(RefactoringClientServerInProcess, RequestSourceRangesForQueryMessage) scheduleServerMessages(); } -TEST_F(RefactoringClientServerInProcess, SendUpdatePchProjectPartsMessage) +TEST_F(RefactoringClientServerInProcess, SendUpdateProjectPartsMessage) { ProjectPartContainer projectPart2{"projectPartId", {"-x", "c++-header", "-Wno-pragma-once-outside-header"}, - {TESTDATA_DIR "/includecollector_header.h"}, - {TESTDATA_DIR "/includecollector_main.cpp"}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {{1, 1}}, + {{1, 2}}}; FileContainer fileContainer{{"/path/to/", "file"}, "content", {}}; - UpdatePchProjectPartsMessage message{{projectPart2}, {fileContainer}}; + UpdateProjectPartsMessage message{{projectPart2}, {fileContainer}}; - EXPECT_CALL(mockRefactoringServer, updatePchProjectParts(message)); + EXPECT_CALL(mockRefactoringServer, updateProjectParts(message)); - serverProxy.updatePchProjectParts(message.clone()); + serverProxy.updateProjectParts(message.clone()); scheduleServerMessages(); } -TEST_F(RefactoringClientServerInProcess, SendRemovePchProjectPartsMessage) +TEST_F(RefactoringClientServerInProcess, SendRemoveProjectPartsMessage) { - RemovePchProjectPartsMessage message{{"projectPartId1", "projectPartId2"}}; + RemoveProjectPartsMessage message{{"projectPartId1", "projectPartId2"}}; - EXPECT_CALL(mockRefactoringServer, removePchProjectParts(message)); + EXPECT_CALL(mockRefactoringServer, removeProjectParts(message)); - serverProxy.removePchProjectParts(message.clone()); + serverProxy.removeProjectParts(message.clone()); scheduleServerMessages(); } diff --git a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp index ab5691d4ec5..6b9257facf0 100644 --- a/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp +++ b/tests/unit/unittest/refactoringdatabaseinitializer-test.cpp @@ -38,8 +38,7 @@ using Sqlite::Table; class RefactoringDatabaseInitializer : public testing::Test { protected: - NiceMock<MockMutex> mockMutex; - NiceMock<MockSqliteDatabase> mockDatabase{mockMutex}; + NiceMock<MockSqliteDatabase> mockDatabase; Initializer initializer{mockDatabase}; }; @@ -47,8 +46,9 @@ TEST_F(RefactoringDatabaseInitializer, AddSymbolsTable) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT, symbolKind INTEGER, signature TEXT)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_symbolKind_symbolName ON symbols(symbolKind, symbolName)"))); initializer.createSymbolsTable(); } @@ -57,8 +57,9 @@ TEST_F(RefactoringDatabaseInitializer, AddLocationsTable) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_line_column ON locations(sourceId, line, column)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER, locationKind INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_locations_sourceId_line_column ON locations(sourceId, line, column)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON locations(sourceId, locationKind)"))); initializer.createLocationsTable(); } @@ -68,7 +69,7 @@ TEST_F(RefactoringDatabaseInitializer, AddSourcesTable) InSequence s; EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, directoryId INTEGER, sourceName TEXT, sourceType INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sources_sourceName ON sources(sourceName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_sources_directoryId_sourceName ON sources(directoryId, sourceName)"))); initializer.createSourcesTable(); } @@ -78,7 +79,7 @@ TEST_F(RefactoringDatabaseInitializer, AddDirectoriesTable) InSequence s; EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS directories(directoryId INTEGER PRIMARY KEY, directoryPath TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_directories_directoryPath ON directories(directoryPath)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_directories_directoryPath ON directories(directoryPath)"))); initializer.createDirectoriesTable(); } @@ -87,30 +88,90 @@ TEST_F(RefactoringDatabaseInitializer, AddProjectPartsTable) { InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT, compilerMacros TEXT, includeSearchPaths TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)"))); initializer.createProjectPartsTable(); } +TEST_F(RefactoringDatabaseInitializer, AddProjectPartsSourcesTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsSources_sourceId_projectPartId ON projectPartsSources(sourceId, projectPartId)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsSources_projectPartId ON projectPartsSources(projectPartId)"))); + + initializer.createProjectPartsSourcesTable(); +} + +TEST_F(RefactoringDatabaseInitializer, AddUsedMacrosTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, sourceId INTEGER, macroName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_sourceId_macroName ON usedMacros(sourceId, macroName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)"))); + + initializer.createUsedMacrosTable(); +} + +TEST_F(RefactoringDatabaseInitializer, AddFileStatusesTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, lastModified INTEGER, isInPrecompiledHeader INTEGER)"))); + + initializer.createFileStatusesTable(); +} + +TEST_F(RefactoringDatabaseInitializer, AddSourceDependenciesTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)"))); + + initializer.createSourceDependenciesTable(); +} + +TEST_F(RefactoringDatabaseInitializer, AddPrecompiledHeaderTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS precompiledHeaders(projectPartId INTEGER PRIMARY KEY, pchPath TEXT, pchBuildTime INTEGER)"))); + + initializer.createPrecompiledHeadersTable(); +} + TEST_F(RefactoringDatabaseInitializer, CreateInTheContructor) { InSequence s; - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, immediateBegin()); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS symbols(symbolId INTEGER PRIMARY KEY, usr TEXT, symbolName TEXT, symbolKind INTEGER, signature TEXT)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_usr ON symbols(usr)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_line_column ON locations(sourceId, line, column)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_symbols_symbolKind_symbolName ON symbols(symbolKind, symbolName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS locations(symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER, locationKind INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_locations_sourceId_line_column ON locations(sourceId, line, column)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_locations_sourceId_locationKind ON locations(sourceId, locationKind)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sources(sourceId INTEGER PRIMARY KEY, directoryId INTEGER, sourceName TEXT, sourceType INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sources_sourceName ON sources(sourceName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_sources_directoryId_sourceName ON sources(directoryId, sourceName)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS directories(directoryId INTEGER PRIMARY KEY, directoryPath TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_directories_directoryPath ON directories(directoryPath)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_directories_directoryPath ON directories(directoryPath)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectParts(projectPartId INTEGER PRIMARY KEY, projectPartName TEXT, compilerArguments TEXT, compilerMacros TEXT, includeSearchPaths TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectParts_projectPartName ON projectParts(projectPartName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS projectPartsSources(projectPartId INTEGER, sourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_projectPartsSources_sourceId_projectPartId ON projectPartsSources(sourceId, projectPartId)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_projectPartsSources_projectPartId ON projectPartsSources(projectPartId)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS usedMacros(usedMacroId INTEGER PRIMARY KEY, sourceId INTEGER, macroName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_sourceId_macroName ON usedMacros(sourceId, macroName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_usedMacros_macroName ON usedMacros(macroName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS fileStatuses(sourceId INTEGER PRIMARY KEY, size INTEGER, lastModified INTEGER, isInPrecompiledHeader INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS sourceDependencies(sourceId INTEGER, dependencySourceId INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_sourceDependencies_sourceId_dependencySourceId ON sourceDependencies(sourceId, dependencySourceId)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE IF NOT EXISTS precompiledHeaders(projectPartId INTEGER PRIMARY KEY, pchPath TEXT, pchBuildTime INTEGER)"))); + EXPECT_CALL(mockDatabase, commit()); Initializer initializer{mockDatabase}; } diff --git a/tests/unit/unittest/refactoringserver-test.cpp b/tests/unit/unittest/refactoringserver-test.cpp index 44fe87497b6..0abe22f1b62 100644 --- a/tests/unit/unittest/refactoringserver-test.cpp +++ b/tests/unit/unittest/refactoringserver-test.cpp @@ -43,6 +43,7 @@ namespace { using testing::AllOf; using testing::Contains; +using testing::Field; using testing::IsEmpty; using testing::NiceMock; using testing::Not; @@ -72,8 +73,8 @@ MATCHER_P2(IsSourceLocation, line, column, + ")" ) { - return arg.line() == uint(line) - && arg.column() == uint(column); + return arg.line == uint(line) + && arg.column == uint(column); } class RefactoringServer : public ::testing::Test @@ -82,6 +83,11 @@ protected: void SetUp() override; void TearDown() override; + ClangBackEnd::FilePathId filePathId(Utils::SmallStringView string) + { + return filePathCache.filePathId(ClangBackEnd::FilePathView{string}); + } + protected: NiceMock<MockRefactoringClient> mockRefactoringClient; NiceMock<MockSymbolIndexing> mockSymbolIndexing; @@ -111,12 +117,12 @@ TEST_F(RefactoringServerSlowTest, RequestSourceLocationsForRenamingMessage) EXPECT_CALL(mockRefactoringClient, sourceLocationsForRenamingMessage( - AllOf(Property(&SourceLocationsForRenamingMessage::textDocumentRevision, 1), - Property(&SourceLocationsForRenamingMessage::symbolName, "v"), - Property(&SourceLocationsForRenamingMessage::sourceLocations, - Property(&SourceLocationsContainer::sourceLocationContainers, - AllOf(Contains(IsSourceLocation(1, 5)), - Contains(IsSourceLocation(3, 9)))))))); + AllOf(Field(&SourceLocationsForRenamingMessage::textDocumentRevision, 1), + Field(&SourceLocationsForRenamingMessage::symbolName, "v"), + Field(&SourceLocationsForRenamingMessage::sourceLocations, + Property(&SourceLocationsContainer::sourceLocationContainers, + AllOf(Contains(IsSourceLocation(1, 5)), + Contains(IsSourceLocation(3, 9)))))))); refactoringServer.requestSourceLocationsForRenamingMessage(std::move(message)); } @@ -129,9 +135,9 @@ TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesForQueryMessage) EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } @@ -151,9 +157,9 @@ TEST_F(RefactoringServerSlowTest, RequestSingleSourceRangesAndDiagnosticsWithUns EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 1, 9, unsavedContent)))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 1, 9, unsavedContent)))))); refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } @@ -166,14 +172,14 @@ TEST_F(RefactoringServerSlowTest, RequestTwoSourceRangesForQueryMessage) EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))); refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); } @@ -190,14 +196,14 @@ TEST_F(RefactoringServerVerySlowTest, RequestManySourceRangesForQueryMessage) EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent)))))); EXPECT_CALL(mockRefactoringClient, sourceRangesForQueryMessage( - Property(&SourceRangesForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))) + Field(&SourceRangesForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Not(Contains(IsSourceRangeWithText(1, 1, 2, 4, sourceContent))))))) .Times(processingSlotCount + 2); refactoringServer.requestSourceRangesForQueryMessage(std::move(message)); @@ -264,11 +270,11 @@ TEST_F(RefactoringServerSlowTest, ForValidRequestSourceRangesAndDiagnosticsGetSo EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage( AllOf( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - Contains(IsSourceRangeWithText(1, 1, 1, 12, "void f() {}")))), - Property(&SourceRangesAndDiagnosticsForQueryMessage::diagnostics, - IsEmpty())))); + Field(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + Contains(IsSourceRangeWithText(1, 1, 1, 12, "void f() {}")))), + Field(&SourceRangesAndDiagnosticsForQueryMessage::diagnostics, + IsEmpty())))); refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); } @@ -283,21 +289,23 @@ TEST_F(RefactoringServerSlowTest, ForInvalidRequestSourceRangesAndDiagnosticsGet EXPECT_CALL(mockRefactoringClient, sourceRangesAndDiagnosticsForQueryMessage( AllOf( - Property(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, - Property(&SourceRangesContainer::sourceRangeWithTextContainers, - IsEmpty())), - Property(&SourceRangesAndDiagnosticsForQueryMessage::diagnostics, - Not(IsEmpty()))))); + Field(&SourceRangesAndDiagnosticsForQueryMessage::sourceRanges, + Field(&SourceRangesContainer::sourceRangeWithTextContainers, + IsEmpty())), + Field(&SourceRangesAndDiagnosticsForQueryMessage::diagnostics, + Not(IsEmpty()))))); refactoringServer.requestSourceRangesAndDiagnosticsForQueryMessage(std::move(message)); } -TEST_F(RefactoringServer, UpdatePchProjectPartsCallsSymbolIndexingUpdateProjectParts) +TEST_F(RefactoringServer, UpdateProjectPartsCallsSymbolIndexingUpdateProjectParts) { ProjectPartContainers projectParts{{{"projectPartId", {"-I", TESTDATA_DIR}, - {"header1.h"}, - {"main.cpp"}}}}; + {{"DEFINE", "1"}}, + {"/includes"}, + {filePathId("header1.h")}, + {filePathId("main.cpp")}}}}; FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"}, "void f();", {}}}; @@ -306,7 +314,7 @@ TEST_F(RefactoringServer, UpdatePchProjectPartsCallsSymbolIndexingUpdateProjectP EXPECT_CALL(mockSymbolIndexing, updateProjectParts(projectParts, unsaved)); - refactoringServer.updatePchProjectParts({Utils::clone(projectParts), Utils::clone(unsaved)}); + refactoringServer.updateProjectParts({Utils::clone(projectParts), Utils::clone(unsaved)}); } void RefactoringServer::SetUp() diff --git a/tests/unit/unittest/sizedarray-test.cpp b/tests/unit/unittest/sizedarray-test.cpp index b3637a23a19..03cec127b35 100644 --- a/tests/unit/unittest/sizedarray-test.cpp +++ b/tests/unit/unittest/sizedarray-test.cpp @@ -145,4 +145,13 @@ TEST(SizedArray, ConstREndIteratorIsOneAfterRBeginForOneSizedArray) ASSERT_THAT(std::next(array.crbegin(), 1), array.crend()); } +TEST(SizedArray, InitializerListSize) +{ + SizedArray<char, 8> array{'a', 'b'}; + + auto size = array.size(); + + ASSERT_THAT(size, 2); +} + } // anonymous namespace diff --git a/tests/unit/unittest/smallstring-test.cpp b/tests/unit/unittest/smallstring-test.cpp index 69017f0d70d..ee55d875a7d 100644 --- a/tests/unit/unittest/smallstring-test.cpp +++ b/tests/unit/unittest/smallstring-test.cpp @@ -55,24 +55,17 @@ TEST(SmallString, NullSmallStringIsEqualToEmptySmallString) TEST(SmallString, ShortSmallStringLiteralIsShortSmallString) { - constexpr SmallStringLiteral shortText("short string"); + // constexpr + SmallStringLiteral shortText("short string"); -#if __cpp_constexpr >= 201304 ASSERT_TRUE(shortText.isShortString()); -#else - ASSERT_TRUE(shortText.isReadOnlyReference()); -#endif } TEST(SmallString, ShortSmallStringIsShortSmallString) { SmallString shortText("short string"); -#if __cpp_constexpr >= 201304 ASSERT_TRUE(shortText.isShortString()); -#else - ASSERT_TRUE(shortText.isReadOnlyReference()); -#endif } TEST(SmallString, CreateFromCStringIterators) @@ -189,11 +182,7 @@ TEST(SmallString, CopyShortConstExpressionSmallStringIsShortSmallString) auto shortTextCopy = shortText; -#if __cpp_constexpr >= 201304 ASSERT_TRUE(shortTextCopy.isShortString()); -#else - ASSERT_TRUE(shortTextCopy.isReadOnlyReference()); -#endif } TEST(SmallString, CopyLongConstExpressionSmallStringIsLongSmallString) @@ -1687,7 +1676,7 @@ TEST(SmallString, ToView) { SmallString text = "text"; - auto view = text.toView(); + auto view = text.toStringView(); ASSERT_THAT(view, "text"); diff --git a/tests/unit/unittest/sourcerangecontainer-matcher.h b/tests/unit/unittest/sourcerangecontainer-matcher.h index 3656b840d7a..c2345be533a 100644 --- a/tests/unit/unittest/sourcerangecontainer-matcher.h +++ b/tests/unit/unittest/sourcerangecontainer-matcher.h @@ -40,10 +40,10 @@ MATCHER_P4(IsSourceRange, startLine, startColumn, endLine, endColumn, + ")]" ) { - return arg.start().line() == uint(startLine) - && arg.start().column() == uint(startColumn) - && arg.end().line() == uint(endLine) - && arg.end().column() == uint(endColumn); + return arg.start.line == uint(startLine) + && arg.start.column == uint(startColumn) + && arg.end.line == uint(endLine) + && arg.end.column == uint(endColumn); } MATCHER_P5(IsSourceRangeWithText, startLine, startColumn, endLine, endColumn, text, @@ -56,11 +56,11 @@ MATCHER_P5(IsSourceRangeWithText, startLine, startColumn, endLine, endColumn, te + ")" ) { - return arg.start().line() == uint(startLine) - && arg.start().column() == uint(startColumn) - && arg.end().line() == uint(endLine) - && arg.end().column() == uint(endColumn) - && arg.text().toCarriageReturnsStripped() == text; + return arg.start.line == uint(startLine) + && arg.start.column == uint(startColumn) + && arg.end.line == uint(endLine) + && arg.end.column == uint(endColumn) + && arg.text.toCarriageReturnsStripped() == text; } diff --git a/tests/unit/unittest/sourcerangefilter-test.cpp b/tests/unit/unittest/sourcerangefilter-test.cpp index f5630af57cb..d59bd033e19 100644 --- a/tests/unit/unittest/sourcerangefilter-test.cpp +++ b/tests/unit/unittest/sourcerangefilter-test.cpp @@ -101,7 +101,7 @@ TEST_F(SourceRangeFilter, FilterDuplicatesFromMessage) auto filteredMessage = filter.removeDuplicates(std::move(message2)); - ASSERT_THAT(filteredMessage.sourceRanges().sourceRangeWithTextContainers(), + ASSERT_THAT(filteredMessage.sourceRanges.sourceRangeWithTextContainers, ContainerEq(sourceRanges3)); } @@ -119,5 +119,4 @@ TEST_F(SourceRangeFilter, SortSourceRanges) ASSERT_THAT(sourceRange, ContainerEq(sourceRanges3)); } - } diff --git a/tests/unit/unittest/sqlitedatabase-test.cpp b/tests/unit/unittest/sqlitedatabase-test.cpp index 73f3a427242..8ccc2f652c6 100644 --- a/tests/unit/unittest/sqlitedatabase-test.cpp +++ b/tests/unit/unittest/sqlitedatabase-test.cpp @@ -47,12 +47,27 @@ using Sqlite::Table; class SqliteDatabase : public ::testing::Test { protected: - void SetUp() override; - void TearDown() override; + void SetUp() override + { + database.setJournalMode(JournalMode::Memory); + database.setDatabaseFilePath(databaseFilePath); + auto &table = database.addTable(); + table.setName("test"); + table.addColumn("name"); + + database.open(); + } + + void TearDown() override + { + if (database.isOpen()) + database.close(); + } SpyDummy spyDummy; - QString databaseFilePath = QStringLiteral(":memory:"); + QString databaseFilePath{":memory:"}; Sqlite::Database database; + Sqlite::TransactionInterface &transactionInterface = database; }; TEST_F(SqliteDatabase, SetDatabaseFilePath) @@ -140,20 +155,39 @@ TEST_F(SqliteDatabase, LastRowId) ASSERT_THAT(database.lastInsertedRowId(), 42); } -void SqliteDatabase::SetUp() +TEST_F(SqliteDatabase, DeferredBegin) { - database.setJournalMode(JournalMode::Memory); - database.setDatabaseFilePath(databaseFilePath); - auto &table = database.addTable(); - table.setName("test"); - table.addColumn("name"); + ASSERT_NO_THROW(transactionInterface.deferredBegin()); - database.open(); + transactionInterface.commit(); +} + +TEST_F(SqliteDatabase, ImmediateBegin) +{ + ASSERT_NO_THROW(transactionInterface.immediateBegin()); + + transactionInterface.commit(); +} + +TEST_F(SqliteDatabase, ExclusiveBegin) +{ + ASSERT_NO_THROW(transactionInterface.exclusiveBegin()); + + transactionInterface.commit(); } -void SqliteDatabase::TearDown() +TEST_F(SqliteDatabase, Commit) { - if (database.isOpen()) - database.close(); + transactionInterface.deferredBegin(); + + ASSERT_NO_THROW(transactionInterface.commit()); } + +TEST_F(SqliteDatabase, Rollback) +{ + transactionInterface.deferredBegin(); + + ASSERT_NO_THROW(transactionInterface.rollback()); +} + } diff --git a/tests/unit/unittest/sqliteindex-test.cpp b/tests/unit/unittest/sqliteindex-test.cpp index 4c21c7f9356..f6fb4e8be30 100644 --- a/tests/unit/unittest/sqliteindex-test.cpp +++ b/tests/unit/unittest/sqliteindex-test.cpp @@ -31,6 +31,7 @@ namespace { using Sqlite::Exception; using Sqlite::Index; +using Sqlite::IndexType; TEST(Index, OneColumn) { @@ -63,4 +64,13 @@ TEST(Index, EmptyColumns) ASSERT_THROW(index.sqlStatement(), Exception); } + +TEST(Index, UniqueIndex) +{ + Index index{"tableName", {"column1"}, IndexType::Unique}; + + auto sqlStatement = index.sqlStatement(); + + ASSERT_THAT(sqlStatement, Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_tableName_column1 ON tableName(column1)")); +} } diff --git a/tests/unit/unittest/sqlitestatement-test.cpp b/tests/unit/unittest/sqlitestatement-test.cpp index f033c07ed73..cb8206d8757 100644 --- a/tests/unit/unittest/sqlitestatement-test.cpp +++ b/tests/unit/unittest/sqlitestatement-test.cpp @@ -639,6 +639,40 @@ TEST_F(SqliteStatement, ThrowExceptionOnlyInReset) Sqlite::StatementHasError); } +TEST_F(SqliteStatement, ResetIfWriteIsThrowingException) +{ + MockSqliteStatement mockStatement; + + EXPECT_CALL(mockStatement, bind(1, TypedEq<Utils::SmallStringView>("bar"))) + .WillOnce(Throw(Sqlite::StatementIsBusy(""))); + EXPECT_CALL(mockStatement, reset()); + + ASSERT_ANY_THROW(mockStatement.write("bar")); +} + +TEST_F(SqliteStatement, ResetIfWriteNamedIsThrowingException) +{ + MockSqliteStatement mockStatement; + + EXPECT_CALL(mockStatement, bindingIndexForName(TypedEq<Utils::SmallStringView>("@foo"))) + .WillOnce(Return(1)); + EXPECT_CALL(mockStatement, bind(1, TypedEq<Utils::SmallStringView>("bar"))) + .WillOnce(Throw(Sqlite::StatementIsBusy(""))); + EXPECT_CALL(mockStatement, reset()); + + ASSERT_ANY_THROW(mockStatement.writeNamed("@foo", "bar")); +} + +TEST_F(SqliteStatement, ResetIfExecuteThrowsException) +{ + MockSqliteStatement mockStatement; + + EXPECT_CALL(mockStatement, next()).WillOnce(Throw(Sqlite::StatementIsBusy(""))); + EXPECT_CALL(mockStatement, reset()); + + ASSERT_ANY_THROW(mockStatement.execute()); +} + void SqliteStatement::SetUp() { database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC, value NUMERIC)"); diff --git a/tests/unit/unittest/sqlitetable-test.cpp b/tests/unit/unittest/sqlitetable-test.cpp index 658e593b629..c5ce8e325dd 100644 --- a/tests/unit/unittest/sqlitetable-test.cpp +++ b/tests/unit/unittest/sqlitetable-test.cpp @@ -110,4 +110,21 @@ TEST_F(SqliteTable, InitializeTableWithIndex) table.initialize(mockDatabase); } + +TEST_F(SqliteTable, InitializeTableWithUniqueIndex) +{ + InSequence sequence; + table.setName(tableName.clone()); + auto &column = table.addColumn("name"); + auto &column2 = table.addColumn("value"); + table.addUniqueIndex({column}); + table.addIndex({column2}); + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TABLE testTable(name NUMERIC, value NUMERIC)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_testTable_name ON testTable(name)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_testTable_value ON testTable(value)"))); + + table.initialize(mockDatabase); +} + } diff --git a/tests/unit/unittest/sqlitetransaction-test.cpp b/tests/unit/unittest/sqlitetransaction-test.cpp index 69f90a71221..dc3e5bba70b 100644 --- a/tests/unit/unittest/sqlitetransaction-test.cpp +++ b/tests/unit/unittest/sqlitetransaction-test.cpp @@ -25,91 +25,295 @@ #include "googletest.h" +#include "mocksqlitetransactionbackend.h" + #include <sqlitetransaction.h> +#include <sqliteexception.h> #include <mocksqlitedatabase.h> namespace { -using DeferredTransaction = Sqlite::DeferredTransaction<MockSqliteDatabase>; -using ImmediateTransaction = Sqlite::ImmediateTransaction<MockSqliteDatabase>; -using ExclusiveTransaction = Sqlite::ExclusiveTransaction<MockSqliteDatabase>; +using Sqlite::DeferredTransaction; +using Sqlite::ImmediateTransaction; +using Sqlite::ExclusiveTransaction; +using Sqlite::DeferredNonThrowingDestructorTransaction; +using Sqlite::ImmediateNonThrowingDestructorTransaction; +using Sqlite::ExclusiveNonThrowingDestructorTransaction; class SqliteTransaction : public testing::Test { protected: - MockMutex mockMutex; - MockSqliteDatabase mockDatabase{mockMutex}; + NiceMock<MockSqliteTransactionBackend> mockTransactionBackend; }; TEST_F(SqliteTransaction, DeferredTransactionCommit) { - EXPECT_CALL(mockDatabase, databaseMutex()); - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + DeferredTransaction transaction{mockTransactionBackend}; + transaction.commit(); +} + +TEST_F(SqliteTransaction, DeferredTransactionCommitCallsInterface) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); - DeferredTransaction transaction{mockDatabase}; + DeferredTransaction transaction{mockTransactionBackend}; transaction.commit(); } TEST_F(SqliteTransaction, DeferredTransactionRollBack) { - EXPECT_CALL(mockDatabase, databaseMutex()); - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN"))); - EXPECT_CALL(mockDatabase, execute(Eq("ROLLBACK"))); - EXPECT_CALL(mockMutex, unlock()); + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()); + EXPECT_CALL(mockTransactionBackend, rollback()); + EXPECT_CALL(mockTransactionBackend, unlock()); - DeferredTransaction transaction{mockDatabase}; + DeferredTransaction transaction{mockTransactionBackend}; } TEST_F(SqliteTransaction, ImmediateTransactionCommit) { - EXPECT_CALL(mockDatabase, databaseMutex()); - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); + InSequence s; - ImmediateTransaction transaction{mockDatabase}; + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, immediateBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ImmediateTransaction transaction{mockTransactionBackend}; transaction.commit(); } TEST_F(SqliteTransaction, ImmediateTransactionRollBack) { - EXPECT_CALL(mockDatabase, databaseMutex()); - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); - EXPECT_CALL(mockDatabase, execute(Eq("ROLLBACK"))); - EXPECT_CALL(mockMutex, unlock()); + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, immediateBegin()); + EXPECT_CALL(mockTransactionBackend, rollback()); + EXPECT_CALL(mockTransactionBackend, unlock()); - ImmediateTransaction transaction{mockDatabase}; + ImmediateTransaction transaction{mockTransactionBackend}; } TEST_F(SqliteTransaction, ExclusiveTransactionCommit) { - EXPECT_CALL(mockDatabase, databaseMutex()); - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN EXCLUSIVE"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, exclusiveBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); - ExclusiveTransaction transaction{mockDatabase}; + ExclusiveTransaction transaction{mockTransactionBackend}; transaction.commit(); } TEST_F(SqliteTransaction, ExclusiveTransactionRollBack) { - EXPECT_CALL(mockDatabase, databaseMutex()); - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN EXCLUSIVE"))); - EXPECT_CALL(mockDatabase, execute(Eq("ROLLBACK"))); - EXPECT_CALL(mockMutex, unlock()); + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, exclusiveBegin()); + EXPECT_CALL(mockTransactionBackend, rollback()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ExclusiveTransaction transaction{mockTransactionBackend}; +} + +TEST_F(SqliteTransaction, DeferredNonThrowingDestructorTransactionCommit) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + DeferredNonThrowingDestructorTransaction transaction{mockTransactionBackend}; + transaction.commit(); +} + +TEST_F(SqliteTransaction, DeferredNonThrowingDestructorTransactionCommitCallsInterface) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + DeferredNonThrowingDestructorTransaction transaction{mockTransactionBackend}; + transaction.commit(); +} + +TEST_F(SqliteTransaction, DeferredNonThrowingDestructorTransactionRollBack) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()); + EXPECT_CALL(mockTransactionBackend, rollback()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + DeferredNonThrowingDestructorTransaction transaction{mockTransactionBackend}; +} + +TEST_F(SqliteTransaction, ImmediateNonThrowingDestructorTransactionCommit) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, immediateBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ImmediateNonThrowingDestructorTransaction transaction{mockTransactionBackend}; + transaction.commit(); +} + +TEST_F(SqliteTransaction, ImmediateNonThrowingDestructorTransactionRollBack) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, immediateBegin()); + EXPECT_CALL(mockTransactionBackend, rollback()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ImmediateNonThrowingDestructorTransaction transaction{mockTransactionBackend}; +} + +TEST_F(SqliteTransaction, ExclusiveNonThrowingDestructorTransactionCommit) +{ + InSequence s; - ExclusiveTransaction transaction{mockDatabase}; + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, exclusiveBegin()); + EXPECT_CALL(mockTransactionBackend, commit()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ExclusiveNonThrowingDestructorTransaction transaction{mockTransactionBackend}; + transaction.commit(); +} + +TEST_F(SqliteTransaction, ExclusiveTNonThrowingDestructorransactionRollBack) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, exclusiveBegin()); + EXPECT_CALL(mockTransactionBackend, rollback()); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ExclusiveNonThrowingDestructorTransaction transaction{mockTransactionBackend}; } +TEST_F(SqliteTransaction, DeferredTransactionBeginThrows) +{ + ON_CALL(mockTransactionBackend, deferredBegin()) + .WillByDefault(Throw(Sqlite::Exception("foo"))); + + ASSERT_THROW(DeferredTransaction{mockTransactionBackend}, + Sqlite::Exception); } +TEST_F(SqliteTransaction, ImmediateTransactionBeginThrows) +{ + ON_CALL(mockTransactionBackend, immediateBegin()) + .WillByDefault(Throw(Sqlite::Exception("foo"))); + + ASSERT_THROW(ImmediateTransaction{mockTransactionBackend}, + Sqlite::Exception); +} + +TEST_F(SqliteTransaction, ExclusiveTransactionBeginThrows) +{ + ON_CALL(mockTransactionBackend, exclusiveBegin()) + .WillByDefault(Throw(Sqlite::Exception("foo"))); + + ASSERT_THROW(ExclusiveTransaction{mockTransactionBackend}, + Sqlite::Exception); +} + +TEST_F(SqliteTransaction, DeferredTransactionBeginThrowsAndNotRollback) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, deferredBegin()) + .WillOnce(Throw(Sqlite::Exception("foo"))); + EXPECT_CALL(mockTransactionBackend, rollback()).Times(0); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ASSERT_ANY_THROW(DeferredTransaction{mockTransactionBackend}); +} + +TEST_F(SqliteTransaction, ImmediateTransactionBeginThrowsAndNotRollback) +{ + InSequence s; + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, immediateBegin()) + .WillOnce(Throw(Sqlite::Exception("foo"))); + EXPECT_CALL(mockTransactionBackend, rollback()).Times(0); + EXPECT_CALL(mockTransactionBackend, unlock()); + + + ASSERT_ANY_THROW(ImmediateTransaction{mockTransactionBackend}); +} + +TEST_F(SqliteTransaction, ExclusiveTransactionBeginThrowsAndNotRollback) +{ + InSequence s; + + EXPECT_CALL(mockTransactionBackend, lock()); + EXPECT_CALL(mockTransactionBackend, exclusiveBegin()) + .WillOnce(Throw(Sqlite::Exception("foo"))); + EXPECT_CALL(mockTransactionBackend, rollback()).Times(0); + EXPECT_CALL(mockTransactionBackend, unlock()); + + ASSERT_ANY_THROW(ExclusiveTransaction{mockTransactionBackend}); +} + +TEST_F(SqliteTransaction, TransactionCommitThrows) +{ + ON_CALL(mockTransactionBackend, commit()) + .WillByDefault(Throw(Sqlite::Exception("foo"))); + ImmediateTransaction transaction{mockTransactionBackend}; + + ASSERT_THROW(transaction.commit(), + Sqlite::Exception); +} + +TEST_F(SqliteTransaction, TransactionRollbackInDestructorThrows) +{ + ON_CALL(mockTransactionBackend, rollback()) + .WillByDefault(Throw(Sqlite::Exception("foo"))); + + ASSERT_THROW(ExclusiveTransaction{mockTransactionBackend}, + Sqlite::Exception); +} + +TEST_F(SqliteTransaction, TransactionRollbackInDestructorDontThrows) +{ + ON_CALL(mockTransactionBackend, rollback()) + .WillByDefault(Throw(Sqlite::Exception("foo"))); + + ASSERT_NO_THROW(ExclusiveNonThrowingDestructorTransaction{mockTransactionBackend}); +} + +} diff --git a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp index d118570ea97..4990438c509 100644 --- a/tests/unit/unittest/storagesqlitestatementfactory-test.cpp +++ b/tests/unit/unittest/storagesqlitestatementfactory-test.cpp @@ -33,17 +33,14 @@ namespace { -using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>, - MockSqliteReadStatement, - MockSqliteWriteStatement>; +using StatementFactory = ClangBackEnd::StorageSqliteStatementFactory<NiceMock<MockSqliteDatabase>>; using Sqlite::Table; class StorageSqliteStatementFactory : public testing::Test { protected: - NiceMock<MockMutex> mockMutex; - NiceMock<MockSqliteDatabase> mockDatabase{mockMutex}; + NiceMock<MockSqliteDatabase> mockDatabase; StatementFactory factory{mockDatabase}; }; @@ -51,13 +48,9 @@ TEST_F(StorageSqliteStatementFactory, AddNewSymbolsTable) { InSequence s; - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT, symbolKind INTEGER)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId)"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); factory.createNewSymbolsTable(); } @@ -66,28 +59,47 @@ TEST_F(StorageSqliteStatementFactory, AddNewLocationsTable) { InSequence s; - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newLocations_sourceId ON newLocations(sourceId)"))); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, sourceId INTEGER, line INTEGER, column INTEGER, locationKind INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_newLocations_sourceId_line_column ON newLocations(sourceId, line, column)"))); factory.createNewLocationsTable(); } +TEST_F(StorageSqliteStatementFactory, AddNewUsedMacroTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newUsedMacros(sourceId INTEGER, macroName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newUsedMacros_sourceId_macroName ON newUsedMacros(sourceId, macroName)"))); + + factory.createNewUsedMacrosTable(); +} + +TEST_F(StorageSqliteStatementFactory, AddNewSourceDependenciesTable) +{ + InSequence s; + + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSourceDependencies(sourceId INTEGER, dependencySourceId TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSourceDependencies_sourceId_dependencySourceId ON newSourceDependencies(sourceId, dependencySourceId)"))); + + factory.createNewSourceDependenciesTable(); +} + TEST_F(StorageSqliteStatementFactory, AddTablesInConstructor) { - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))).Times(2); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))).Times(2); - EXPECT_CALL(mockMutex, lock()).Times(2); - EXPECT_CALL(mockMutex, unlock()).Times(2); + InSequence s; - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT)"))); + EXPECT_CALL(mockDatabase, immediateBegin()); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSymbols(temporarySymbolId INTEGER PRIMARY KEY, symbolId INTEGER, usr TEXT, symbolName TEXT, symbolKind INTEGER)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_usr_symbolName ON newSymbols(usr, symbolName)"))); EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSymbols_symbolId ON newSymbols(symbolId)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, line INTEGER, column INTEGER, sourceId INTEGER)"))); - EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newLocations_sourceId ON newLocations(sourceId)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newLocations(temporarySymbolId INTEGER, symbolId INTEGER, sourceId INTEGER, line INTEGER, column INTEGER, locationKind INTEGER)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE UNIQUE INDEX IF NOT EXISTS index_newLocations_sourceId_line_column ON newLocations(sourceId, line, column)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newUsedMacros(sourceId INTEGER, macroName TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newUsedMacros_sourceId_macroName ON newUsedMacros(sourceId, macroName)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE TEMPORARY TABLE newSourceDependencies(sourceId INTEGER, dependencySourceId TEXT)"))); + EXPECT_CALL(mockDatabase, execute(Eq("CREATE INDEX IF NOT EXISTS index_newSourceDependencies_sourceId_dependencySourceId ON newSourceDependencies(sourceId, dependencySourceId)"))); + EXPECT_CALL(mockDatabase, commit()); StatementFactory factory{mockDatabase}; } @@ -95,13 +107,13 @@ TEST_F(StorageSqliteStatementFactory, AddTablesInConstructor) TEST_F(StorageSqliteStatementFactory, InsertNewSymbolsStatement) { ASSERT_THAT(factory.insertSymbolsToNewSymbolsStatement.sqlStatement, - Eq("INSERT INTO newSymbols(temporarySymbolId, usr, symbolName) VALUES(?,?,?)")); + Eq("INSERT INTO newSymbols(temporarySymbolId, usr, symbolName, symbolKind) VALUES(?,?,?,?)")); } TEST_F(StorageSqliteStatementFactory, InsertNewLocationsToLocations) { ASSERT_THAT(factory.insertLocationsToNewLocationsStatement.sqlStatement, - Eq("INSERT INTO newLocations(temporarySymbolId, line, column, sourceId) VALUES(?,?,?,?)")); + Eq("INSERT OR IGNORE INTO newLocations(temporarySymbolId, line, column, sourceId, locationKind) VALUES(?,?,?,?,?)")); } TEST_F(StorageSqliteStatementFactory, SelectNewSourceIdsStatement) @@ -113,7 +125,7 @@ TEST_F(StorageSqliteStatementFactory, SelectNewSourceIdsStatement) TEST_F(StorageSqliteStatementFactory, AddNewSymbolsToSymbolsStatement) { ASSERT_THAT(factory.addNewSymbolsToSymbolsStatement.sqlStatement, - Eq("INSERT INTO symbols(usr, symbolName) SELECT usr, symbolName FROM newSymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)")); + Eq("INSERT INTO symbols(usr, symbolName, symbolKind) SELECT usr, symbolName, symbolKind FROM newSymbols WHERE NOT EXISTS (SELECT usr FROM symbols WHERE symbols.usr == newSymbols.usr)")); } TEST_F(StorageSqliteStatementFactory, SyncNewSymbolsFromSymbolsStatement) @@ -137,7 +149,7 @@ TEST_F(StorageSqliteStatementFactory, DeleteAllLocationsFromUpdatedFiles) TEST_F(StorageSqliteStatementFactory, InsertNewLocationsInLocations) { ASSERT_THAT(factory.insertNewLocationsInLocationsStatement.sqlStatement, - Eq("INSERT INTO locations(symbolId, line, column, sourceId) SELECT symbolId, line, column, sourceId FROM newLocations")); + Eq("INSERT INTO locations(symbolId, line, column, sourceId, locationKind) SELECT symbolId, line, column, sourceId, locationKind FROM newLocations")); } TEST_F(StorageSqliteStatementFactory, DeleteNewSymbolsTableStatement) @@ -152,5 +164,119 @@ TEST_F(StorageSqliteStatementFactory, DeleteNewLocationsTableStatement) Eq("DELETE FROM newLocations")); } +TEST_F(StorageSqliteStatementFactory, InsertProjectPart) +{ + ASSERT_THAT(factory.insertProjectPartStatement.sqlStatement, + Eq("INSERT OR IGNORE INTO projectParts(projectPartName, compilerArguments, compilerMacros, includeSearchPaths) VALUES (?,?,?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, UpdateProjectPart) +{ + ASSERT_THAT(factory.updateProjectPartStatement.sqlStatement, + Eq("UPDATE projectParts SET compilerArguments = ?, compilerMacros = ?, includeSearchPaths = ? WHERE projectPartName = ?")); +} + +TEST_F(StorageSqliteStatementFactory, GetProjectPartIdForProjectPartName) +{ + ASSERT_THAT(factory.getProjectPartIdStatement.sqlStatement, + Eq("SELECT projectPartId FROM projectParts WHERE projectPartName = ?")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteAllProjectPartsSourcesWithProjectPartId) +{ + ASSERT_THAT(factory.deleteAllProjectPartsSourcesWithProjectPartIdStatement.sqlStatement, + Eq("DELETE FROM projectPartsSources WHERE projectPartId = ?")); +} + +TEST_F(StorageSqliteStatementFactory, InsertProjectPartsSources) +{ + ASSERT_THAT(factory.insertProjectPartSourcesStatement.sqlStatement, + Eq("INSERT INTO projectPartsSources(projectPartId, sourceId) VALUES (?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, GetCompileArgumentsForFileId) +{ + ASSERT_THAT(factory.getCompileArgumentsForFileIdStatement.sqlStatement, + Eq("SELECT compilerArguments FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertIntoNewUsedMacros) +{ + ASSERT_THAT(factory.insertIntoNewUsedMacrosStatement.sqlStatement, + Eq("INSERT INTO newUsedMacros(sourceId, macroName) VALUES (?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, SyncNewUsedMacros) +{ + ASSERT_THAT(factory.syncNewUsedMacrosStatement.sqlStatement, + Eq("INSERT INTO usedMacros(sourceId, macroName) SELECT sourceId, macroName FROM newUsedMacros WHERE NOT EXISTS (SELECT sourceId FROM usedMacros WHERE usedMacros.sourceId == newUsedMacros.sourceId AND usedMacros.macroName == newUsedMacros.macroName)")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteOutdatedUnusedMacros) +{ + ASSERT_THAT(factory.deleteOutdatedUsedMacrosStatement.sqlStatement, + Eq("DELETE FROM usedMacros WHERE sourceId IN (SELECT sourceId FROM newUsedMacros) AND NOT EXISTS (SELECT sourceId FROM newUsedMacros WHERE newUsedMacros.sourceId == usedMacros.sourceId AND newUsedMacros.macroName == usedMacros.macroName)")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteAllInNewUnusedMacros) +{ + ASSERT_THAT(factory.deleteNewUsedMacrosTableStatement.sqlStatement, + Eq("DELETE FROM newUsedMacros")); +} + +TEST_F(StorageSqliteStatementFactory, InsertFileStatuses) +{ + ASSERT_THAT(factory.insertFileStatuses.sqlStatement, + Eq("INSERT OR REPLACE INTO fileStatuses(sourceId, size, lastModified, isInPrecompiledHeader) VALUES (?,?,?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, InsertIntoNewSourceDependencies) +{ + ASSERT_THAT(factory.insertIntoNewSourceDependenciesStatement.sqlStatement, + Eq("INSERT INTO newSourceDependencies(sourceId, dependencySourceId) VALUES (?,?)")); +} + +TEST_F(StorageSqliteStatementFactory, SyncNewSourceDependencies) +{ + ASSERT_THAT(factory.syncNewSourceDependenciesStatement.sqlStatement, + Eq("INSERT INTO sourceDependencies(sourceId, dependencySourceId) SELECT sourceId, dependencySourceId FROM newSourceDependencies WHERE NOT EXISTS (SELECT sourceId FROM sourceDependencies WHERE sourceDependencies.sourceId == newSourceDependencies.sourceId AND sourceDependencies.dependencySourceId == newSourceDependencies.dependencySourceId)")); +} + +TEST_F(StorageSqliteStatementFactory, DeleteOutdatedSourceDependencies) +{ + ASSERT_THAT(factory.deleteOutdatedSourceDependenciesStatement.sqlStatement, + Eq("DELETE FROM sourceDependencies WHERE sourceId IN (SELECT sourceId FROM newSourceDependencies) AND NOT EXISTS (SELECT sourceId FROM newSourceDependencies WHERE newSourceDependencies.sourceId == sourceDependencies.sourceId AND newSourceDependencies.dependencySourceId == sourceDependencies.dependencySourceId)")); } +TEST_F(StorageSqliteStatementFactory, DeleteAllInNewSourceDependencies) +{ + ASSERT_THAT(factory.deleteNewSourceDependenciesStatement.sqlStatement, + Eq("DELETE FROM newSourceDependencies")); +} + +TEST_F(StorageSqliteStatementFactory, GetProjectPartCompilerArgumentsAndCompilerMacrosBySourceId) +{ + ASSERT_THAT(factory.getProjectPartArtefactsBySourceId.sqlStatement, + Eq("SELECT compilerArguments, compilerMacros, includeSearchPaths, projectPartId FROM projectParts WHERE projectPartId = (SELECT projectPartId FROM projectPartsSources WHERE sourceId = ?)")); +} + +TEST_F(StorageSqliteStatementFactory, GetProjectPartArtefactsByProjectPartName) +{ + ASSERT_THAT(factory.getProjectPartArtefactsByProjectPartName.sqlStatement, + Eq("SELECT compilerArguments, compilerMacros, includeSearchPaths, projectPartId FROM projectParts WHERE projectPartName = ?")); + +} + +TEST_F(StorageSqliteStatementFactory, GetLowestLastModifiedTimeOfDependencies) +{ + ASSERT_THAT(factory.getLowestLastModifiedTimeOfDependencies.sqlStatement, + Eq("WITH RECURSIVE sourceIds(sourceId) AS (VALUES(?) UNION SELECT dependencySourceId FROM sourceDependencies, sourceIds WHERE sourceDependencies.sourceId = sourceIds.sourceId) SELECT min(lastModified) FROM fileStatuses, sourceIds WHERE fileStatuses.sourceId = sourceIds.sourceId")); +} + +TEST_F(StorageSqliteStatementFactory, GetPrecompiledHeaderForProjectPartName) +{ + ASSERT_THAT(factory.getPrecompiledHeader.sqlStatement, + Eq("SELECT pchPath, pchBuildTime FROM precompiledHeaders WHERE projectPartId = ?")); +} + +} diff --git a/tests/unit/unittest/stringcache-test.cpp b/tests/unit/unittest/stringcache-test.cpp index 8465321c34d..102d8510427 100644 --- a/tests/unit/unittest/stringcache-test.cpp +++ b/tests/unit/unittest/stringcache-test.cpp @@ -45,6 +45,7 @@ using StorageIdFunction = std::function<int(Utils::SmallStringView)>; using StorageStringFunction = std::function<Utils::PathString(int)>; using Cache = ClangBackEnd::StringCache<Utils::PathString, + Utils::SmallStringView, int, NiceMock<MockMutex>, decltype(&Utils::reverseCompare), diff --git a/tests/unit/unittest/symbolfinder-test.cpp b/tests/unit/unittest/symbolfinder-test.cpp index d036b5b227d..6ab0bd06cd9 100644 --- a/tests/unit/unittest/symbolfinder-test.cpp +++ b/tests/unit/unittest/symbolfinder-test.cpp @@ -42,11 +42,7 @@ MATCHER_P2(IsSourceLocation, line, column, + ", column " + PrintToString(column) ) { - if (arg.line() != uint(line) - || arg.column() != uint(column)) - return false; - - return true; + return arg.line == uint(line) && arg.column == uint(column); } MATCHER_P(StrEq, text, diff --git a/tests/unit/unittest/symbolindexer-test.cpp b/tests/unit/unittest/symbolindexer-test.cpp index 934733ba02e..08293a05877 100644 --- a/tests/unit/unittest/symbolindexer-test.cpp +++ b/tests/unit/unittest/symbolindexer-test.cpp @@ -27,32 +27,54 @@ #include "mockclangpathwatcher.h" #include "mocksymbolscollector.h" #include "mocksymbolstorage.h" +#include "mockfilepathcaching.h" +#include "mocksqlitetransactionbackend.h" -#include <symbolindexer.h> -#include <updatepchprojectpartsmessage.h> +#include <filepathcaching.h> +#include <filestatuscache.h> #include <projectpartcontainerv2.h> +#include <refactoringdatabaseinitializer.h> +#include <symbolindexer.h> +#include <updateprojectpartsmessage.h> -namespace { +#include <QDateTime> -using testing::_; -using testing::Contains; -using testing::Field; -using testing::IsEmpty; -using testing::NiceMock; -using testing::Property; -using testing::Return; -using testing::ReturnRef; -using testing::Sequence; +#include <fstream> + +namespace { using Utils::PathString; +using ClangBackEnd::CompilerMacro; +using ClangBackEnd::FileStatuses; +using ClangBackEnd::FilePathId; +using ClangBackEnd::FilePathIds; +using ClangBackEnd::FilePathView; using ClangBackEnd::V2::ProjectPartContainer; using ClangBackEnd::V2::ProjectPartContainers; using ClangBackEnd::V2::FileContainers; using ClangBackEnd::SymbolEntries; using ClangBackEnd::SymbolEntry; +using ClangBackEnd::SourceDependencies; using ClangBackEnd::SourceLocationEntries; using ClangBackEnd::SourceLocationEntry; -using ClangBackEnd::SymbolType; +using ClangBackEnd::SymbolKind; +using ClangBackEnd::SourceLocationKind; +using ClangBackEnd::UsedMacros; +using OptionalProjectPartArtefact = Utils::optional<ClangBackEnd::ProjectPartArtefact>; + +MATCHER_P2(IsFileId, directoryId, fileNameId, + std::string(negation ? "isn't " : "is ") + + PrintToString(ClangBackEnd::FilePathId(directoryId, fileNameId))) +{ + return arg == ClangBackEnd::FilePathId(directoryId, fileNameId); +} + +struct Data +{ + Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; + ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> databaseInitializer{database}; + ClangBackEnd::FilePathCaching filePathCache{database}; +}; class SymbolIndexer : public testing::Test { @@ -61,52 +83,136 @@ protected: { ON_CALL(mockCollector, symbols()).WillByDefault(ReturnRef(symbolEntries)); ON_CALL(mockCollector, sourceLocations()).WillByDefault(ReturnRef(sourceLocations)); + ON_CALL(mockCollector, sourceFiles()).WillByDefault(ReturnRef(sourceFileIds)); + ON_CALL(mockCollector, usedMacros()).WillByDefault(ReturnRef(usedMacros)); + ON_CALL(mockCollector, fileStatuses()).WillByDefault(ReturnRef(fileStatus)); + ON_CALL(mockCollector, sourceDependencies()).WillByDefault(ReturnRef(sourceDependencies)); + ON_CALL(mockStorage, fetchProjectPartArtefact(A<FilePathId>())).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A<FilePathId>())).WillByDefault(Return(QDateTime::currentSecsSinceEpoch())); + } + + static void SetUpTestCase() + { + data = std::make_unique<Data>(); + } + + static void TearDownTestCase() + { + data.reset(); + } + + void touchFile(FilePathId filePathId) + { + std::ofstream ostream(std::string(filePathCache.filePath(filePathId)), std::ios::binary); + ostream.write("\n", 1); + ostream.close(); + } + + FilePathId filePathId(Utils::SmallStringView path) const + { + return filePathCache.filePathId(ClangBackEnd::FilePathView(path)); } protected: - PathString main1Path = TESTDATA_DIR "/includecollector_main3.cpp"; - PathString main2Path = TESTDATA_DIR "/includecollector_main2.cpp"; - PathString header1Path = TESTDATA_DIR "/includecollector_header1.h"; - PathString header2Path = TESTDATA_DIR "/includecollector_header2.h"; + static std::unique_ptr<Data> data; // it can be non const because data holds no tested classes + ClangBackEnd::FilePathCaching &filePathCache = data->filePathCache; + ClangBackEnd::FilePathId main1PathId{filePathId(TESTDATA_DIR "/symbolindexer_main1.cpp")}; + ClangBackEnd::FilePathId main2PathId{filePathId(TESTDATA_DIR "/symbolindexer_main2.cpp")}; + ClangBackEnd::FilePathId header2PathId{filePathId(TESTDATA_DIR "/symbolindexer_header1.h")}; + ClangBackEnd::FilePathId header1PathId{filePathId(TESTDATA_DIR "/symbolindexer_header2.h")}; PathString generatedFileName = "includecollector_generated_file.h"; - PathString generatedFilePath = TESTDATA_DIR "/includecollector_generated_file.h"; + ClangBackEnd::FilePathId generatedFilePathId{1, 21}; ProjectPartContainer projectPart1{"project1", {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, - {header1Path.clone()}, - {main1Path.clone()}}; + {{"BAR", "1"}, {"FOO", "1"}}, + {"/includes"}, + {header1PathId}, + {main1PathId}}; ProjectPartContainer projectPart2{"project2", {"-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"}, - {header2Path.clone()}, - {main2Path.clone()}}; + {{"BAR", "1"}, {"FOO", "0"}}, + {"/includes"}, + {header2PathId}, + {main2PathId}}; + ProjectPartContainer projectPart3{"project3", + {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, + {{"BAR", "1"}, {"FOO", "1"}}, + {"/includes", "/other/includes"}, + {header1PathId}, + {main1PathId}}; FileContainers unsaved{{{TESTDATA_DIR, "query_simplefunction.h"}, "void f();", {}}}; - SymbolEntries symbolEntries{{1, {"function", "function"}}}; - SourceLocationEntries sourceLocations{{1, {1, 1}, {42, 23}, SymbolType::Declaration}}; + SymbolEntries symbolEntries{{1, {"function", "function", SymbolKind::Function}}}; + SourceLocationEntries sourceLocations{{1, {1, 1}, {42, 23}, SourceLocationKind::Declaration}}; + FilePathIds sourceFileIds{{1, 1}, {42, 23}}; + UsedMacros usedMacros{{"Foo", {1, 1}}}; + FileStatuses fileStatus{{{1, 2}, 3, 4, false}}; + SourceDependencies sourceDependencies{{{1, 1}, {1, 2}}, {{1, 1}, {1, 3}}}; + ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFOO\"]", "{\"FOO\":\"1\",\"BAR\":\"1\"}", "[\"/includes\"]", 74}; + ClangBackEnd::ProjectPartArtefact emptyArtefact{"", "", "", 74}; + ClangBackEnd::ProjectPartPch projectPartPch{"/path/to/pch", 4}; + NiceMock<MockSqliteTransactionBackend> mockSqliteTransactionBackend; NiceMock<MockSymbolsCollector> mockCollector; NiceMock<MockSymbolStorage> mockStorage; NiceMock<MockClangPathWatcher> mockPathWatcher; - ClangBackEnd::SymbolIndexer indexer{mockCollector, mockStorage, mockPathWatcher}; + ClangBackEnd::FileStatusCache fileStatusCache{filePathCache}; + ClangBackEnd::SymbolIndexer indexer{mockCollector, + mockStorage, + mockPathWatcher, + filePathCache, + fileStatusCache, + mockSqliteTransactionBackend}; }; +std::unique_ptr<Data> SymbolIndexer::data; + TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollector) { - EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePaths(), projectPart1.arguments())); + EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePathIds, projectPart1.arguments)); indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); } -TEST_F(SymbolIndexer, UpdateProjectPartsCallsClearInCollector) +TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithPrecompiledHeaderInCollector) { - EXPECT_CALL(mockCollector, clear()); + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillByDefault(Return(emptyArtefact)); + ON_CALL(mockStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))).WillByDefault(Return(projectPartPch)); + + EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePathIds, + ElementsAre(Eq("-I"), + Eq(TESTDATA_DIR), + Eq("-Wno-pragma-once-outside-header"), + Eq("-Xclang"), + Eq("-include-pch"), + Eq("-Xclang"), + Eq("/path/to/pch")))); + + indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesWithoutPrecompiledHeaderInCollector) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))).WillByDefault(Return(emptyArtefact)); + + EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePathIds, + ElementsAre(Eq("-I"), + Eq(TESTDATA_DIR), + Eq("-Wno-pragma-once-outside-header")))); indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); } +TEST_F(SymbolIndexer, UpdateProjectPartsCallsClearInCollector) +{ + EXPECT_CALL(mockCollector, clear()).Times(2); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddFilesInCollectorForEveryProjectPart) { - EXPECT_CALL(mockCollector, addFiles(_, _)) - .Times(2); + EXPECT_CALL(mockCollector, addFiles(_, _)).Times(2); indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); } @@ -121,37 +227,93 @@ TEST_F(SymbolIndexer, UpdateProjectPartsDoesNotCallAddFilesInCollectorForEmptyEv TEST_F(SymbolIndexer, UpdateProjectPartsCallscollectSymbolsInCollector) { - EXPECT_CALL(mockCollector, collectSymbols()); + EXPECT_CALL(mockCollector, collectSymbols()).Times(2);; - indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); } TEST_F(SymbolIndexer, UpdateProjectPartsCallsSymbolsInCollector) { - EXPECT_CALL(mockCollector, symbols()); + EXPECT_CALL(mockCollector, symbols()).Times(2); - indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); } TEST_F(SymbolIndexer, UpdateProjectPartsCallsSourceLocationsInCollector) { - EXPECT_CALL(mockCollector, sourceLocations()); + EXPECT_CALL(mockCollector, sourceLocations()).Times(2); - indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); } TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddUnsavedFilesInCollector) { - EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved)); + EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved)).Times(2); - indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); } TEST_F(SymbolIndexer, UpdateProjectPartsCallsAddSymbolsAndSourceLocationsInStorage) { - EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(2); + EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)).Times(2); + EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(2); - indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartsInStorage) +{ + EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq("project1"), + ElementsAre("-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"), + ElementsAre(CompilerMacro{"BAR", "1"}, CompilerMacro{"FOO", "1"}), + ElementsAre("/includes"))); + EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq("project2"), + ElementsAre("-I", TESTDATA_DIR, "-x", "c++-header", "-Wno-pragma-once-outside-header"), + ElementsAre(CompilerMacro{"BAR", "1"}, CompilerMacro{"FOO", "0"}), + ElementsAre("/includes"))); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsUpdateProjectPartSources) +{ + EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq<Utils::SmallStringView>("project1"), ElementsAre(IsFileId(1, 1), IsFileId(42, 23)))); + EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq<Utils::SmallStringView>("project2"), ElementsAre(IsFileId(1, 1), IsFileId(42, 23)))); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertOrUpdateUsedMacros) +{ + EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(Eq(usedMacros))) + .Times(2); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertFileStatuses) +{ + EXPECT_CALL(mockStorage, insertFileStatuses(Eq(fileStatus))) + .Times(2); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsInsertOrUpdateSourceDependencies) +{ + EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))) + .Times(2); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); +} + +TEST_F(SymbolIndexer, UpdateProjectPartsCallsFetchProjectPartArtefacts) +{ + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart2.projectPartId))); + + indexer.updateProjectParts({projectPart1, projectPart2}, Utils::clone(unsaved)); } TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) @@ -159,10 +321,18 @@ TEST_F(SymbolIndexer, UpdateProjectPartsCallsInOrder) InSequence s; EXPECT_CALL(mockCollector, clear()); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))); EXPECT_CALL(mockCollector, addFiles(_, _)); EXPECT_CALL(mockCollector, addUnsavedFiles(unsaved)); EXPECT_CALL(mockCollector, collectSymbols()); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockStorage, insertOrUpdateProjectPart(Eq(projectPart1.projectPartId), Eq(projectPart1.arguments), Eq(projectPart1.compilerMacros), Eq(projectPart1.includeSearchPaths))); + EXPECT_CALL(mockStorage, updateProjectPartSources(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId), Eq(sourceFileIds))); + EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(Eq(usedMacros))); + EXPECT_CALL(mockStorage, insertFileStatuses(Eq(fileStatus))); + EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); indexer.updateProjectParts({projectPart1}, Utils::clone(unsaved)); } @@ -171,7 +341,224 @@ TEST_F(SymbolIndexer, CallSetNotifier) { EXPECT_CALL(mockPathWatcher, setNotifier(_)); - ClangBackEnd::SymbolIndexer indexer{mockCollector, mockStorage, mockPathWatcher}; + ClangBackEnd::SymbolIndexer indexer{mockCollector, mockStorage, mockPathWatcher, filePathCache, fileStatusCache, mockSqliteTransactionBackend}; +} + +TEST_F(SymbolIndexer, PathChangedCallsFetchProjectPartArtefactInStorage) +{ + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[1])); + + indexer.pathsChanged(sourceFileIds); +} + +TEST_F(SymbolIndexer, UpdateChangedPathCallsInOrder) +{ + InSequence s; + + EXPECT_CALL(mockCollector, clear()); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])); + EXPECT_CALL(mockCollector, addFiles(ElementsAre(sourceFileIds[0]), Eq(artefact.compilerArguments))); + EXPECT_CALL(mockCollector, collectSymbols()); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()); + EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(symbolEntries, sourceLocations)); + EXPECT_CALL(mockStorage, updateProjectPartSources(artefact.projectPartId, Eq(sourceFileIds))); + EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(Eq(usedMacros))); + EXPECT_CALL(mockStorage, insertFileStatuses(Eq(fileStatus))); + EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(Eq(sourceDependencies))); + EXPECT_CALL(mockSqliteTransactionBackend, commit()); + + indexer.updateChangedPath(sourceFileIds[0]); +} + +TEST_F(SymbolIndexer, HandleEmptyOptionalArtifactInUpdateChangedPath) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillByDefault(Return(emptyArtefact)); + + EXPECT_CALL(mockCollector, clear()); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(sourceFileIds[0])); + EXPECT_CALL(mockCollector, addFiles(_, _)).Times(0); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); + EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(_, _)).Times(0); + EXPECT_CALL(mockStorage, updateProjectPartSources(An<int>(), _)).Times(0); + EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(_)).Times(0); + EXPECT_CALL(mockStorage, insertFileStatuses(_)).Times(0); + EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(_)).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); + + indexer.updateChangedPath(sourceFileIds[0]); +} + +TEST_F(SymbolIndexer, UpdateChangedPathIsUsingPrecompiledHeader) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchPrecompiledHeader(Eq(artefact.projectPartId))) + .WillByDefault(Return(projectPartPch)); + + EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePathIds, + ElementsAre(Eq("-DFOO"), + Eq("-Xclang"), + Eq("-include-pch"), + Eq("-Xclang"), + Eq("/path/to/pch")))); + + indexer.updateChangedPath(sourceFileIds[0]); +} + +TEST_F(SymbolIndexer, UpdateChangedPathIsNotUsingPrecompiledHeaderIfItNotExists) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<FilePathId>(sourceFileIds[0]))) + .WillByDefault(Return(artefact)); + + EXPECT_CALL(mockCollector, addFiles(projectPart1.sourcePathIds, + ElementsAre(Eq("-DFOO")))); + + indexer.updateChangedPath(sourceFileIds[0]); +} + + +TEST_F(SymbolIndexer, CompilerMacrosAndIncludeSearchPathsAreNotDifferent) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + auto areDifferent = indexer.compilerMacrosOrIncludeSearchPathsAreDifferent(projectPart1, + artefact); + + ASSERT_FALSE(areDifferent); +} + +TEST_F(SymbolIndexer, CompilerMacrosAreDifferent) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + auto areDifferent = indexer.compilerMacrosOrIncludeSearchPathsAreDifferent(projectPart2, + artefact); + + ASSERT_TRUE(areDifferent); +} + +TEST_F(SymbolIndexer, IncludeSearchPathsAreDifferent) +{ + ProjectPartContainer projectPart3{"project3", + {"-I", TESTDATA_DIR, "-Wno-pragma-once-outside-header"}, + {{"BAR", "1"}, {"FOO", "1"}}, + {"/includes", "/other/includes"}, + {header1PathId}, + {main1PathId}}; + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + auto areDifferent = indexer.compilerMacrosOrIncludeSearchPathsAreDifferent(projectPart3, + artefact); + + ASSERT_TRUE(areDifferent); +} + +TEST_F(SymbolIndexer, DontReparseInUpdateProjectPartsIfDefinesAreTheSame) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + EXPECT_CALL(mockCollector, clear()); + EXPECT_CALL(mockStorage, fetchProjectPartArtefact(TypedEq<Utils::SmallStringView>(projectPart1.projectPartId))); + EXPECT_CALL(mockCollector, addFiles(_, _)).Times(0); + EXPECT_CALL(mockCollector, collectSymbols()).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, immediateBegin()).Times(0); + EXPECT_CALL(mockStorage, addSymbolsAndSourceLocations(_, _)).Times(0); + EXPECT_CALL(mockStorage, updateProjectPartSources(An<int>(), _)).Times(0); + EXPECT_CALL(mockStorage, insertOrUpdateUsedMacros(_)).Times(0); + EXPECT_CALL(mockStorage, insertFileStatuses(_)).Times(0); + EXPECT_CALL(mockStorage, insertOrUpdateSourceDependencies(_)).Times(0); + EXPECT_CALL(mockSqliteTransactionBackend, commit()).Times(0); + + indexer.updateProjectPart(std::move(projectPart1), {}); +} + +TEST_F(SymbolIndexer, PathsChangedUpdatesFileStatusCache) +{ + auto sourceId = filePathId(TESTDATA_DIR "/symbolindexer_pathChanged.cpp"); + auto oldLastModified = fileStatusCache.lastModifiedTime(sourceId); + touchFile(sourceId); + + indexer.pathsChanged({sourceId}); + + ASSERT_THAT(fileStatusCache.lastModifiedTime(sourceId), Gt(oldLastModified)); +} + +TEST_F(SymbolIndexer, GetUpdatableFilePathIdsIfCompilerMacrosAreDifferent) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + auto filePathIds = indexer.updatableFilePathIds(projectPart2, artefact); + + ASSERT_THAT(filePathIds, projectPart2.sourcePathIds); +} + +TEST_F(SymbolIndexer, GetUpdatableFilePathIdsIfIncludeSearchPathsAreDifferent) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + auto filePathIds = indexer.updatableFilePathIds(projectPart3, artefact); + + ASSERT_THAT(filePathIds, projectPart3.sourcePathIds); +} + +TEST_F(SymbolIndexer, GetNoUpdatableFilePathIdsIfArtefactsAreTheSame) +{ + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + + auto filePathIds = indexer.updatableFilePathIds(projectPart1, artefact); + + ASSERT_THAT(filePathIds, IsEmpty()); +} + +TEST_F(SymbolIndexer, OutdatedFilesPassUpdatableFilePathIds) +{ + indexer.pathsChanged({main1PathId}); + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A<FilePathId>())) + .WillByDefault(Return(0)); + + auto filePathIds = indexer.updatableFilePathIds(projectPart1, artefact); + + ASSERT_THAT(filePathIds, ElementsAre(main1PathId)); +} + +TEST_F(SymbolIndexer, UpToDateFilesDontPassFilteredUpdatableFilePathIds) +{ + indexer.pathsChanged({main1PathId}); + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A<FilePathId>())) + .WillByDefault(Return(QDateTime::currentSecsSinceEpoch())); + + auto filePathIds = indexer.updatableFilePathIds(projectPart1, artefact); + + ASSERT_THAT(filePathIds, IsEmpty()); +} + +TEST_F(SymbolIndexer, OutdatedFilesAreParsedInUpdateProjectParts) +{ + indexer.pathsChanged({main1PathId}); + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A<FilePathId>())) + .WillByDefault(Return(0)); + + EXPECT_CALL(mockCollector, addFiles(ElementsAre(main1PathId), _)); + + indexer.updateProjectParts({projectPart1}, {}); +} + +TEST_F(SymbolIndexer, UpToDateFilesAreNotParsedInUpdateProjectParts) +{ + indexer.pathsChanged({main1PathId}); + ON_CALL(mockStorage, fetchProjectPartArtefact(An<Utils::SmallStringView>())).WillByDefault(Return(artefact)); + ON_CALL(mockStorage, fetchLowestLastModifiedTime(A<FilePathId>())) + .WillByDefault(Return(QDateTime::currentSecsSinceEpoch())); + + EXPECT_CALL(mockCollector, addFiles(_, _)).Times(0); + + indexer.updateProjectParts({projectPart1}, {}); } } diff --git a/tests/unit/unittest/symbolindexing-test.cpp b/tests/unit/unittest/symbolindexing-test.cpp index b5e93e4d6c0..1d6c8d720be 100644 --- a/tests/unit/unittest/symbolindexing-test.cpp +++ b/tests/unit/unittest/symbolindexing-test.cpp @@ -65,14 +65,17 @@ MATCHER_P3(IsLocation, filePathId, line, column, const ClangRefactoring::SourceLocation &location = arg; return location.filePathId == filePathId - && location.line == line - && location.column == column; + && location.lineColumn.line == line + && location.lineColumn.column == column; }; class SymbolIndexing : public testing::Test { protected: - FilePathId filePathId(Utils::SmallString filePath); + FilePathId filePathId(Utils::SmallStringView filePath) + { + return filePathCache.filePathId(ClangBackEnd::FilePathView{filePath}); + } protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; @@ -84,8 +87,10 @@ protected: PathString main1Path = TESTDATA_DIR "/symbolindexing_main1.cpp"; ProjectPartContainer projectPart1{"project1", {"cc", "-I", TESTDATA_DIR, "-std=c++1z"}, + {{"DEFINE", "1"}}, + {"/includes"}, {}, - {main1Path.clone()}}; + {filePathId(main1Path)}}; }; TEST_F(SymbolIndexing, Locations) @@ -110,9 +115,17 @@ TEST_F(SymbolIndexing, DISABLED_TemplateFunction) IsLocation(filePathId(TESTDATA_DIR "/symbolindexing_main1.cpp"), 6, 5))); } -ClangBackEnd::FilePathId SymbolIndexing::filePathId(Utils::SmallString filePath) +TEST_F(SymbolIndexing, PathsAreUpdated) { - return filePathCache.filePathId(ClangBackEnd::FilePathView{filePath}); + indexing.indexer().updateProjectParts({projectPart1}, {}); + + indexing.indexer().pathsChanged({filePathId(main1Path)}); + indexing.indexer().pathsChanged({filePathId(main1Path)}); + auto locations = query.locationsAt(filePathId(TESTDATA_DIR "/symbolindexing_main1.cpp"), 6, 5); + ASSERT_THAT(locations, + ElementsAre( + IsLocation(filePathId(TESTDATA_DIR "/symbolindexing_main1.cpp"), 5, 9), + IsLocation(filePathId(TESTDATA_DIR "/symbolindexing_main1.cpp"), 6, 5))); } } diff --git a/tests/unit/unittest/symbolquery-test.cpp b/tests/unit/unittest/symbolquery-test.cpp index 59e64fb79a2..53eb9d1c686 100644 --- a/tests/unit/unittest/symbolquery-test.cpp +++ b/tests/unit/unittest/symbolquery-test.cpp @@ -40,7 +40,8 @@ namespace { using ClangRefactoring::QuerySqliteStatementFactory; using Sqlite::Database; - +using ClangBackEnd::SourceLocationKind; +using ClangBackEnd::SymbolKind; using MockStatementFactory = QuerySqliteStatementFactory<MockSqliteDatabase, MockSqliteReadStatement>; using MockQuery = ClangRefactoring::SymbolQuery<MockStatementFactory>; @@ -52,44 +53,55 @@ using RealQuery = ClangRefactoring::SymbolQuery<RealStatementFactory>; class SymbolQuery : public testing::Test { protected: + NiceMock<MockSqliteDatabase> mockDatabase; + MockStatementFactory mockStatementFactory{mockDatabase}; + MockSqliteReadStatement &selectLocationsForSymbolLocation = mockStatementFactory.selectLocationsForSymbolLocation; + MockSqliteReadStatement &selectSourceUsagesForSymbolLocation = mockStatementFactory.selectSourceUsagesForSymbolLocation; + MockSqliteReadStatement &selectSymbolsForKindAndStartsWith = mockStatementFactory.selectSymbolsForKindAndStartsWith; + MockSqliteReadStatement &selectSymbolsForKindAndStartsWith2 = mockStatementFactory.selectSymbolsForKindAndStartsWith2; + MockSqliteReadStatement &selectSymbolsForKindAndStartsWith3 = mockStatementFactory.selectSymbolsForKindAndStartsWith3; + MockSqliteReadStatement &selectLocationOfSymbol = mockStatementFactory.selectLocationOfSymbol; + SourceLocations locations{{{1, 1}, 1, 1}, + {{1, 1}, 2, 3}, + {{1, 2}, 1, 1}, + {{1, 2}, 3, 1}, + {{1, 4}, 1, 1}, + {{1, 4}, 1, 3}}; + MockQuery query{mockStatementFactory}; +}; + +class SymbolQuerySlowTest : public testing::Test +{ +protected: void SetUp() override { database.execute("INSERT INTO sources VALUES (1, 1, \"filename.h\", 1)"); database.execute("INSERT INTO sources VALUES (2, 1, \"filename.cpp\", 1)"); database.execute("INSERT INTO directories VALUES (1, \"/path/to\")"); - database.execute("INSERT INTO locations VALUES (1, 2, 3, 1)"); - database.execute("INSERT INTO locations VALUES (1, 4, 6, 2)"); - database.execute("INSERT INTO symbols VALUES (1, \"functionusr\", \"function\")"); + database.execute("INSERT INTO locations VALUES (1, 2, 3, 1, 1)"); + database.execute("INSERT INTO locations VALUES (1, 4, 6, 2, 3)"); + database.execute("INSERT INTO symbols VALUES (1, \"functionusr\", \"Function\", 3, \"void function(int)\")"); + database.execute("INSERT INTO symbols VALUES (2, \"classusr\", \"Class\", 2, \"class Class final\")"); + database.execute("INSERT INTO symbols VALUES (3, \"enumusr\", \"Enum\", 1, \"enum Enum : char\")"); } protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; ClangBackEnd::RefactoringDatabaseInitializer<Sqlite::Database> initializer{database}; RealStatementFactory realStatementFactory{database}; - RealQuery realQuery{realStatementFactory}; - NiceMock<MockSqliteDatabase> mockDatabase; - MockStatementFactory mockStatementFactory{mockDatabase}; - MockSqliteReadStatement &selectLocationsForSymbolLocation = mockStatementFactory.selectLocationsForSymbolLocation; - MockSqliteReadStatement &selectSourceUsagesForSymbolLocation = mockStatementFactory.selectSourceUsagesForSymbolLocation; - SourceLocations locations{{{1, 1}, 1, 1}, - {{1, 1}, 2, 3}, - {{1, 2}, 1, 1}, - {{1, 2}, 3, 1}, - {{1, 4}, 1, 1}, - {{1, 4}, 1, 3}}; - MockQuery mockQuery{mockStatementFactory}; + RealQuery query{realStatementFactory}; }; TEST_F(SymbolQuery, LocationsAtCallsValues) { EXPECT_CALL(selectLocationsForSymbolLocation, valuesReturnSourceLocations(_, 42, 14, 7)); - mockQuery.locationsAt({1, 42}, 14, 7); + query.locationsAt({1, 42}, 14, 7); } -TEST_F(SymbolQuery, LocationsAt) +TEST_F(SymbolQuerySlowTest, LocationsAt) { - auto locations = realQuery.locationsAt({1, 2}, 4, 6); + auto locations = query.locationsAt({1, 2}, 4, 6); ASSERT_THAT(locations, UnorderedElementsAre(SourceLocation({1, 1}, 2, 3), @@ -100,16 +112,85 @@ TEST_F(SymbolQuery, SourceUsagesAtCallsValues) { EXPECT_CALL(selectSourceUsagesForSymbolLocation, valuesReturnSourceUsages(_, 42, 14, 7)); - mockQuery.sourceUsagesAt({1, 42}, 14, 7); + query.sourceUsagesAt({1, 42}, 14, 7); } -TEST_F(SymbolQuery, SourceUsagesAt) +TEST_F(SymbolQuerySlowTest, SourceUsagesAt) { - auto usages = realQuery.sourceUsagesAt({1, 2}, 4, 6); + auto usages = query.sourceUsagesAt({1, 2}, 4, 6); ASSERT_THAT(usages, UnorderedElementsAre(CppTools::Usage("/path/to/filename.h", 2, 3), CppTools::Usage("/path/to/filename.cpp", 4, 6))); } +TEST_F(SymbolQuery, SymbolsCallsValuesWithOneKindParameter) +{ + EXPECT_CALL(selectSymbolsForKindAndStartsWith, valuesReturnSymbols(100, int(SymbolKind::Record), Eq("foo"))); + + query.symbols({SymbolKind::Record}, "foo"); +} + +TEST_F(SymbolQuerySlowTest, SymbolsWithOneKindParameters) +{ + auto symbols = query.symbols({SymbolKind::Record}, "Cla%"); + + ASSERT_THAT(symbols, + UnorderedElementsAre(Symbol{2, "Class", "class Class final"})); +} + +TEST_F(SymbolQuerySlowTest, SymbolsWithEmptyKinds) +{ + auto symbols = query.symbols({}, "%"); + + ASSERT_THAT(symbols, IsEmpty()); +} + +TEST_F(SymbolQuery, SymbolsCallsValuesWithTwoKindParameters) +{ + EXPECT_CALL(selectSymbolsForKindAndStartsWith2, valuesReturnSymbols(100, int(SymbolKind::Record), int(SymbolKind::Function), Eq("foo"))); + + query.symbols({SymbolKind::Record, SymbolKind::Function}, "foo"); +} + +TEST_F(SymbolQuerySlowTest, SymbolsWithTwoKindParameters) +{ + auto symbols = query.symbols({SymbolKind::Record, SymbolKind::Function}, "%c%"); + + ASSERT_THAT(symbols, + UnorderedElementsAre(Symbol{2, "Class", "class Class final"}, + Symbol{1, "Function", "void function(int)"})); +} + +TEST_F(SymbolQuery, SymbolsCallsValuesWithThreeKindParameters) +{ + EXPECT_CALL(selectSymbolsForKindAndStartsWith3, valuesReturnSymbols(100, int(SymbolKind::Record), int(SymbolKind::Function), int(SymbolKind::Enumeration), Eq("foo"))); + + query.symbols({SymbolKind::Record, SymbolKind::Function, SymbolKind::Enumeration}, "foo"); +} + +TEST_F(SymbolQuerySlowTest, SymbolsWithThreeKindParameters) +{ + auto symbols = query.symbols({SymbolKind::Record, SymbolKind::Function, SymbolKind::Enumeration}, "%"); + + ASSERT_THAT(symbols, + UnorderedElementsAre(Symbol{2, "Class", "class Class final"}, + Symbol{1, "Function", "void function(int)"}, + Symbol{3, "Enum", "enum Enum : char"})); +} + +TEST_F(SymbolQuery, LocationForSymbolIdCallsValueReturningSourceLocation) +{ + EXPECT_CALL(selectLocationOfSymbol, valueReturnSourceLocation(1, int(SourceLocationKind::Definition))); + + query.locationForSymbolId(1, SourceLocationKind::Definition); +} + +TEST_F(SymbolQuerySlowTest, LocationForSymbolId) +{ + auto location = query.locationForSymbolId(1, SourceLocationKind::Definition); + + ASSERT_THAT(location.value(), Eq(SourceLocation({1, 2}, {4, 6}))); +} + } diff --git a/tests/unit/unittest/symbolscollector-test.cpp b/tests/unit/unittest/symbolscollector-test.cpp index 4a98306d93f..1dcc4d95c77 100644 --- a/tests/unit/unittest/symbolscollector-test.cpp +++ b/tests/unit/unittest/symbolscollector-test.cpp @@ -28,10 +28,12 @@ #include "filesystem-utilities.h" #include <symbolscollector.h> +#include <filestatus.h> #include <filepathcaching.h> #include <refactoringdatabaseinitializer.h> +#include <QDateTime> #include <QDir> using testing::PrintToString; @@ -48,24 +50,109 @@ using ClangBackEnd::FilePath; using ClangBackEnd::FilePathId; using ClangBackEnd::FilePathCaching; using ClangBackEnd::V2::FileContainers; +using ClangBackEnd::SourceDependency; using ClangBackEnd::SourceLocationEntry; using ClangBackEnd::SymbolEntry; -using ClangBackEnd::SymbolType; +using ClangBackEnd::SymbolKind; +using ClangBackEnd::SymbolTag; +using ClangBackEnd::SourceLocationKind; using ClangBackEnd::SymbolIndex; +using ClangBackEnd::UsedMacro; using Sqlite::Database; namespace { +MATCHER_P5(IsSourceLocationEntry, symbolId, filePathId, line, column, kind, + std::string(negation ? "isn't" : "is") + + PrintToString(SourceLocationEntry{symbolId, filePathId, {line, column}, kind}) + ) +{ + const SourceLocationEntry &entry = arg; + + return entry.filePathId == filePathId + && entry.lineColumn.line == line + && entry.lineColumn.column == column + && entry.kind == kind + && entry.symbolId == symbolId; +} + +MATCHER_P2(HasLineColumn, line, column, + std::string(negation ? "isn't" : "is") + + PrintToString(Utils::LineColumn{line, column}) + ) +{ + const SourceLocationEntry &entry = arg; + + return entry.lineColumn.line == line + && entry.lineColumn.column == column; +} + +MATCHER_P(HasSymbolName, symbolName, + std::string(negation ? "hasn't" : "has") + + " symbol name: " + + symbolName + ) +{ + const SymbolEntry &entry = arg.second; + + return entry.symbolName == symbolName; +} + +MATCHER_P(HasSymbolKind, symbolKind, + std::string(negation ? "hasn't" : "has") + + " and symbol kind: " + + PrintToString(symbolKind) + ) +{ + const SymbolEntry &entry = arg.second; + + return entry.symbolKind == symbolKind; +} + +MATCHER_P(HasSymbolTag, symbolTag, + std::string(negation ? "hasn't" : "has") + + " and symbol tag: " + + PrintToString(symbolTag) + ) +{ + const SymbolEntry &entry = arg.second; + + return entry.symbolTags.contains(symbolTag); +} + class SymbolsCollector : public testing::Test { protected: - FilePathId filePathId(Utils::SmallStringView string) + FilePathId filePathId(Utils::SmallStringView filePath) const + { + return filePathCache.filePathId(ClangBackEnd::FilePathView{filePath}); + } + + static off_t fileSize(Utils::SmallStringView filePath) { - return filePathCache.filePathId(ClangBackEnd::FilePathView{string}); + return QFileInfo(QString(filePath)).size(); } - SymbolIndex symbolIdForSymbolName(const Utils::SmallString &symbolName); + static std::time_t lastModified(Utils::SmallStringView filePath) + { + return QFileInfo(QString(filePath)).lastModified().toTime_t(); + } + + ClangBackEnd::FileStatus fileStatus(Utils::SmallStringView filePath) const + { + return {filePathId(filePath), fileSize(filePath), lastModified(filePath), false}; + } + + SymbolIndex symbolId(const Utils::SmallString &symbolName) + { + for (const auto &entry : collector.symbols()) { + if (entry.second.symbolName == symbolName) + return entry.first; + } + + return 0; + } protected: Sqlite::Database database{":memory:", Sqlite::JournalMode::Memory}; @@ -76,44 +163,41 @@ protected: TEST_F(SymbolsCollector, CollectSymbolName) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); ASSERT_THAT(collector.symbols(), - Contains( - Pair(_, Field(&SymbolEntry::symbolName, "x")))); + Contains(HasSymbolName("x"))); } TEST_F(SymbolsCollector, SymbolMatchesLocation) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); ASSERT_THAT(collector.sourceLocations(), Contains( - AllOf(Field(&SourceLocationEntry::symbolId, symbolIdForSymbolName("function")), - Field(&SourceLocationEntry::line, 1), - Field(&SourceLocationEntry::column, 6)))); + AllOf(Field(&SourceLocationEntry::symbolId, symbolId("function")), + HasLineColumn(1, 6)))); } TEST_F(SymbolsCollector, OtherSymboldMatchesLocation) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); ASSERT_THAT(collector.sourceLocations(), Contains( - AllOf(Field(&SourceLocationEntry::symbolId, symbolIdForSymbolName("function")), - Field(&SourceLocationEntry::line, 2), - Field(&SourceLocationEntry::column, 6)))); + AllOf(Field(&SourceLocationEntry::symbolId, symbolId("function")), + HasLineColumn(2, 6)))); } TEST_F(SymbolsCollector, CollectFilePath) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); @@ -121,46 +205,43 @@ TEST_F(SymbolsCollector, CollectFilePath) Contains( AllOf(Field(&SourceLocationEntry::filePathId, filePathId(TESTDATA_DIR"/symbolscollector_simple.cpp")), - Field(&SourceLocationEntry::symbolType, SymbolType::Declaration)))); + Field(&SourceLocationEntry::kind, SourceLocationKind::Declaration)))); } TEST_F(SymbolsCollector, CollectLineColumn) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); ASSERT_THAT(collector.sourceLocations(), Contains( - AllOf(Field(&SourceLocationEntry::line, 1), - Field(&SourceLocationEntry::column, 6), - Field(&SourceLocationEntry::symbolType, SymbolType::Declaration)))); + AllOf(HasLineColumn(1, 6), + Field(&SourceLocationEntry::kind, SourceLocationKind::Declaration)))); } TEST_F(SymbolsCollector, CollectReference) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); ASSERT_THAT(collector.sourceLocations(), Contains( - AllOf(Field(&SourceLocationEntry::line, 14), - Field(&SourceLocationEntry::column, 5), - Field(&SourceLocationEntry::symbolType, SymbolType::DeclarationReference)))); + AllOf(HasLineColumn(14, 5), + Field(&SourceLocationEntry::kind, SourceLocationKind::DeclarationReference)))); } TEST_F(SymbolsCollector, ReferencedSymboldMatchesLocation) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_simple.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_simple.cpp")}, {"cc"}); collector.collectSymbols(); ASSERT_THAT(collector.sourceLocations(), Contains( - AllOf(Field(&SourceLocationEntry::symbolId, symbolIdForSymbolName("function")), - Field(&SourceLocationEntry::line, 14), - Field(&SourceLocationEntry::column, 5)))); + AllOf(Field(&SourceLocationEntry::symbolId, symbolId("function")), + HasLineColumn(14, 5)))); } TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile)) @@ -168,19 +249,18 @@ TEST_F(SymbolsCollector, DISABLED_ON_WINDOWS(CollectInUnsavedFile)) FileContainers unsaved{{{TESTDATA_DIR, "symbolscollector_generated_file.h"}, "void function();", {}}}; - collector.addFiles({TESTDATA_DIR "/symbolscollector_unsaved.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_unsaved.cpp")}, {"cc"}); collector.addUnsavedFiles(std::move(unsaved)); collector.collectSymbols(); ASSERT_THAT(collector.symbols(), - Contains( - Pair(_, Field(&SymbolEntry::symbolName, "function")))); + Contains(HasSymbolName("function"))); } TEST_F(SymbolsCollector, SourceFiles) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.collectSymbols(); @@ -192,7 +272,7 @@ TEST_F(SymbolsCollector, SourceFiles) TEST_F(SymbolsCollector, MainFileInSourceFiles) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); ASSERT_THAT(collector.sourceFiles(), ElementsAre(filePathId(TESTDATA_DIR "/symbolscollector_main.cpp"))); @@ -200,7 +280,7 @@ TEST_F(SymbolsCollector, MainFileInSourceFiles) TEST_F(SymbolsCollector, ResetMainFileInSourceFiles) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); ASSERT_THAT(collector.sourceFiles(), ElementsAre(filePathId(TESTDATA_DIR "/symbolscollector_main.cpp"))); @@ -208,7 +288,7 @@ TEST_F(SymbolsCollector, ResetMainFileInSourceFiles) TEST_F(SymbolsCollector, DontDuplicateSourceFiles) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.collectSymbols(); collector.collectSymbols(); @@ -221,7 +301,7 @@ TEST_F(SymbolsCollector, DontDuplicateSourceFiles) TEST_F(SymbolsCollector, ClearSourceFiles) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.clear(); @@ -230,7 +310,7 @@ TEST_F(SymbolsCollector, ClearSourceFiles) TEST_F(SymbolsCollector, ClearSymbols) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.collectSymbols(); collector.clear(); @@ -240,7 +320,7 @@ TEST_F(SymbolsCollector, ClearSymbols) TEST_F(SymbolsCollector, ClearSourceLocations) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.collectSymbols(); collector.clear(); @@ -248,9 +328,29 @@ TEST_F(SymbolsCollector, ClearSourceLocations) ASSERT_THAT(collector.sourceLocations(), IsEmpty()); } +TEST_F(SymbolsCollector, ClearFileStatus) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); + collector.collectSymbols(); + + collector.clear(); + + ASSERT_THAT(collector.fileStatuses(), IsEmpty()); +} + +TEST_F(SymbolsCollector, ClearUsedMacros) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_defines.h")}, {"cc"}); + collector.collectSymbols(); + + collector.clear(); + + ASSERT_THAT(collector.usedMacros(), IsEmpty()); +} + TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.clear(); collector.collectSymbols(); @@ -260,7 +360,7 @@ TEST_F(SymbolsCollector, DontCollectSymbolsAfterFilesAreCleared) TEST_F(SymbolsCollector, DontCollectSourceFilesAfterFilesAreCleared) { - collector.addFiles({TESTDATA_DIR "/symbolscollector_main.cpp"}, {"cc"}); + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); collector.clear(); collector.collectSymbols(); @@ -268,14 +368,343 @@ TEST_F(SymbolsCollector, DontCollectSourceFilesAfterFilesAreCleared) ASSERT_THAT(collector.sourceFiles(), IsEmpty()); } -SymbolIndex SymbolsCollector::symbolIdForSymbolName(const Utils::SmallString &symbolName) +TEST_F(SymbolsCollector, DontCollectFileStatusAfterFilesAreCleared) { - for (const auto &entry : collector.symbols()) { - if (entry.second.symbolName == symbolName) - return entry.first; - } + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); + + collector.clear(); + collector.collectSymbols(); + + ASSERT_THAT(collector.fileStatuses(), IsEmpty()); +} + +TEST_F(SymbolsCollector, DontCollectUsedMacrosAfterFilesAreCleared) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_main.cpp")}, {"cc"}); + + collector.clear(); + collector.collectSymbols(); + + ASSERT_THAT(collector.usedMacros(), IsEmpty()); +} + +TEST_F(SymbolsCollector, CollectUsedMacrosWithExternalDefine) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.usedMacros(), + ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), + Eq(UsedMacro{"IF_DEFINE", fileId}), + Eq(UsedMacro{"__clang__", fileId}), + Eq(UsedMacro{"CLASS_EXPORT", fileId}), + Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), + Eq(UsedMacro{"MACRO_EXPANSION", fileId}), + Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); +} + +TEST_F(SymbolsCollector, CollectUsedMacrosWithoutExternalDefine) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.usedMacros(), + ElementsAre(Eq(UsedMacro{"DEFINED", fileId}), + Eq(UsedMacro{"IF_DEFINE", fileId}), + Eq(UsedMacro{"__clang__", fileId}), + Eq(UsedMacro{"CLASS_EXPORT", fileId}), + Eq(UsedMacro{"IF_NOT_DEFINE", fileId}), + Eq(UsedMacro{"MACRO_EXPANSION", fileId}), + Eq(UsedMacro{"COMPILER_ARGUMENT", fileId}))); +} + +TEST_F(SymbolsCollector, DontCollectHeaderGuards) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.usedMacros(), + Not(Contains(Eq(UsedMacro{"SYMBOLSCOLLECTOR_DEFINES_H", fileId})))); +} + +TEST_F(SymbolsCollector, DISABLED_DontCollectDynamicLibraryExports) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.usedMacros(), + Not(Contains(Eq(UsedMacro{"CLASS_EXPORT", fileId})))); +} + +TEST_F(SymbolsCollector, CollectMacroDefinitionSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 4, 9, SourceLocationKind::MacroDefinition))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageInIfNotDefSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 6, 9, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectSecondMacroUsageInIfNotDefSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("IF_NOT_DEFINE"), fileId, 9, 9, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageCompilerArgumentSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("COMPILER_ARGUMENT"), fileId, 12, 9, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageInIfDefSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); - return 0; + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("IF_DEFINE"), fileId, 17, 8, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageInDefinedSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("DEFINED"), fileId, 22, 13, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageExpansionSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("MACRO_EXPANSION"), fileId, 27, 10, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageUndefSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("UN_DEFINE"), fileId, 34, 8, SourceLocationKind::MacroUndefinition))); +} + +TEST_F(SymbolsCollector, CollectMacroUsageBuiltInSourceLocation) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceLocations(), + Contains(IsSourceLocationEntry(symbolId("__clang__"), fileId, 29, 9, SourceLocationKind::MacroUsage))); +} + +TEST_F(SymbolsCollector, CollectMacroDefinitionSymbols) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains(AllOf(HasSymbolName("IF_NOT_DEFINE"), HasSymbolKind(SymbolKind::Macro)))); +} + +TEST_F(SymbolsCollector, CollectMacroBuiltInSymbols) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains(AllOf(HasSymbolName("__clang__"), HasSymbolKind(SymbolKind::Macro)))); +} + +TEST_F(SymbolsCollector, CollectMacroCompilerArgumentSymbols) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_defines.h"); + collector.addFiles({fileId}, {"cc", "-DCOMPILER_ARGUMENT"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains(AllOf(HasSymbolName("COMPILER_ARGUMENT"), HasSymbolKind(SymbolKind::Macro)))); +} + +TEST_F(SymbolsCollector, CollectFileStatuses) +{ + auto fileId = filePathId(TESTDATA_DIR "/symbolscollector_main.cpp"); + collector.addFiles({fileId}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.fileStatuses(), + ElementsAre( + fileStatus(TESTDATA_DIR "/symbolscollector_main.cpp"), + fileStatus(TESTDATA_DIR "/symbolscollector_header1.h"), + fileStatus(TESTDATA_DIR "/symbolscollector_header2.h"))); +} + +TEST_F(SymbolsCollector, CollectSourceDependencies) +{ + auto mainFileId = filePathId(TESTDATA_DIR "/symbolscollector_main2.cpp"); + auto header1FileId = filePathId(TESTDATA_DIR "/symbolscollector_header1.h"); + auto header2FileId = filePathId(TESTDATA_DIR "/symbolscollector_header2.h"); + auto header3FileId = filePathId(TESTDATA_DIR "/symbolscollector_header3.h"); + collector.addFiles({mainFileId}, {"cc", "-I" TESTDATA_DIR}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.sourceDependencies(), + UnorderedElementsAre(SourceDependency(mainFileId, header1FileId), + SourceDependency(mainFileId, header3FileId), + SourceDependency(header3FileId, header2FileId), + SourceDependency(header1FileId, header2FileId))); +} + +TEST_F(SymbolsCollector, IsClassSymbol) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains( + AllOf( + HasSymbolName("Class"), + HasSymbolKind(SymbolKind::Record), + HasSymbolTag(SymbolTag::Class)))); +} + +TEST_F(SymbolsCollector, IsStructSymbol) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains( + AllOf( + HasSymbolName("Struct"), + HasSymbolKind(SymbolKind::Record), + HasSymbolTag(SymbolTag::Struct)))); +} + +TEST_F(SymbolsCollector, IsEnumerationSymbol) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + AllOf( + Contains( + AllOf( + HasSymbolName("Enumeration"), + HasSymbolKind(SymbolKind::Enumeration))), + Contains( + AllOf( + HasSymbolName("ScopedEnumeration"), + HasSymbolKind(SymbolKind::Enumeration))))); +} + +TEST_F(SymbolsCollector, IsUnionSymbol) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains( + AllOf( + HasSymbolName("Union"), + HasSymbolKind(SymbolKind::Record), + HasSymbolTag(SymbolTag::Union)))); +} + +TEST_F(SymbolsCollector, DISABLED_ON_NON_WINDOWS(IsMsvcInterfaceSymbol)) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains( + AllOf( + HasSymbolName("MsvcInterface"), + HasSymbolKind(SymbolKind::Record), + HasSymbolTag(SymbolTag::MsvcInterface)))); +} + +TEST_F(SymbolsCollector, IsFunctionSymbol) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains( + AllOf( + HasSymbolName("Function"), + HasSymbolKind(SymbolKind::Function)))); +} + +TEST_F(SymbolsCollector, IsVariableSymbol) +{ + collector.addFiles({filePathId(TESTDATA_DIR "/symbolscollector_symbolkind.cpp")}, {"cc"}); + + collector.collectSymbols(); + + ASSERT_THAT(collector.symbols(), + Contains( + AllOf( + HasSymbolName("Variable"), + HasSymbolKind(SymbolKind::Variable)))); } } diff --git a/tests/unit/unittest/symbolsfindfilter-test.cpp b/tests/unit/unittest/symbolsfindfilter-test.cpp new file mode 100644 index 00000000000..fad174dfceb --- /dev/null +++ b/tests/unit/unittest/symbolsfindfilter-test.cpp @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2017 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 <clangrefactoring/symbolsfindfilter.h> + +namespace { + +class SymbolsFindFilter : public ::testing::Test +{ +protected: + ClangRefactoring::SymbolsFindFilter symbolsFindFilter; +}; + +TEST_F(SymbolsFindFilter, FindAll) +{ + symbolsFindFilter.findAll("*", Core::FindRegularExpression); +} + +} diff --git a/tests/unit/unittest/symbolstorage-test.cpp b/tests/unit/unittest/symbolstorage-test.cpp index 0f93e210a70..95fa71c2797 100644 --- a/tests/unit/unittest/symbolstorage-test.cpp +++ b/tests/unit/unittest/symbolstorage-test.cpp @@ -26,8 +26,7 @@ #include "googletest.h" #include "mockfilepathcaching.h" -#include "mocksqlitereadstatement.h" -#include "mocksqlitewritestatement.h" +#include "mocksqlitedatabase.h" #include <storagesqlitestatementfactory.h> #include <symbolstorage.h> @@ -35,33 +34,32 @@ #include <storagesqlitestatementfactory.h> +#include <utils/optional.h> + namespace { using Utils::PathString; +using ClangBackEnd::FilePathId; using ClangBackEnd::FilePathCachingInterface; using ClangBackEnd::SymbolEntries; using ClangBackEnd::SymbolEntry; using ClangBackEnd::SourceLocationEntries; using ClangBackEnd::SourceLocationEntry; using ClangBackEnd::StorageSqliteStatementFactory; -using ClangBackEnd::SymbolType; +using ClangBackEnd::SymbolIndex; +using ClangBackEnd::SourceLocationKind; +using ClangBackEnd::SymbolKind; using Sqlite::Database; using Sqlite::Table; -using StatementFactory = StorageSqliteStatementFactory<MockSqliteDatabase, - MockSqliteReadStatement, - MockSqliteWriteStatement>; +using StatementFactory = StorageSqliteStatementFactory<MockSqliteDatabase>; using Storage = ClangBackEnd::SymbolStorage<StatementFactory>; class SymbolStorage : public testing::Test { protected: - void SetUp(); - -protected: MockFilePathCaching filePathCache; - NiceMock<MockMutex> mockMutex; - NiceMock<MockSqliteDatabase> mockDatabase{mockMutex}; + NiceMock<MockSqliteDatabase> mockDatabase; StatementFactory statementFactory{mockDatabase}; MockSqliteWriteStatement &insertSymbolsToNewSymbolsStatement = statementFactory.insertSymbolsToNewSymbolsStatement; MockSqliteWriteStatement &insertLocationsToNewLocationsStatement = statementFactory.insertLocationsToNewLocationsStatement; @@ -73,10 +71,30 @@ protected: MockSqliteWriteStatement &insertNewLocationsInLocationsStatement = statementFactory.insertNewLocationsInLocationsStatement; MockSqliteWriteStatement &deleteNewSymbolsTableStatement = statementFactory.deleteNewSymbolsTableStatement; MockSqliteWriteStatement &deleteNewLocationsTableStatement = statementFactory.deleteNewLocationsTableStatement; - SymbolEntries symbolEntries{{1, {"functionUSR", "function"}}, - {2, {"function2USR", "function2"}}}; - SourceLocationEntries sourceLocations{{1, {1, 3}, {42, 23}, SymbolType::Declaration}, - {2, {1, 4}, {7, 11}, SymbolType::Declaration}}; + MockSqliteWriteStatement &insertProjectPartStatement = statementFactory.insertProjectPartStatement; + MockSqliteWriteStatement &updateProjectPartStatement = statementFactory.updateProjectPartStatement; + MockSqliteReadStatement &getProjectPartIdStatement = statementFactory.getProjectPartIdStatement; + MockSqliteWriteStatement &deleteAllProjectPartsSourcesWithProjectPartIdStatement = statementFactory.deleteAllProjectPartsSourcesWithProjectPartIdStatement; + MockSqliteWriteStatement &insertProjectPartSourcesStatement = statementFactory.insertProjectPartSourcesStatement; + MockSqliteWriteStatement &insertIntoNewUsedMacrosStatement = statementFactory.insertIntoNewUsedMacrosStatement; + MockSqliteWriteStatement &syncNewUsedMacrosStatement = statementFactory.syncNewUsedMacrosStatement; + MockSqliteWriteStatement &deleteOutdatedUsedMacrosStatement = statementFactory.deleteOutdatedUsedMacrosStatement; + MockSqliteWriteStatement &deleteNewUsedMacrosTableStatement = statementFactory.deleteNewUsedMacrosTableStatement; + MockSqliteWriteStatement &insertFileStatuses = statementFactory.insertFileStatuses; + MockSqliteWriteStatement &insertIntoNewSourceDependenciesStatement = statementFactory.insertIntoNewSourceDependenciesStatement; + MockSqliteWriteStatement &syncNewSourceDependenciesStatement = statementFactory.syncNewSourceDependenciesStatement; + MockSqliteWriteStatement &deleteOutdatedSourceDependenciesStatement = statementFactory.deleteOutdatedSourceDependenciesStatement; + MockSqliteWriteStatement &deleteNewSourceDependenciesStatement = statementFactory.deleteNewSourceDependenciesStatement; + MockSqliteReadStatement &getProjectPartArtefactsBySourceId = statementFactory.getProjectPartArtefactsBySourceId; + MockSqliteReadStatement &getProjectPartArtefactsByProjectPartName = statementFactory.getProjectPartArtefactsByProjectPartName; + MockSqliteReadStatement &getLowestLastModifiedTimeOfDependencies = statementFactory.getLowestLastModifiedTimeOfDependencies; + MockSqliteReadStatement &getPrecompiledHeader = statementFactory.getPrecompiledHeader; + + SymbolEntries symbolEntries{{1, {"functionUSR", "function", SymbolKind::Function}}, + {2, {"function2USR", "function2", SymbolKind::Function}}}; + SourceLocationEntries sourceLocations{{1, {1, 3}, {42, 23}, SourceLocationKind::Declaration}, + {2, {1, 4}, {7, 11}, SourceLocationKind::Definition}}; + ClangBackEnd::ProjectPartArtefact artefact{"[\"-DFOO\"]", "{\"FOO\":\"1\"}", "[\"/includes\"]", 74}; Storage storage{statementFactory, filePathCache}; }; @@ -84,8 +102,8 @@ TEST_F(SymbolStorage, CreateAndFillTemporaryLocationsTable) { InSequence sequence; - EXPECT_CALL(insertLocationsToNewLocationsStatement, write(1, 42, 23, 3)); - EXPECT_CALL(insertLocationsToNewLocationsStatement, write(2, 7, 11, 4)); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(TypedEq<SymbolIndex>(1), TypedEq<int>(42), TypedEq<int>(23), TypedEq<int>(3), TypedEq<int>(int(SourceLocationKind::Declaration)))); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(TypedEq<SymbolIndex>(2), TypedEq<int>(7), TypedEq<int>(11), TypedEq<int>(4), TypedEq<int>(int(SourceLocationKind::Definition)))); storage.fillTemporaryLocationsTable(sourceLocations); } @@ -143,11 +161,9 @@ TEST_F(SymbolStorage, AddSymbolsAndSourceLocationsCallsWrite) { InSequence sequence; - EXPECT_CALL(mockMutex, lock()); - EXPECT_CALL(mockDatabase, execute(Eq("BEGIN IMMEDIATE"))); - EXPECT_CALL(insertSymbolsToNewSymbolsStatement, write(_, _, _)).Times(2); - EXPECT_CALL(insertLocationsToNewLocationsStatement, write(1, 42, 23, 3)); - EXPECT_CALL(insertLocationsToNewLocationsStatement, write(2, 7, 11, 4)); + EXPECT_CALL(insertSymbolsToNewSymbolsStatement, write(An<uint>(), An<Utils::SmallStringView>(), An<Utils::SmallStringView>(), An<uint>())).Times(2); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(TypedEq<SymbolIndex>(1), TypedEq<int>(42), TypedEq<int>(23), TypedEq<int>(3), TypedEq<int>(int(SourceLocationKind::Declaration)))); + EXPECT_CALL(insertLocationsToNewLocationsStatement, write(TypedEq<SymbolIndex>(2), TypedEq<int>(7), TypedEq<int>(11), TypedEq<int>(4), TypedEq<int>(int(SourceLocationKind::Definition)))); EXPECT_CALL(addNewSymbolsToSymbolsStatement, execute()); EXPECT_CALL(syncNewSymbolsFromSymbolsStatement, execute()); EXPECT_CALL(syncSymbolsIntoNewLocationsStatement, execute()); @@ -155,14 +171,175 @@ TEST_F(SymbolStorage, AddSymbolsAndSourceLocationsCallsWrite) EXPECT_CALL(insertNewLocationsInLocationsStatement, execute()); EXPECT_CALL(deleteNewSymbolsTableStatement, execute()); EXPECT_CALL(deleteNewLocationsTableStatement, execute()); - EXPECT_CALL(mockDatabase, execute(Eq("COMMIT"))); - EXPECT_CALL(mockMutex, unlock()); storage.addSymbolsAndSourceLocations(symbolEntries, sourceLocations); } -void SymbolStorage::SetUp() +TEST_F(SymbolStorage, ConvertStringsToJson) +{ + Utils::SmallStringVector strings{"foo", "bar", "foo"}; + + auto jsonText = storage.toJson(strings); + + ASSERT_THAT(jsonText, Eq("[\"foo\",\"bar\",\"foo\"]")); +} + +TEST_F(SymbolStorage, InsertProjectPart) +{ + InSequence sequence; + ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(1)); + + EXPECT_CALL(mockDatabase, setLastInsertedRowId(-1)); + EXPECT_CALL(insertProjectPartStatement, + write(TypedEq<Utils::SmallStringView>("project"), + TypedEq<Utils::SmallStringView>("[\"foo\"]"), + TypedEq<Utils::SmallStringView>("{\"FOO\":\"1\"}"), + TypedEq<Utils::SmallStringView>("[\"/includes\"]"))); + EXPECT_CALL(mockDatabase, lastInsertedRowId()); + + storage.insertOrUpdateProjectPart("project", {"foo"}, {{"FOO", "1"}}, {"/includes"}); +} + +TEST_F(SymbolStorage, UpdateProjectPart) +{ + InSequence sequence; + ON_CALL(mockDatabase, lastInsertedRowId()).WillByDefault(Return(-1)); + + EXPECT_CALL(mockDatabase, setLastInsertedRowId(-1)); + EXPECT_CALL(insertProjectPartStatement, + write(TypedEq<Utils::SmallStringView>("project"), + TypedEq<Utils::SmallStringView>("[\"foo\"]"), + TypedEq<Utils::SmallStringView>("{\"FOO\":\"1\"}"), + TypedEq<Utils::SmallStringView>("[\"/includes\"]"))); + EXPECT_CALL(mockDatabase, lastInsertedRowId()); + EXPECT_CALL(updateProjectPartStatement, + write(TypedEq<Utils::SmallStringView>("[\"foo\"]"), + TypedEq<Utils::SmallStringView>("{\"FOO\":\"1\"}"), + TypedEq<Utils::SmallStringView>("[\"/includes\"]"), + TypedEq<Utils::SmallStringView>("project"))); + + storage.insertOrUpdateProjectPart("project", {"foo"}, {{"FOO", "1"}}, {"/includes"}); +} + +TEST_F(SymbolStorage, UpdateProjectPartSources) +{ + InSequence sequence; + + EXPECT_CALL(getProjectPartIdStatement, valueReturnInt32(TypedEq<Utils::SmallStringView>("project"))).WillRepeatedly(Return(42)); + EXPECT_CALL(deleteAllProjectPartsSourcesWithProjectPartIdStatement, write(TypedEq<int>(42))); + EXPECT_CALL(insertProjectPartSourcesStatement, write(TypedEq<int>(42), TypedEq<int>(1))); + EXPECT_CALL(insertProjectPartSourcesStatement, write(TypedEq<int>(42), TypedEq<int>(2))); + + storage.updateProjectPartSources("project", {{1, 1}, {1, 2}}); +} + +TEST_F(SymbolStorage, InsertOrUpdateUsedMacros) +{ + InSequence sequence; + + EXPECT_CALL(insertIntoNewUsedMacrosStatement, write(TypedEq<uint>(42u), TypedEq<Utils::SmallStringView>("FOO"))); + EXPECT_CALL(insertIntoNewUsedMacrosStatement, write(TypedEq<uint>(43u), TypedEq<Utils::SmallStringView>("BAR"))); + EXPECT_CALL(syncNewUsedMacrosStatement, execute()); + EXPECT_CALL(deleteOutdatedUsedMacrosStatement, execute()); + EXPECT_CALL(deleteNewUsedMacrosTableStatement, execute()); + + storage.insertOrUpdateUsedMacros({{"FOO", {1, 42}}, {"BAR", {1, 43}}}); +} + +TEST_F(SymbolStorage, InsertFileStatuses) +{ + EXPECT_CALL(insertFileStatuses, write(TypedEq<int>(42), TypedEq<off_t>(1), TypedEq<time_t>(2), TypedEq<bool>(false))); + EXPECT_CALL(insertFileStatuses, write(TypedEq<int>(43), TypedEq<off_t>(4), TypedEq<time_t>(5), TypedEq<bool>(true))); + + storage.insertFileStatuses({{{1, 42}, 1, 2, false}, {{1, 43}, 4, 5, true}}); +} + +TEST_F(SymbolStorage, InsertOrUpdateSourceDependencies) { + InSequence sequence; + + EXPECT_CALL(insertIntoNewSourceDependenciesStatement, write(TypedEq<int>(42), TypedEq<int>(1))); + EXPECT_CALL(insertIntoNewSourceDependenciesStatement, write(TypedEq<int>(42), TypedEq<int>(2))); + EXPECT_CALL(syncNewSourceDependenciesStatement, execute()); + EXPECT_CALL(deleteOutdatedSourceDependenciesStatement, execute()); + EXPECT_CALL(deleteNewSourceDependenciesStatement, execute()); + + storage.insertOrUpdateSourceDependencies({{{1, 42}, {1, 1}}, {{1, 42}, {1, 2}}}); } + +TEST_F(SymbolStorage, FetchProjectPartArtefactBySourceIdCallsValueInStatement) +{ + EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1)) + .WillRepeatedly(Return(artefact)); + + storage.fetchProjectPartArtefact({2, 1}); +} + +TEST_F(SymbolStorage, FetchProjectPartArtefactBySourceIdReturnArtefact) +{ + EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1)) + .WillRepeatedly(Return(artefact)); + + auto result = storage.fetchProjectPartArtefact({2, 1}); + + ASSERT_THAT(result, Eq(artefact)); +} + +TEST_F(SymbolStorage, FetchProjectPartArtefactByProjectNameCallsValueInStatement) +{ + EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1)) + .WillRepeatedly(Return(artefact)); + + storage.fetchProjectPartArtefact({2, 1}); +} + +TEST_F(SymbolStorage, FetchProjectPartArtefactByProjectNameReturnArtefact) +{ + EXPECT_CALL(getProjectPartArtefactsBySourceId, valueReturnProjectPartArtefact(1)) + .WillRepeatedly(Return(artefact)); + + auto result = storage.fetchProjectPartArtefact({2, 1}); + + ASSERT_THAT(result, Eq(artefact)); +} + +TEST_F(SymbolStorage, FetchLowestLastModifiedTimeIfNoModificationTimeExists) +{ + EXPECT_CALL(getLowestLastModifiedTimeOfDependencies, valueReturnInt64(Eq(1))); + + auto lowestLastModified = storage.fetchLowestLastModifiedTime({1, 1}); + + ASSERT_THAT(lowestLastModified, Eq(0)); +} + +TEST_F(SymbolStorage, FetchLowestLastModifiedTime) +{ + EXPECT_CALL(getLowestLastModifiedTimeOfDependencies, valueReturnInt64(Eq(21))) + .WillRepeatedly(Return(12)); + + auto lowestLastModified = storage.fetchLowestLastModifiedTime({1, 21}); + + ASSERT_THAT(lowestLastModified, Eq(12)); +} +TEST_F(SymbolStorage, FetchPrecompiledHeaderCallsValueInStatement) +{ + EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))); + + storage.fetchPrecompiledHeader(25); +} + +TEST_F(SymbolStorage, FetchPrecompiledHeader) +{ + ClangBackEnd::ProjectPartPch pch{"", "/path/to/pch", 131}; + EXPECT_CALL(getPrecompiledHeader, valueReturnProjectPartPch(Eq(25))) + .WillRepeatedly(Return(pch)); + + auto precompiledHeader = storage.fetchPrecompiledHeader(25); + + ASSERT_THAT(precompiledHeader.value(), Eq(pch)); +} + + + } diff --git a/tests/unit/unittest/tokeninfos-test.cpp b/tests/unit/unittest/tokeninfos-test.cpp deleted file mode 100644 index d3e249c3291..00000000000 --- a/tests/unit/unittest/tokeninfos-test.cpp +++ /dev/null @@ -1,1281 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 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 "testenvironment.h" - -#include <clangdocument.h> -#include <clangdocuments.h> -#include <clangtranslationunit.h> -#include <cursor.h> -#include <clangsupport_global.h> -#include <clangstring.h> -#include <projectpart.h> -#include <projects.h> -#include <sourcelocation.h> -#include <sourcerange.h> -#include <tokeninfo.h> -#include <tokeninfos.h> -#include <unsavedfiles.h> - -#include <clang-c/Index.h> - -using ClangBackEnd::Cursor; -using ClangBackEnd::HighlightingTypes; -using ClangBackEnd::TokenInfo; -using ClangBackEnd::TokenInfos; -using ClangBackEnd::HighlightingType; -using ClangBackEnd::Document; -using ClangBackEnd::Documents; -using ClangBackEnd::TranslationUnit; -using ClangBackEnd::UnsavedFiles; -using ClangBackEnd::ProjectPart; -using ClangBackEnd::ClangString; -using ClangBackEnd::SourceRange; - -using testing::PrintToString; -using testing::IsNull; -using testing::NotNull; -using testing::Gt; -using testing::Contains; -using testing::ElementsAre; -using testing::_; -using testing::EndsWith; -using testing::AllOf; -using testing::Not; -using testing::IsEmpty; -using testing::SizeIs; - -namespace { - -MATCHER_P4(IsHighlightingMark, line, column, length, type, - std::string(negation ? "isn't " : "is ") - + PrintToString(TokenInfo(line, column, length, type)) - ) -{ - const TokenInfo expected(line, column, length, type); - - return arg == expected; -} - -MATCHER_P(HasOnlyType, type, - std::string(negation ? "isn't " : "is ") - + PrintToString(type) - ) -{ - return arg.hasOnlyType(type); -} - -MATCHER_P2(HasTwoTypes, firstType, secondType, - std::string(negation ? "isn't " : "is ") - + PrintToString(firstType) - + " and " - + PrintToString(secondType) - ) -{ - return arg.hasMainType(firstType) && arg.hasMixinTypeAt(0, secondType) && arg.mixinSize() == 1; -} - -MATCHER_P3(HasThreeTypes, firstType, secondType, thirdType, - std::string(negation ? "isn't " : "is ") - + PrintToString(firstType) - + ", " - + PrintToString(secondType) - + " and " - + PrintToString(thirdType) - ) -{ - return arg.hasMainType(firstType) && arg.hasMixinTypeAt(0, secondType) && arg.hasMixinTypeAt(1, thirdType) && arg.mixinSize() == 2; -} - -MATCHER_P(HasMixin, mixinType, - std::string(negation ? "isn't " : "is ") - + PrintToString(mixinType) - ) -{ - return arg.hasMixinType(mixinType); -} - -struct Data { - Data() - { - document.parse(); - } - - ClangBackEnd::ProjectParts projects; - ClangBackEnd::UnsavedFiles unsavedFiles; - ClangBackEnd::Documents documents{projects, unsavedFiles}; - Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/highlightingmarks.cpp")}; - Document document{filePath, - ProjectPart(Utf8StringLiteral("projectPartId"), - TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14"), - Utf8StringLiteral("-I" TESTDATA_DIR)})), - {}, - documents}; - TranslationUnit translationUnit{filePath, - filePath, - document.translationUnit().cxIndex(), - document.translationUnit().cxTranslationUnit()}; -}; - -class TokenInfos : public ::testing::Test -{ -public: - static void SetUpTestCase(); - static void TearDownTestCase(); - - SourceRange sourceRange(uint line, uint columnEnd) const; - -protected: - static Data *d; - const TranslationUnit &translationUnit = d->translationUnit; -}; - -TEST_F(TokenInfos, CreateNullInformations) -{ - ::TokenInfos infos; - - ASSERT_TRUE(infos.isNull()); -} - -TEST_F(TokenInfos, NullInformationsAreEmpty) -{ - ::TokenInfos infos; - - ASSERT_TRUE(infos.isEmpty()); -} - -TEST_F(TokenInfos, IsNotNull) -{ - const auto aRange = translationUnit.sourceRange(3, 1, 5, 1); - - const auto infos = translationUnit.tokenInfosInRange(aRange); - - ASSERT_FALSE(infos.isNull()); -} - -TEST_F(TokenInfos, IteratorBeginEnd) -{ - const auto aRange = translationUnit.sourceRange(3, 1, 5, 1); - const auto infos = translationUnit.tokenInfosInRange(aRange); - - const auto endIterator = std::next(infos.begin(), infos.size()); - - ASSERT_THAT(infos.end(), endIterator); -} - -TEST_F(TokenInfos, ForFullTranslationUnitRange) -{ - const auto infos = translationUnit.tokenInfos(); - - ASSERT_THAT(infos, AllOf(Contains(IsHighlightingMark(1u, 1u, 4u, HighlightingType::Keyword)), - Contains(IsHighlightingMark(277u, 5u, 15u, HighlightingType::Function)))); -} - -TEST_F(TokenInfos, Size) -{ - const auto range = translationUnit.sourceRange(5, 5, 5, 10); - - const auto infos = translationUnit.tokenInfosInRange(range); - - ASSERT_THAT(infos.size(), 1); -} - -TEST_F(TokenInfos, DISABLED_Keyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(5, 12)); - - ASSERT_THAT(infos[0], IsHighlightingMark(5u, 5u, 6u, HighlightingType::Keyword)); -} - -TEST_F(TokenInfos, StringLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(1, 29)); - - ASSERT_THAT(infos[4], IsHighlightingMark(1u, 24u, 10u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenInfos, Utf8StringLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(2, 33)); - - ASSERT_THAT(infos[4], IsHighlightingMark(2u, 24u, 12u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenInfos, RawStringLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(3, 34)); - - ASSERT_THAT(infos[4], IsHighlightingMark(3u, 24u, 13u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenInfos, CharacterLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(4, 28)); - - ASSERT_THAT(infos[3], IsHighlightingMark(4u, 24u, 3u, HighlightingType::StringLiteral)); -} - -TEST_F(TokenInfos, IntegerLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(23, 26)); - - ASSERT_THAT(infos[3], IsHighlightingMark(23u, 24u, 1u, HighlightingType::NumberLiteral)); -} - -TEST_F(TokenInfos, FloatLiteral) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(24, 29)); - - ASSERT_THAT(infos[3], IsHighlightingMark(24u, 24u, 4u, HighlightingType::NumberLiteral)); -} - -TEST_F(TokenInfos, FunctionDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(45, 20)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenInfos, MemberFunctionDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(52, 29)); - - ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenInfos, VirtualMemberFunctionDefinitionOutsideOfClassBody) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(586, 37)); - - ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenInfos, VirtualMemberFunctionDefinitionInsideOfClassBody) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(589, 47)); - - ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); -} - -TEST_F(TokenInfos, FunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(55, 32)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenInfos, MemberFunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(59, 27)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenInfos, MemberFunctionReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(104, 35)); - - ASSERT_THAT(infos[0], IsHighlightingMark(104u, 9u, 23u, HighlightingType::Function)); -} - -TEST_F(TokenInfos, FunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(64, 16)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, TypeConversionFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(68, 20)); - - ASSERT_THAT(infos[1], IsHighlightingMark(68u, 14u, 3u, HighlightingType::Type)); -} - -TEST_F(TokenInfos, InbuiltTypeConversionFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(69, 20)); - - ASSERT_THAT(infos[1], IsHighlightingMark(69u, 14u, 3u, HighlightingType::PrimitiveType)); -} - -TEST_F(TokenInfos, TypeReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(74, 13)); - - ASSERT_THAT(infos[0], IsHighlightingMark(74u, 5u, 3u, HighlightingType::Type)); -} - -TEST_F(TokenInfos, LocalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(79, 13)); - - ASSERT_THAT(infos[1], IsHighlightingMark(79u, 9u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, LocalVariableDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(79, 13)); - - ASSERT_THAT(infos[1], IsHighlightingMark(79u, 9u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, LocalVariableReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(81, 26)); - - ASSERT_THAT(infos[0], IsHighlightingMark(81u, 5u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, LocalVariableFunctionArgumentDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(84, 45)); - - ASSERT_THAT(infos[5], IsHighlightingMark(84u, 41u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, LocalVariableFunctionArgumentReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(86, 26)); - - ASSERT_THAT(infos[0], IsHighlightingMark(86u, 5u, 3u, HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, ClassVariableDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(90, 21)); - - ASSERT_THAT(infos[1], IsHighlightingMark(90u, 9u, 11u, HighlightingType::Field)); -} - -TEST_F(TokenInfos, ClassVariableReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(94, 23)); - - ASSERT_THAT(infos[0], IsHighlightingMark(94u, 9u, 11u, HighlightingType::Field)); -} - -TEST_F(TokenInfos, StaticMethodDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(110, 25)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenInfos, StaticMethodReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(114, 30)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, Enumeration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(118, 17)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, Enumerator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(120, 15)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Enumeration)); -} - -TEST_F(TokenInfos, EnumerationReferenceDeclarationType) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, EnumerationReferenceDeclarationVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, EnumerationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(127, 30)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, EnumeratorReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(127, 30)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Enumeration)); -} - -TEST_F(TokenInfos, ClassForwardDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(130, 12)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, ConstructorDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(134, 13)); - - ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenInfos, DestructorDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(135, 15)); - - ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); -} - -TEST_F(TokenInfos, ClassForwardDeclarationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(138, 23)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, ClassTypeReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, ConstructorReferenceVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, UnionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(145, 12)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, UnionDeclarationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, GlobalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::GlobalVariable)); -} - -TEST_F(TokenInfos, StructDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(50, 11)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, NameSpace) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(160, 22)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, NameSpaceAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(164, 38)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, UsingStructInNameSpace) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(165, 36)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, NameSpaceReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, StructInNameSpaceReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, VirtualFunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(170, 35)); - - ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration)); -} - -TEST_F(TokenInfos, DISABLED_NonVirtualFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(177, 46)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, DISABLED_NonVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(180, 54)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, VirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(192, 51)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::VirtualFunction)); -} - -TEST_F(TokenInfos, FinalVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(202, 61)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, NonFinalVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(207, 61)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::VirtualFunction)); -} - -TEST_F(TokenInfos, PlusOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(224, 49)); - - ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Operator)); -} - -TEST_F(TokenInfos, PlusAssignOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(226, 24)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Operator)); -} - -TEST_F(TokenInfos, Comment) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(229, 14)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Comment)); -} - -TEST_F(TokenInfos, PreprocessingDirective) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(231, 37)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); -} - -TEST_F(TokenInfos, PreprocessorMacroDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(231, 37)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PreprocessorDefinition)); -} - -TEST_F(TokenInfos, PreprocessorFunctionMacroDefinition) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(232, 47)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PreprocessorDefinition)); -} - -TEST_F(TokenInfos, PreprocessorMacroExpansion) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(236, 27)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); -} - -TEST_F(TokenInfos, PreprocessorMacroExpansionArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(236, 27)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::NumberLiteral)); -} - -TEST_F(TokenInfos, PreprocessorInclusionDirective) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(239, 18)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::StringLiteral)); -} - -TEST_F(TokenInfos, GotoLabelStatement) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(242, 12)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Label)); -} - -TEST_F(TokenInfos, GotoLabelStatementReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(244, 21)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Label)); -} - -TEST_F(TokenInfos, TemplateReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(254, 25)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, TemplateTypeParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateDefaultParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, NonTypeTemplateParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, NonTypeTemplateParameterDefaultArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::NumberLiteral)); -} - -TEST_F(TokenInfos, TemplateTemplateParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[17], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateTemplateParameterDefaultArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); - - ASSERT_THAT(infos[19], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateFunctionDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(266, 63)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, TemplateTypeParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(268, 58)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateTypeParameterDeclarationReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(268, 58)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, NonTypeTemplateParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(269, 71)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, NonTypeTemplateParameterReferenceReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(269, 71)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, TemplateTemplateParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateTemplateContainerParameterReference) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateTemplateParameterReferenceVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, ClassFinalVirtualFunctionCallPointer) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(212, 61)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, ClassFinalVirtualFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(277, 23)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, HasFunctionArguments) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(286, 29)); - - ASSERT_TRUE(infos[1].hasFunctionArguments()); -} - -TEST_F(TokenInfos, PreprocessorInclusionDirectiveWithAngleBrackets ) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(289, 38)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::StringLiteral)); -} - -TEST_F(TokenInfos, ArgumentInMacroExpansionIsKeyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PrimitiveType)); -} - -TEST_F(TokenInfos, DISABLED_FirstArgumentInMacroExpansionIsLocalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenInfos, DISABLED_SecondArgumentInMacroExpansionIsLocalVariable) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); - - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenInfos, DISABLED_SecondArgumentInMacroExpansionIsField) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(310, 40)); - - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); -} - - -TEST_F(TokenInfos, EnumerationType) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(316, 30)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TypeInStaticCast) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, StaticCastIsKeyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Keyword)); -} - -TEST_F(TokenInfos, StaticCastPunctationIsInvalid) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); - ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenInfos, TypeInReinterpretCast) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(329, 69)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, IntegerAliasDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(333, 41)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, IntegerAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(341, 31)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, SecondIntegerAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(342, 43)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, IntegerTypedef) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(343, 35)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, FunctionAlias) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(344, 16)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, FriendTypeDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(350, 28)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, FriendArgumentTypeDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); - - ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, FriendArgumentDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); - - ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, FieldInitialization) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(358, 18)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Field)); -} - -TEST_F(TokenInfos, TemplateFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(372, 29)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, TemplatedType) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(377, 21)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplatedTypeDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(384, 49)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, NoOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(389, 24)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenInfos, ScopeOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(400, 33)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenInfos, TemplateClassNamespace) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateClass) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateClassParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TemplateClassDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); - - ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, TypeDefDeclaration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(418, 36)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, TypeDefDeclarationUsage) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(419, 48)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, NonConstReferenceArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(455, 35)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, ConstReferenceArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(464, 32)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, RValueReferenceArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(473, 52)); - - infos[1]; - - ASSERT_THAT(infos[8], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, NonConstPointerArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(482, 33)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, PointerToConstArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(490, 31)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, ConstPointerArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(491, 30)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, NonConstPointerGetterAsArgument) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(580, 42)); - - infos[1]; - - ASSERT_THAT(infos[2] ,HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[4], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[5], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[6], HasMixin(HighlightingType::OutputArgument)); - ASSERT_THAT(infos[7], Not(HasMixin(HighlightingType::OutputArgument))); -} - -TEST_F(TokenInfos, NonConstReferenceArgumentCallInsideCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(501, 64)); - infos[1]; - - infos[3]; - - ASSERT_THAT(infos[7], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, OutputArgumentsAreEmptyAfterIteration) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(501, 63)); - - for (const auto &info : infos ) { Q_UNUSED(info) } - - ASSERT_TRUE(infos.currentOutputArgumentRangesAreEmpty()); -} - -TEST_F(TokenInfos, NonConstReferenceArgumentFromFunctionParameter) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(506, 42)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, NonConstPointerArgumentAsExpression) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(513, 33)); - - infos[1]; - - ASSERT_THAT(infos[3], - HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, NonConstPointerArgumentAsInstanceWithMember) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(525, 46)); - - infos[1]; - - ASSERT_THAT(infos[2], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, NonConstPointerArgumentAsMemberOfInstance) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(525, 46)); - - infos[1]; - infos[2]; - - ASSERT_THAT(infos[4], - HasTwoTypes(HighlightingType::Field, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, DISABLED_NonConstReferenceArgumentConstructor) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(540, 57)); - - infos[2]; - - ASSERT_THAT(infos[3], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, DISABLED_NonConstReferenceMemberInitialization) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(546, 19)); - - infos[2]; - - ASSERT_THAT(infos[3], - HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); -} - -TEST_F(TokenInfos, EnumerationTypeDef) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(424, 41)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); -} - -// QTCREATORBUG-15473 -TEST_F(TokenInfos, DISABLED_ArgumentToUserDefinedIndexOperator) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(434, 19)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, ClassTemplateParticalSpecialization) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(553, 33)); - - ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Type)); -} - -TEST_F(TokenInfos, UsingFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(556, 27)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, PreprocessorIfDirective) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(558, 6)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); -} - -TEST_F(TokenInfos, PreprocessorInclusionDirectiveWithKeyword) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(561, 15)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::StringLiteral)); -} - -// CLANG-UPGRADE-CHECK: Enable once https://bugs.llvm.org//show_bug.cgi?id=12972 is resolved. -TEST_F(TokenInfos, DISABLED_VariableInOperatorFunctionCall) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(566, 12)); - - ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::LocalVariable)); -} - -TEST_F(TokenInfos, UsingTemplateFunction) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(584, 17)); - - ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function)); -} - -TEST_F(TokenInfos, HeaderNameIsInclusion) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(239, 31)); - ClangBackEnd::TokenInfoContainer container(infos[2]); - ASSERT_THAT(container.isIncludeDirectivePath(), true); -} - -TEST_F(TokenInfos, HeaderNameIsInclusionWithAngleBrackets) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(289, 31)); - ClangBackEnd::TokenInfoContainer container(infos[2]); - ASSERT_THAT(container.isIncludeDirectivePath(), true); -} - - -TEST_F(TokenInfos, NotInclusion) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(241, 13)); - ClangBackEnd::TokenInfoContainer container(infos[1]); - ASSERT_THAT(container.isIncludeDirectivePath(), false); -} - -TEST_F(TokenInfos, MacroIsIdentifier) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(232, 30)); - ClangBackEnd::TokenInfoContainer container(infos[2]); - ASSERT_THAT(container.isIdentifier(), true); -} - -TEST_F(TokenInfos, DefineIsNotIdentifier) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(232, 30)); - ClangBackEnd::TokenInfoContainer container(infos[1]); - ASSERT_THAT(container.isIncludeDirectivePath(), false); -} - -TEST_F(TokenInfos, DISABLED_WITHOUT_INVALIDDECL_PATCH(TypeNameOfInvalidDeclarationIsInvalid)) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(592, 14)); - - ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Invalid)); -} - -TEST_F(TokenInfos, DISABLED_WITHOUT_INVALIDDECL_PATCH(VariableNameOfInvalidDeclarationIsInvalid)) -{ - const auto infos = translationUnit.tokenInfosInRange(sourceRange(592, 14)); - - ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); -} - -Data *TokenInfos::d; - -void TokenInfos::SetUpTestCase() -{ - d = new Data; -} - -void TokenInfos::TearDownTestCase() -{ - delete d; - d = nullptr; -} - -ClangBackEnd::SourceRange TokenInfos::sourceRange(uint line, uint columnEnd) const -{ - return translationUnit.sourceRange(line, 1, line, columnEnd); -} - -} diff --git a/tests/unit/unittest/tokenprocessor-test.cpp b/tests/unit/unittest/tokenprocessor-test.cpp new file mode 100644 index 00000000000..50ee2cd9d03 --- /dev/null +++ b/tests/unit/unittest/tokenprocessor-test.cpp @@ -0,0 +1,1700 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 "testenvironment.h" + +#include <clangdocument.h> +#include <clangdocuments.h> +#include <clangtranslationunit.h> +#include <cursor.h> +#include <clangsupport_global.h> +#include <clangstring.h> +#include <fulltokeninfo.h> +#include <projectpart.h> +#include <projects.h> +#include <sourcelocation.h> +#include <sourcerange.h> +#include <tokeninfo.h> +#include <tokenprocessor.h> +#include <unsavedfiles.h> + +#include <clang-c/Index.h> + +using ClangBackEnd::Cursor; +using ClangBackEnd::HighlightingTypes; +using ClangBackEnd::TokenInfo; +using ClangBackEnd::TokenProcessor; +using ClangBackEnd::HighlightingType; +using ClangBackEnd::Document; +using ClangBackEnd::Documents; +using ClangBackEnd::TranslationUnit; +using ClangBackEnd::UnsavedFiles; +using ClangBackEnd::ProjectPart; +using ClangBackEnd::ClangString; +using ClangBackEnd::SourceRange; + +using testing::PrintToString; +using testing::IsNull; +using testing::NotNull; +using testing::Gt; +using testing::Contains; +using testing::ElementsAre; +using testing::_; +using testing::EndsWith; +using testing::AllOf; +using testing::Not; +using testing::IsEmpty; +using testing::SizeIs; + +namespace { + +MATCHER_P4(IsHighlightingMark, line, column, length, type, + std::string(negation ? "isn't " : "is ") + + PrintToString(line) + ", " + + PrintToString(column) + ", " + + PrintToString(length) + ", " + + PrintToString(type) + ", " + ) +{ + return arg.line() == line && arg.column() == column && arg.length() == length + && arg.types().mainHighlightingType == type; +} + +MATCHER_P(HasOnlyType, type, + std::string(negation ? "isn't " : "is ") + + PrintToString(type) + ) +{ + return arg.hasOnlyType(type); +} + +MATCHER_P2(HasTwoTypes, firstType, secondType, + std::string(negation ? "isn't " : "is ") + + PrintToString(firstType) + + " and " + + PrintToString(secondType) + ) +{ + return arg.hasMainType(firstType) && arg.hasMixinTypeAt(0, secondType) && arg.mixinSize() == 1; +} + +MATCHER_P3(HasThreeTypes, firstType, secondType, thirdType, + std::string(negation ? "isn't " : "is ") + + PrintToString(firstType) + + ", " + + PrintToString(secondType) + + " and " + + PrintToString(thirdType) + ) +{ + return arg.hasMainType(firstType) && arg.hasMixinTypeAt(0, secondType) && arg.hasMixinTypeAt(1, thirdType) && arg.mixinSize() == 2; +} + +MATCHER_P(HasMixin, mixinType, + std::string(negation ? "isn't " : "is ") + + PrintToString(mixinType) + ) +{ + return arg.hasMixinType(mixinType); +} + +struct Data { + Data() + { + document.parse(); + } + + ClangBackEnd::ProjectParts projects; + ClangBackEnd::UnsavedFiles unsavedFiles; + ClangBackEnd::Documents documents{projects, unsavedFiles}; + Utf8String filePath{Utf8StringLiteral(TESTDATA_DIR"/highlightingmarks.cpp")}; + Document document{filePath, + ProjectPart(Utf8StringLiteral("projectPartId"), + TestEnvironment::addPlatformArguments({Utf8StringLiteral("-std=c++14"), + Utf8StringLiteral("-I" TESTDATA_DIR)})), + {}, + documents}; + TranslationUnit translationUnit{filePath, + filePath, + document.translationUnit().cxIndex(), + document.translationUnit().cxTranslationUnit()}; +}; + +class TokenProcessor : public ::testing::Test +{ +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + + SourceRange sourceRange(uint line, uint columnEnd) const; + +protected: + static Data *d; + const TranslationUnit &translationUnit = d->translationUnit; +}; + +TEST_F(TokenProcessor, CreateNullInformations) +{ + ::TokenProcessor<TokenInfo> infos; + + ASSERT_TRUE(infos.isNull()); +} + +TEST_F(TokenProcessor, NullInformationsAreEmpty) +{ + ::TokenProcessor<TokenInfo> infos; + + ASSERT_TRUE(infos.isEmpty()); +} + +TEST_F(TokenProcessor, IsNotNull) +{ + const auto aRange = translationUnit.sourceRange(3, 1, 5, 1); + + const auto infos = translationUnit.tokenInfosInRange(aRange); + + ASSERT_FALSE(infos.isNull()); +} + +TEST_F(TokenProcessor, IteratorBeginEnd) +{ + const auto aRange = translationUnit.sourceRange(3, 1, 5, 1); + const auto infos = translationUnit.tokenInfosInRange(aRange); + + const auto endIterator = std::next(infos.begin(), infos.size()); + + ASSERT_THAT(infos.end(), endIterator); +} + +TEST_F(TokenProcessor, ForFullTranslationUnitRange) +{ + const auto infos = translationUnit.tokenInfos(); + + ASSERT_THAT(infos, AllOf(Contains(IsHighlightingMark(1u, 1u, 4u, HighlightingType::Keyword)), + Contains(IsHighlightingMark(277u, 5u, 15u, HighlightingType::Function)))); +} + +TEST_F(TokenProcessor, Size) +{ + const auto range = translationUnit.sourceRange(5, 5, 5, 10); + + const auto infos = translationUnit.tokenInfosInRange(range); + + ASSERT_THAT(infos.size(), 1); +} + +TEST_F(TokenProcessor, DISABLED_Keyword) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(5, 12)); + + ASSERT_THAT(infos[0], IsHighlightingMark(5u, 5u, 6u, HighlightingType::Keyword)); +} + +TEST_F(TokenProcessor, StringLiteral) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(1, 29)); + + ASSERT_THAT(infos[4], IsHighlightingMark(1u, 24u, 10u, HighlightingType::StringLiteral)); +} + +TEST_F(TokenProcessor, Utf8StringLiteral) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(2, 33)); + + ASSERT_THAT(infos[4], IsHighlightingMark(2u, 24u, 12u, HighlightingType::StringLiteral)); +} + +TEST_F(TokenProcessor, RawStringLiteral) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(3, 34)); + + ASSERT_THAT(infos[4], IsHighlightingMark(3u, 24u, 13u, HighlightingType::StringLiteral)); +} + +TEST_F(TokenProcessor, CharacterLiteral) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(4, 28)); + + ASSERT_THAT(infos[3], IsHighlightingMark(4u, 24u, 3u, HighlightingType::StringLiteral)); +} + +TEST_F(TokenProcessor, IntegerLiteral) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(23, 26)); + + ASSERT_THAT(infos[3], IsHighlightingMark(23u, 24u, 1u, HighlightingType::NumberLiteral)); +} + +TEST_F(TokenProcessor, FloatLiteral) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(24, 29)); + + ASSERT_THAT(infos[3], IsHighlightingMark(24u, 24u, 4u, HighlightingType::NumberLiteral)); +} + +TEST_F(TokenProcessor, FunctionDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(45, 20)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); +} + +TEST_F(TokenProcessor, MemberFunctionDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(52, 29)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); +} + +TEST_F(TokenProcessor, VirtualMemberFunctionDefinitionOutsideOfClassBody) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(586, 37)); + + ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); +} + +TEST_F(TokenProcessor, VirtualMemberFunctionDefinitionInsideOfClassBody) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(589, 47)); + + ASSERT_THAT(infos[2], HasThreeTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); +} + +TEST_F(TokenProcessor, FunctionDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(55, 32)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); +} + +TEST_F(TokenProcessor, MemberFunctionDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(59, 27)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); +} + +TEST_F(TokenProcessor, MemberFunctionReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(104, 35)); + + ASSERT_THAT(infos[0], IsHighlightingMark(104u, 9u, 23u, HighlightingType::Function)); +} + +TEST_F(TokenProcessor, FunctionCall) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(64, 16)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, TypeConversionFunction) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(68, 20)); + + ASSERT_THAT(infos[1], IsHighlightingMark(68u, 14u, 3u, HighlightingType::Type)); +} + +TEST_F(TokenProcessor, InbuiltTypeConversionFunction) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(69, 20)); + + ASSERT_THAT(infos[1], IsHighlightingMark(69u, 14u, 3u, HighlightingType::PrimitiveType)); +} + +TEST_F(TokenProcessor, TypeReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(74, 13)); + + ASSERT_THAT(infos[0], IsHighlightingMark(74u, 5u, 3u, HighlightingType::Type)); +} + +TEST_F(TokenProcessor, LocalVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(79, 13)); + + ASSERT_THAT(infos[1], IsHighlightingMark(79u, 9u, 3u, HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, LocalVariableDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(79, 13)); + + ASSERT_THAT(infos[1], IsHighlightingMark(79u, 9u, 3u, HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, LocalVariableReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(81, 26)); + + ASSERT_THAT(infos[0], IsHighlightingMark(81u, 5u, 3u, HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, LocalVariableFunctionArgumentDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(84, 45)); + + ASSERT_THAT(infos[5], IsHighlightingMark(84u, 41u, 3u, HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, LocalVariableFunctionArgumentReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(86, 26)); + + ASSERT_THAT(infos[0], IsHighlightingMark(86u, 5u, 3u, HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, ClassVariableDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(90, 21)); + + ASSERT_THAT(infos[1], IsHighlightingMark(90u, 9u, 11u, HighlightingType::Field)); +} + +TEST_F(TokenProcessor, ClassVariableReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(94, 23)); + + ASSERT_THAT(infos[0], IsHighlightingMark(94u, 9u, 11u, HighlightingType::Field)); +} + +TEST_F(TokenProcessor, StaticMethodDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(110, 25)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); +} + +TEST_F(TokenProcessor, StaticMethodReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(114, 30)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, Enumeration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(118, 17)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum)); +} + +TEST_F(TokenProcessor, Enumerator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(120, 15)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Enumeration)); +} + +TEST_F(TokenProcessor, EnumerationReferenceDeclarationType) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Enum)); +} + +TEST_F(TokenProcessor, EnumerationReferenceDeclarationVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(125, 28)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, EnumerationReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(127, 30)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, EnumeratorReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(127, 30)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Enumeration)); +} + +TEST_F(TokenProcessor, ClassForwardDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(130, 12)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, ConstructorDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(134, 13)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); +} + +TEST_F(TokenProcessor, DestructorDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(135, 15)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Function, HighlightingType::Declaration)); +} + +TEST_F(TokenProcessor, ClassForwardDeclarationReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(138, 23)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, ClassTypeReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, ConstructorReferenceVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(140, 32)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, UnionDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(145, 12)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Union)); +} + +TEST_F(TokenProcessor, UnionDeclarationReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Union)); +} + +TEST_F(TokenProcessor, GlobalVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(150, 33)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::GlobalVariable)); +} + +TEST_F(TokenProcessor, StructDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(50, 11)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Struct)); +} + +TEST_F(TokenProcessor, NameSpace) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(160, 22)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Namespace)); +} + +TEST_F(TokenProcessor, NameSpaceAlias) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(164, 38)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace)); +} + +TEST_F(TokenProcessor, UsingStructInNameSpace) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(165, 36)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, NameSpaceReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace)); +} + +TEST_F(TokenProcessor, StructInNameSpaceReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(166, 35)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Struct)); +} + +TEST_F(TokenProcessor, VirtualFunctionDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(170, 35)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::VirtualFunction, HighlightingType::Declaration)); +} + +TEST_F(TokenProcessor, DISABLED_NonVirtualFunctionCall) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(177, 46)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, DISABLED_NonVirtualFunctionCallPointer) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(180, 54)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, VirtualFunctionCallPointer) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(192, 51)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::VirtualFunction)); +} + +TEST_F(TokenProcessor, FinalVirtualFunctionCallPointer) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(202, 61)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, NonFinalVirtualFunctionCallPointer) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(207, 61)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::VirtualFunction)); +} + +TEST_F(TokenProcessor, OverriddenPlusOperatorDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(220, 67)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, CallToOverriddenPlusOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(224, 49)); + + ASSERT_THAT(infos[6], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, CallToOverriddenPlusAssignOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(226, 24)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, OverriddenStarOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(604, 26)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, OverriddenStarOperatorNonMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, IntegerCallToOverriddenBinaryOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(613, 9)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, FloatCallToOverriddenBinaryOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(614, 9)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, LeftShiftAssignmentOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(618, 32)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledLeftShiftAssignmentOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(629, 18)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::NumberLiteral)); +} + +TEST_F(TokenProcessor, FunctionCallOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(619, 29)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledFunctionCallOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(632, 16)); + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, AccessOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(620, 38)); + + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledAccessOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(633, 16)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); +} + +TEST_F(TokenProcessor, NewOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(621, 39)); + + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledNewOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(635, 34)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); // = is not marked. + // CLANG-UPGRADE-CHECK: Check if 'new' keyword usage cursor correctly returns referenced() cursor + // and uncomment this test in that case. + // ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // new +} + +TEST_F(TokenProcessor, DeleteOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(622, 37)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // delete + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledDeleteOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(636, 20)); + + // CLANG-UPGRADE-CHECK: Check if 'delete' keyword usage cursor correctly returns referenced() cursor + // and uncomment this test in that case. + // ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // delete + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Invalid)); // ; is a punctuation. +} + +TEST_F(TokenProcessor, NewArrayOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(623, 41)); + + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // new + ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // [ + ASSERT_THAT(infos[5], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ] + ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledNewArrayOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(637, 34)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); // = is not marked. + // CLANG-UPGRADE-CHECK: Check if 'new' keyword usage cursor correctly returns referenced() cursor + // and uncomment this test in that case. + // ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // new +} + +TEST_F(TokenProcessor, DeleteArrayOperatorMemberDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(624, 39)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // delete + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // [ + ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ] + ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation. +} + +TEST_F(TokenProcessor, CalledDeleteArrayOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(638, 20)); + + // CLANG-UPGRADE-CHECK: Check if 'delete' keyword usage cursor correctly returns referenced() cursor + // and uncomment this test in that case. + // ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // delete +} + +TEST_F(TokenProcessor, CalledNotOverloadedOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(634, 22)); + + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Keyword)); // new +} + +TEST_F(TokenProcessor, ParenthesisOperatorWithoutArguments) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(654, 25)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // operator + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '(' + ASSERT_THAT(infos[3], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ')' + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Invalid)); // second '(' is a punctuation +} + +TEST_F(TokenProcessor, CalledParenthesisOperatorWithoutArguments) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(662, 14)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '(' + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // ')' +} + +TEST_F(TokenProcessor, OperatorWithOnePunctuationTokenWithoutArguments) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(655, 25)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // operator + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '*' + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation +} + +TEST_F(TokenProcessor, CalledOperatorWithOnePunctuationTokenWithoutArguments) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(663, 13)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '*' +} + +TEST_F(TokenProcessor, EqualsOperatorOverload) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(656, 43)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Keyword, HighlightingType::OverloadedOperator)); // operator + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '=' + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); // ( is a punctuation +} + +TEST_F(TokenProcessor, CalledEqualsOperatorOverload) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(664, 23)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Operator, HighlightingType::OverloadedOperator)); // '=' +} + +TEST_F(TokenProcessor, LeftParenthesisIsAPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, SeparatingCommaIsAPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); + + ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, RightParenthesisIsAPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); + + ASSERT_THAT(infos[7], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, CurlyLeftParenthesisIsAPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); + + ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, CurlyRightParenthesisIsAPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(607, 29)); + + ASSERT_THAT(infos[9], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, OperatorColon) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(668, 28)); + + ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::Operator)); +} + +TEST_F(TokenProcessor, PunctuationColon) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(133, 10)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, LessThanOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(668, 28)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Operator)); +} + +TEST_F(TokenProcessor, LessThanPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(247, 19)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, GreaterThanPunctuation) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(247, 19)); + + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, Comment) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(229, 14)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Comment)); +} + +TEST_F(TokenProcessor, PreprocessingDirective) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(231, 37)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); +} + +TEST_F(TokenProcessor, PreprocessorMacroDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(231, 37)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PreprocessorDefinition)); +} + +TEST_F(TokenProcessor, PreprocessorFunctionMacroDefinition) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(232, 47)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PreprocessorDefinition)); +} + +TEST_F(TokenProcessor, PreprocessorMacroExpansion) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(236, 27)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); +} + +TEST_F(TokenProcessor, PreprocessorMacroExpansionArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(236, 27)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::NumberLiteral)); +} + +TEST_F(TokenProcessor, PreprocessorInclusionDirective) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(239, 18)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::StringLiteral)); +} + +TEST_F(TokenProcessor, GotoLabelStatement) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(242, 12)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Label)); +} + +TEST_F(TokenProcessor, GotoLabelStatementReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(244, 21)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Label)); +} + +TEST_F(TokenProcessor, TemplateReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(254, 25)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, TemplateTypeParameter) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, TemplateDefaultParameter) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); + + ASSERT_THAT(infos[5], HasTwoTypes(HighlightingType::Type, HighlightingType::Struct)); +} + +TEST_F(TokenProcessor, NonTypeTemplateParameter) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); + + ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, NonTypeTemplateParameterDefaultArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); + + ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::NumberLiteral)); +} + +TEST_F(TokenProcessor, TemplateTemplateParameter) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); + + ASSERT_THAT(infos[17], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, TemplateTemplateParameterDefaultArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(265, 135)); + + ASSERT_THAT(infos[19], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, TemplateFunctionDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(266, 63)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Function, HighlightingType::Declaration, HighlightingType::FunctionDefinition)); +} + +TEST_F(TokenProcessor, TemplateTypeParameterReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(268, 58)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, TemplateTypeParameterDeclarationReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(268, 58)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, NonTypeTemplateParameterReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(269, 71)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, NonTypeTemplateParameterReferenceReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(269, 71)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, TemplateTemplateParameterReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, TemplateTemplateContainerParameterReference) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, TemplateTemplateParameterReferenceVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(270, 89)); + + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, ClassFinalVirtualFunctionCallPointer) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(212, 61)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, ClassFinalVirtualFunctionCall) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(277, 23)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, HasFunctionArguments) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(286, 29)); + + ASSERT_TRUE(infos[1].hasFunctionArguments()); +} + +TEST_F(TokenProcessor, PreprocessorInclusionDirectiveWithAngleBrackets ) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(289, 38)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::StringLiteral)); +} + +TEST_F(TokenProcessor, ArgumentInMacroExpansionIsKeyword) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::PrimitiveType)); +} + +TEST_F(TokenProcessor, DISABLED_FirstArgumentInMacroExpansionIsLocalVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, DISABLED_SecondArgumentInMacroExpansionIsLocalVariable) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(302, 36)); + + ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, DISABLED_SecondArgumentInMacroExpansionIsField) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(310, 40)); + + ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); +} + + +TEST_F(TokenProcessor, EnumerationType) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(316, 30)); + + ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum)); +} + +TEST_F(TokenProcessor, TypeInStaticCast) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); + + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, StaticCastIsKeyword) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Keyword)); +} + +TEST_F(TokenProcessor, StaticCastPunctationIsInvalid) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(328, 64)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Invalid)); + ASSERT_THAT(infos[5], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, TypeInReinterpretCast) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(329, 69)); + + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, IntegerAliasDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(333, 41)); + + ASSERT_THAT(infos[1], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); +} + +TEST_F(TokenProcessor, IntegerAlias) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(341, 31)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); +} + +TEST_F(TokenProcessor, SecondIntegerAlias) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(342, 43)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); +} + +TEST_F(TokenProcessor, IntegerTypedef) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(343, 35)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef)); +} + +TEST_F(TokenProcessor, FunctionAlias) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(344, 16)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::TypeAlias)); +} + +TEST_F(TokenProcessor, FriendTypeDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(350, 28)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, FriendArgumentTypeDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); + + ASSERT_THAT(infos[6], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, FriendArgumentDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(351, 65)); + + ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, FieldInitialization) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(358, 18)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Field)); +} + +TEST_F(TokenProcessor, TemplateFunctionCall) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(372, 29)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, TemplatedType) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(377, 21)); + + ASSERT_THAT(infos[1], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, TemplatedTypeDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(384, 49)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, NoOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(389, 24)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, ScopeOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(400, 33)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, TemplateClassNamespace) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Namespace)); +} + +TEST_F(TokenProcessor, TemplateClass) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, TemplateClassParameter) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); + + ASSERT_THAT(infos[4], HasTwoTypes(HighlightingType::Type, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, TemplateClassDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(413, 78)); + + ASSERT_THAT(infos[6], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, TypeDefDeclaration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(418, 36)); + + ASSERT_THAT(infos[2], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef)); +} + +TEST_F(TokenProcessor, TypeDefDeclarationUsage) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(419, 48)); + + ASSERT_THAT(infos[0], HasTwoTypes(HighlightingType::Type, HighlightingType::Typedef)); +} + +TEST_F(TokenProcessor, NonConstReferenceArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(455, 35)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, ConstReferenceArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(464, 32)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, RValueReferenceArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(473, 52)); + + infos[1]; + + ASSERT_THAT(infos[8], + HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, NonConstPointerArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(482, 33)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, PointerToConstArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(490, 31)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, ConstPointerArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(491, 30)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, NonConstPointerGetterAsArgument) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(580, 42)); + + infos[1]; + + ASSERT_THAT(infos[2] ,HasMixin(HighlightingType::OutputArgument)); + ASSERT_THAT(infos[3], HasMixin(HighlightingType::OutputArgument)); + ASSERT_THAT(infos[4], HasMixin(HighlightingType::OutputArgument)); + ASSERT_THAT(infos[5], HasMixin(HighlightingType::OutputArgument)); + ASSERT_THAT(infos[6], HasMixin(HighlightingType::OutputArgument)); + ASSERT_THAT(infos[7], Not(HasMixin(HighlightingType::OutputArgument))); +} + +TEST_F(TokenProcessor, NonConstReferenceArgumentCallInsideCall) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(501, 64)); + infos[1]; + + infos[3]; + + ASSERT_THAT(infos[7], + HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, OutputArgumentsAreEmptyAfterIteration) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(501, 63)); + + for (const auto &info : infos ) { Q_UNUSED(info) } + + ASSERT_TRUE(infos.currentOutputArgumentRangesAreEmpty()); +} + +TEST_F(TokenProcessor, NonConstReferenceArgumentFromFunctionParameter) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(506, 42)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, NonConstPointerArgumentAsExpression) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(513, 33)); + + infos[1]; + + ASSERT_THAT(infos[3], + HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, NonConstPointerArgumentAsInstanceWithMember) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(525, 46)); + + infos[1]; + + ASSERT_THAT(infos[2], + HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, NonConstPointerArgumentAsMemberOfInstance) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(525, 46)); + + infos[1]; + infos[2]; + + ASSERT_THAT(infos[4], + HasTwoTypes(HighlightingType::Field, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, DISABLED_NonConstReferenceArgumentConstructor) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(540, 57)); + + infos[2]; + + ASSERT_THAT(infos[3], + HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, DISABLED_NonConstReferenceMemberInitialization) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(546, 19)); + + infos[2]; + + ASSERT_THAT(infos[3], + HasTwoTypes(HighlightingType::LocalVariable, HighlightingType::OutputArgument)); +} + +TEST_F(TokenProcessor, EnumerationTypeDef) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(424, 41)); + + ASSERT_THAT(infos[3], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Enum)); +} + +// QTCREATORBUG-15473 +TEST_F(TokenProcessor, DISABLED_ArgumentToUserDefinedIndexOperator) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(434, 19)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, ClassTemplateParticalSpecialization) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(553, 33)); + + ASSERT_THAT(infos[6], HasThreeTypes(HighlightingType::Type, HighlightingType::Declaration, HighlightingType::Class)); +} + +TEST_F(TokenProcessor, UsingFunction) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(556, 27)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, PreprocessorIfDirective) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(558, 6)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Preprocessor)); +} + +TEST_F(TokenProcessor, PreprocessorInclusionDirectiveWithKeyword) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(561, 15)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::StringLiteral)); +} + +// CLANG-UPGRADE-CHECK: Enable once https://bugs.llvm.org//show_bug.cgi?id=12972 is resolved. +TEST_F(TokenProcessor, DISABLED_VariableInOperatorFunctionCall) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(566, 12)); + + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::LocalVariable)); +} + +TEST_F(TokenProcessor, UsingTemplateFunction) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(584, 17)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, HeaderNameIsInclusion) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(239, 31)); + + ClangBackEnd::TokenInfoContainer container(infos[2]); + + ASSERT_THAT(container.extraInfo.includeDirectivePath, true); +} + +TEST_F(TokenProcessor, HeaderNameIsInclusionWithAngleBrackets) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(289, 31)); + + ClangBackEnd::TokenInfoContainer container(infos[2]); + + ASSERT_THAT(container.extraInfo.includeDirectivePath, true); +} + +TEST_F(TokenProcessor, NotInclusion) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(241, 13)); + + ClangBackEnd::TokenInfoContainer container(infos[1]); + + ASSERT_THAT(container.extraInfo.includeDirectivePath, false); +} + +TEST_F(TokenProcessor, MacroIsIdentifier) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(232, 30)); + + ClangBackEnd::TokenInfoContainer container(infos[2]); + + ASSERT_THAT(container.extraInfo.identifier, true); +} + +TEST_F(TokenProcessor, DefineIsNotIdentifier) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(232, 30)); + + ClangBackEnd::TokenInfoContainer container(infos[1]); + + ASSERT_THAT(container.extraInfo.includeDirectivePath, false); +} + +TEST_F(TokenProcessor, NamespaceTypeSpelling) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(592, 59)); + ClangBackEnd::TokenInfoContainer container(infos[10]); + ASSERT_THAT(container.extraInfo.semanticParentTypeSpelling, Utf8StringLiteral("NFoo::NBar::NTest")); +} + +TEST_F(TokenProcessor, DISABLED_WITHOUT_INVALIDDECL_PATCH(TypeNameOfInvalidDeclarationIsInvalid)) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(594, 14)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, DISABLED_WITHOUT_INVALIDDECL_PATCH(VariableNameOfInvalidDeclarationIsInvalid)) +{ + const auto infos = translationUnit.tokenInfosInRange(sourceRange(594, 14)); + + ASSERT_THAT(infos[1], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, QtPropertyName) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); + ASSERT_THAT(infos[8], HasOnlyType(HighlightingType::QtProperty)); +} + +TEST_F(TokenProcessor, QtPropertyFunction) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); + + ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, QtPropertyInternalKeyword) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); + + ASSERT_THAT(infos[9], HasOnlyType(HighlightingType::Invalid)); +} + +TEST_F(TokenProcessor, QtPropertyLastToken) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(599, 103)); + + ASSERT_THAT(infos[14], HasOnlyType(HighlightingType::Function)); +} + +TEST_F(TokenProcessor, QtPropertyType) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(600, 46)); + + ASSERT_THAT(infos[3], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, CursorRange) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(592, 15)); + const auto expectedRange = translationUnit.sourceRange(592, 1, 592, 87); + + ClangBackEnd::TokenInfoContainer container(infos[1]); + + ASSERT_THAT(container.extraInfo.cursorRange, expectedRange); +} + +TEST_F(TokenProcessor, AnonymousEnum) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(641, 7)); + + ClangBackEnd::TokenInfoContainer container(infos[0]); + + ASSERT_THAT(container.types.mainHighlightingType, ClangBackEnd::HighlightingType::Keyword); + ASSERT_THAT(container.types.mixinHighlightingTypes[0], ClangBackEnd::HighlightingType::Enum); +} + +TEST_F(TokenProcessor, AnonymousNamespace) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(645, 12)); + + ClangBackEnd::TokenInfoContainer container(infos[0]); + + ASSERT_THAT(container.types.mainHighlightingType, ClangBackEnd::HighlightingType::Keyword); + ASSERT_THAT(container.types.mixinHighlightingTypes[0], ClangBackEnd::HighlightingType::Namespace); +} + +TEST_F(TokenProcessor, AnonymousStruct) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(647, 13)); + + ClangBackEnd::TokenInfoContainer container(infos[0]); + + ASSERT_THAT(container.types.mainHighlightingType, ClangBackEnd::HighlightingType::Keyword); + ASSERT_THAT(container.types.mixinHighlightingTypes[0], ClangBackEnd::HighlightingType::Struct); +} + +TEST_F(TokenProcessor, LexicalParentIndex) +{ + const auto containers = translationUnit.fullTokenInfosInRange( + translationUnit.sourceRange(50, 1, 53, 3)).toTokenInfoContainers(); + + ASSERT_THAT(containers[3].extraInfo.lexicalParentIndex, 1); +} + +TEST_F(TokenProcessor, QtOldStyleSignal) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(672, 32)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, QtOldStyleSlot) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(673, 30)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); +} + +TEST_F(TokenProcessor, QtOldStyleSignalFunctionPointerType) +{ + const auto infos = translationUnit.fullTokenInfosInRange(sourceRange(674, 50)); + + ASSERT_THAT(infos[0], HasOnlyType(HighlightingType::PreprocessorExpansion)); + ASSERT_THAT(infos[2], HasOnlyType(HighlightingType::Function)); + ASSERT_THAT(infos[4], HasOnlyType(HighlightingType::Type)); + ASSERT_THAT(infos[7], HasOnlyType(HighlightingType::Type)); + ASSERT_THAT(infos[10], HasOnlyType(HighlightingType::Type)); +} + +Data *TokenProcessor::d; + +void TokenProcessor::SetUpTestCase() +{ + d = new Data; +} + +void TokenProcessor::TearDownTestCase() +{ + delete d; + d = nullptr; +} + +ClangBackEnd::SourceRange TokenProcessor::sourceRange(uint line, uint columnEnd) const +{ + return translationUnit.sourceRange(line, 1, line, columnEnd); +} + +} diff --git a/tests/unit/unittest/unittest.pro b/tests/unit/unittest/unittest.pro index 257a83370c9..050537e071a 100644 --- a/tests/unit/unittest/unittest.pro +++ b/tests/unit/unittest/unittest.pro @@ -53,6 +53,7 @@ SOURCES += \ gtest-creator-printing.cpp \ gtest-qt-printing.cpp \ lineprefixer-test.cpp \ + locatorfilter-test.cpp \ matchingtext-test.cpp \ mimedatabase-utilities.cpp \ pchgenerator-test.cpp \ @@ -68,6 +69,7 @@ SOURCES += \ sourcerangefilter-test.cpp \ spydummy.cpp \ symbolindexer-test.cpp \ + symbolsfindfilter-test.cpp \ stringcache-test.cpp \ eventspy.cpp \ unittests-main.cpp \ @@ -85,7 +87,12 @@ SOURCES += \ processcreator-test.cpp \ nativefilepath-test.cpp \ nativefilepathview-test.cpp \ - mocktimer.cpp + mocktimer.cpp \ + tokenprocessor-test.cpp \ + projectpartartefact-test.cpp \ + filestatuscache-test.cpp \ + highlightingresultreporter-test.cpp \ + precompiledheaderstorage-test.cpp !isEmpty(LIBCLANG_LIBS) { SOURCES += \ @@ -141,8 +148,6 @@ SOURCES += \ sqlitestatement-test.cpp \ sqlitetable-test.cpp \ sqlstatementbuilder-test.cpp \ - tokeninfos-test.cpp \ - tokeninfosreporter-test.cpp \ translationunitupdater-test.cpp \ unsavedfiles-test.cpp \ unsavedfile-test.cpp \ @@ -221,7 +226,11 @@ HEADERS += \ mocksymbolquery.h \ runprojectcreateorupdate-utility.h \ rundocumentparse-utility.h \ - mocktimer.h + mocktimer.h \ + mocksqlitetransactionbackend.h \ + mockprojectpartprovider.h \ + mockprecompiledheaderstorage.h \ + mockeditormanager.h !isEmpty(LIBCLANG_LIBS) { HEADERS += \ chunksreportedmonitor.h \ diff --git a/tests/unit/unittest/unsavedfiles-test.cpp b/tests/unit/unittest/unsavedfiles-test.cpp index 8bb474c55eb..6b472918f0d 100644 --- a/tests/unit/unittest/unsavedfiles-test.cpp +++ b/tests/unit/unittest/unsavedfiles-test.cpp @@ -46,8 +46,8 @@ namespace { bool operator==(const ClangBackEnd::FileContainer &fileContainer, const UnsavedFile &unsavedFile) { - return fileContainer.filePath() == unsavedFile.filePath() - && fileContainer.unsavedFileContent() == unsavedFile.fileContent(); + return fileContainer.filePath == unsavedFile.filePath() + && fileContainer.unsavedFileContent == unsavedFile.fileContent(); } bool fileContainersContainsItemMatchingToCxUnsavedFile(const QVector<FileContainer> &fileContainers, const UnsavedFile &unsavedFile) |