File: languagecontrollertestbase.cpp

package info (click to toggle)
kdevelop 4%3A24.12.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 71,888 kB
  • sloc: cpp: 290,869; python: 3,626; javascript: 3,518; sh: 1,316; ansic: 703; xml: 401; php: 95; lisp: 66; makefile: 31; sed: 12
file content (169 lines) | stat: -rw-r--r-- 5,895 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
    SPDX-FileCopyrightText: 2021 Igor Kushnir <igorkuo@gmail.com>

    SPDX-License-Identifier: LGPL-2.0-or-later
*/

#include "languagecontrollertestbase.h"

#include "testfilepaths.h"

#include <interfaces/ilanguagecontroller.h>
#include <interfaces/iplugincontroller.h>
#include <language/backgroundparser/backgroundparser.h>
#include <languagecontroller.h>
#include <shell/core.h>
#include <tests/autotestshell.h>
#include <tests/testcore.h>
#include <tests/testhelpers.h>

#include <QByteArray>
#include <QFileInfo>
#include <QMimeDatabase>
#include <QString>
#include <QTest>
#include <QtLogging>
#include <QUrl>

#include <algorithm>

using namespace KDevelop;

namespace {
QUrl testUrl(const QString& filename)
{
    return QUrl::fromLocalFile(filename);
}

QUrl existentTestUrl(const QString& filename)
{
    const QString filePath = TEST_FILES_DIR "/" + filename;
    QVERIFY_RETURN(QFileInfo::exists(filePath), QUrl{});
    return QUrl::fromLocalFile(filePath);
}
}

LanguageControllerTestBase::LanguageControllerTestBase(QObject* parent)
    : QObject(parent)
    , m_differentLanguagesUrls{
        {testUrl("plus.cc"), "clang"},
        {testUrl("project.cmake"), "CMake"},
        {testUrl("patch.diff"), "diff"},
        {testUrl("gui.qml"), "qml/js"},
    }
{
}

void LanguageControllerTestBase::initTestCase()
{
    AutoTestShell::init({"kdevclangsupport", "kdevpatchreview", "kdevqmljs",
                         "KDevCMakeManager", "KDevCMakeBuilder", "KDevMakeBuilder", "KDevStandardOutputView"});
    TestCore::initialize();
    m_subject = Core::self()->languageController();

    // Remove entries for languages supported by unavailable optional plugins.
    for (auto it = m_differentLanguagesUrls.cbegin(); it != m_differentLanguagesUrls.cend();) {
        const auto mimeType = QMimeDatabase().mimeTypeForFile(it->url.fileName(), QMimeDatabase::MatchExtension);
        QVERIFY(mimeType.isValid());
        QVERIFY(!mimeType.isDefault());

        const QVariantMap constraints{{"X-KDevelop-SupportedMimeTypes", mimeType.name()}};
        const bool languagePluginLoaded =
            !ICore::self()->pluginController()->queryExtensionPlugins("ILanguageSupport", constraints).empty();
        if (languagePluginLoaded) {
            ++it;
        } else {
            qWarning() << "expected language plugin" << it->languageName << "for MIME type" << mimeType.name()
                       << "has not been loaded => skipping test data rows for this language";
            it = m_differentLanguagesUrls.erase(it);
        }
    }

    if (m_differentLanguagesUrls.empty()) {
        QSKIP("zero language plugins => skip the entire test to prevent an assertion failure in QTest::fetchData()");
    }
}

void LanguageControllerTestBase::init()
{
    Core::self()->languageControllerInternal()->initialize();
    m_subject->backgroundParser()->suspend();
}

void LanguageControllerTestBase::cleanup()
{
    Core::self()->languageControllerInternal()->cleanup();
}

void LanguageControllerTestBase::cleanupTestCase()
{
    TestCore::shutdown();
}

void LanguageControllerTestBase::fillLanguageControllerMimeTypeCache() const
{
    for (const auto& url : m_differentLanguagesUrls) {
        const auto languages = m_subject->languagesForUrl(url.url);
        QCOMPARE(languages.size(), 1);
        QCOMPARE(languages.back()->name(), url.languageName);
    }
}

void LanguageControllerTestBase::matchingLanguagesForUrlInBackgroundThreadTestData() const
{
    QTest::addColumn<QUrl>("url");
    QTest::addColumn<QString>("languageName");

    newOptionalRow("CMakeLists", testUrl("CMakeLists.txt"), "CMake");
    newOptionalRow("cmakelists wrong case", testUrl("cmakelists.TXT"), "CMake");

    newOptionalRow("lower-case", testUrl("x.cpp"), "clang");
    newOptionalRow("upper-case", testUrl("Y.CPP"), "clang");
    newOptionalRow("mixed-case", testUrl("aBc.CpP"), "clang");

    newOptionalRow(".C", testUrl("ambiguous.C"), "clang");
    newOptionalRow(".cl", testUrl("Open.cl"), "clang");

    newOptionalRow("existent C with extension", existentTestUrl("t.c"), "clang");

    for (const auto& url : m_differentLanguagesUrls) {
        const auto filename = url.url.fileName();
        const auto extension = filename.mid(filename.lastIndexOf('.'));
        newOptionalRow(extension.toUtf8().constData(), url.url, url.languageName);
    }
}

void LanguageControllerTestBase::matchingLanguagesForUrlTestData() const
{
    matchingLanguagesForUrlInBackgroundThreadTestData();

    newOptionalRow("existent C w/o extension", existentTestUrl("X"), "clang");
    newOptionalRow("existent patch w/o extension", existentTestUrl("y"), "diff");
}

void LanguageControllerTestBase::nonmatchingLanguagesForUrlTestData()
{
    QTest::addColumn<QUrl>("url");

    QTest::newRow("empty") << testUrl(QString());
    QTest::newRow("archive") << testUrl("a.tar.gz");
    QTest::newRow("OpenDocument Text") << testUrl("b.odt");
    QTest::newRow("existent archive with extension") << existentTestUrl("N.tar.gz");
    QTest::newRow("existent archive w/o extension") << existentTestUrl("z");
}

void LanguageControllerTestBase::newOptionalRow(const char* dataTag, const QUrl& url, const QString& languageName) const
{
    const bool languagePluginLoaded = std::any_of(m_differentLanguagesUrls.cbegin(), m_differentLanguagesUrls.cend(),
                                                  [&languageName](const UrlEntry& entry) {
                                                      return entry.languageName == languageName;
                                                  });
    if (languagePluginLoaded) {
        QTest::newRow(dataTag) << url << languageName;
    } else {
        qWarning() << "skipping test data row because its language plugin is unavailable:" << dataTag << url.fileName()
                   << languageName;
    }
}

#include "moc_languagecontrollertestbase.cpp"