File indexing completed on 2024-07-14 14:36:28

0001 /*
0002     This file is part of the KDE project
0003     SPDX-FileCopyrightText: 2019 Dominik Haumann <dhaumann@kde.org>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "variable_test.h"
0009 #include "moc_variable_test.cpp"
0010 
0011 #include <katedocument.h>
0012 #include <kateglobal.h>
0013 #include <ktexteditor/document.h>
0014 #include <ktexteditor/editor.h>
0015 #include <ktexteditor/view.h>
0016 
0017 #include <QTest>
0018 #include <QUuid>
0019 
0020 using namespace KTextEditor;
0021 
0022 QTEST_MAIN(VariableTest)
0023 
0024 VariableTest::VariableTest()
0025     : QObject()
0026 {
0027     KTextEditor::EditorPrivate::enableUnitTestMode();
0028 }
0029 
0030 VariableTest::~VariableTest()
0031 {
0032 }
0033 
0034 void VariableTest::testReturnValues()
0035 {
0036     auto editor = KTextEditor::Editor::instance();
0037 
0038     const QString name = QStringLiteral("Document:");
0039     auto func = [](const QStringView &, KTextEditor::View *) {
0040         return QString();
0041     };
0042 
0043     // exact matches
0044     QVERIFY(!editor->unregisterVariableMatch(name));
0045     QVERIFY(editor->registerVariableMatch(name, "Document Text", func));
0046     QVERIFY(!editor->registerVariableMatch(name, "Document Text", func));
0047     QVERIFY(editor->unregisterVariableMatch(name));
0048     QVERIFY(!editor->unregisterVariableMatch(name));
0049 
0050     // prefix matches
0051     QVERIFY(!editor->unregisterVariablePrefix(name));
0052     QVERIFY(editor->registerVariablePrefix(name, "Document Text", func));
0053     QVERIFY(!editor->registerVariablePrefix(name, "Document Text", func));
0054     QVERIFY(editor->unregisterVariablePrefix(name));
0055     QVERIFY(!editor->unregisterVariablePrefix(name));
0056 }
0057 
0058 void VariableTest::testExactMatch_data()
0059 {
0060     QTest::addColumn<QString>("text");
0061     QTest::addColumn<QString>("expected");
0062     QTest::addColumn<QString>("expectedText");
0063 
0064     QTest::newRow("World") << "World"
0065                            << "World"
0066                            << "World";
0067     QTest::newRow("Smart World") << "Smart World"
0068                                  << "Smart World"
0069                                  << "Smart World";
0070 }
0071 
0072 void VariableTest::testExactMatch()
0073 {
0074     QFETCH(QString, text);
0075     QFETCH(QString, expected);
0076     QFETCH(QString, expectedText);
0077 
0078     auto editor = KTextEditor::Editor::instance();
0079     auto doc = editor->createDocument(nullptr);
0080     auto view = doc->createView(nullptr);
0081     doc->setText(text);
0082 
0083     const QString name = QStringLiteral("Doc:Text");
0084     auto func = [](const QStringView &, KTextEditor::View *view) {
0085         return view->document()->text();
0086     };
0087 
0088     QVERIFY(editor->registerVariableMatch(name, "Document Text", func));
0089 
0090     // expandVariable
0091     QString output;
0092     QVERIFY(editor->expandVariable(QStringLiteral("Doc:Text"), view, output));
0093     QCOMPARE(output, expected);
0094 
0095     // expandText
0096     editor->expandText(QStringLiteral("Hello %{Doc:Text}!"), view, output);
0097     QCOMPARE(output, QStringLiteral("Hello ") + expectedText + QLatin1Char('!'));
0098 
0099     editor->expandText(QStringLiteral("Hello %{Doc:Text} %{Doc:Text}!"), view, output);
0100     QCOMPARE(output, QStringLiteral("Hello ") + expectedText + QLatin1Char(' ') + expectedText + QLatin1Char('!'));
0101 
0102     QVERIFY(editor->unregisterVariableMatch("Doc:Text"));
0103 
0104     delete doc;
0105 }
0106 
0107 void VariableTest::testPrefixMatch()
0108 {
0109     auto editor = KTextEditor::Editor::instance();
0110 
0111     const QString prefix = QStringLiteral("Mirror:");
0112     auto func = [](const QStringView &text, KTextEditor::View *) {
0113         QStringView rest = text.right(text.size() - 7);
0114         QString out;
0115         for (auto it = rest.rbegin(); it != rest.rend(); ++it) {
0116             out += *it;
0117         }
0118         return out;
0119     };
0120 
0121     QVERIFY(editor->registerVariablePrefix(prefix, "Reverse text", func));
0122 
0123     QString output;
0124     QVERIFY(editor->expandVariable(QStringLiteral("Mirror:12345"), nullptr, output));
0125     QCOMPARE(output, QStringLiteral("54321"));
0126 
0127     editor->expandText(QStringLiteral("Countdown: %{Mirror:12345}"), nullptr, output);
0128     QCOMPARE(output, QStringLiteral("Countdown: 54321"));
0129 
0130     // Test recursive expansion
0131     editor->expandText(QStringLiteral("Countup: %{Mirror:%{Mirror:12345}}"), nullptr, output);
0132     QCOMPARE(output, QStringLiteral("Countup: 12345"));
0133 
0134     QVERIFY(editor->unregisterVariablePrefix(prefix));
0135 }
0136 
0137 void VariableTest::testRecursiveMatch()
0138 {
0139     auto editor = KTextEditor::Editor::instance();
0140     auto doc = editor->createDocument(nullptr);
0141     auto view = doc->createView(nullptr);
0142     doc->setText(QStringLiteral("Text"));
0143 
0144     const QString name = QStringLiteral("Doc:Text");
0145     auto func = [](const QStringView &, KTextEditor::View *view) {
0146         return view->document()->text();
0147     };
0148     QVERIFY(editor->registerVariableMatch(name, "Document Text", func));
0149 
0150     // Test recursive expansion
0151     doc->setText(QStringLiteral("Text"));
0152     QString output;
0153     editor->expandText(QStringLiteral("Hello %{Doc:%{Doc:Text}}!"), view, output);
0154     QCOMPARE(output, QStringLiteral("Hello Text!"));
0155 
0156     QVERIFY(editor->unregisterVariableMatch(name));
0157     delete doc;
0158 }
0159 
0160 void VariableTest::testBuiltins()
0161 {
0162     auto editor = KTextEditor::Editor::instance();
0163     auto doc = editor->createDocument(nullptr);
0164     doc->openUrl(QUrl::fromLocalFile(QDir::homePath() + QStringLiteral("/kate-v5.tar.gz")));
0165     doc->setText(QStringLiteral("get an edge in editing\n:-)"));
0166     auto view = doc->createView(nullptr);
0167     view->setCursorPosition(KTextEditor::Cursor(1, 2));
0168     view->show();
0169 
0170     QString out;
0171 
0172     // Test invalid ones:
0173     editor->expandText(QStringLiteral("%{}"), view, out);
0174     QCOMPARE(out, QStringLiteral("%{}"));
0175     editor->expandText(QStringLiteral("%{"), view, out);
0176     QCOMPARE(out, QStringLiteral("%{"));
0177     editor->expandText(QStringLiteral("%{{}"), view, out);
0178     QCOMPARE(out, QStringLiteral("%{{}"));
0179     editor->expandText(QStringLiteral("%{{}}"), view, out);
0180     QCOMPARE(out, QStringLiteral("%{{}}"));
0181 
0182     // Document:FileBaseName
0183     editor->expandText(QStringLiteral("%{Document:FileBaseName}"), view, out);
0184     QCOMPARE(out, QStringLiteral("kate-v5"));
0185 
0186     // Document:FileExtension
0187     editor->expandText(QStringLiteral("%{Document:FileExtension}"), view, out);
0188     QCOMPARE(out, QStringLiteral("tar.gz"));
0189 
0190     // Document:FileName
0191     editor->expandText(QStringLiteral("%{Document:FileName}"), view, out);
0192     QCOMPARE(out, QStringLiteral("kate-v5.tar.gz"));
0193 
0194     // Document:FilePath
0195     editor->expandText(QStringLiteral("%{Document:FilePath}"), view, out);
0196     QCOMPARE(out, QFileInfo(view->document()->url().toLocalFile()).absoluteFilePath());
0197 
0198     // Document:Text
0199     editor->expandText(QStringLiteral("%{Document:Text}"), view, out);
0200     QCOMPARE(out, QStringLiteral("get an edge in editing\n:-)"));
0201 
0202     // Document:Path
0203     editor->expandText(QStringLiteral("%{Document:Path}"), view, out);
0204     QCOMPARE(out, QFileInfo(doc->url().toLocalFile()).absolutePath());
0205 
0206     // Document:NativeFilePath
0207     editor->expandText(QStringLiteral("%{Document:NativeFilePath}"), view, out);
0208     QCOMPARE(out, QDir::toNativeSeparators(QFileInfo(doc->url().toLocalFile()).absoluteFilePath()));
0209 
0210     // Document:NativePath
0211     editor->expandText(QStringLiteral("%{Document:NativePath}"), view, out);
0212     QCOMPARE(out, QDir::toNativeSeparators(QFileInfo(doc->url().toLocalFile()).absolutePath()));
0213 
0214     // Document:NativePath
0215     editor->expandText(QStringLiteral("%{Document:NativePath}"), view, out);
0216     QCOMPARE(out, QDir::toNativeSeparators(QFileInfo(doc->url().toLocalFile()).absolutePath()));
0217 
0218     // Document:Cursor:Line
0219     editor->expandText(QStringLiteral("%{Document:Cursor:Line}"), view, out);
0220     QCOMPARE(out, QStringLiteral("1"));
0221 
0222     // Document:Cursor:Column
0223     editor->expandText(QStringLiteral("%{Document:Cursor:Column}"), view, out);
0224     QCOMPARE(out, QStringLiteral("2"));
0225 
0226     // Document:Cursor:XPos
0227     editor->expandText(QStringLiteral("%{Document:Cursor:XPos}"), view, out);
0228     QVERIFY(out.toInt() > 0);
0229 
0230     // Document:Cursor:YPos
0231     editor->expandText(QStringLiteral("%{Document:Cursor:YPos}"), view, out);
0232     QVERIFY(out.toInt() > 0);
0233 
0234     view->setSelection(KTextEditor::Range(1, 0, 1, 3));
0235     // Document:Selection:Text
0236     editor->expandText(QStringLiteral("%{Document:Selection:Text}"), view, out);
0237     QCOMPARE(out, QStringLiteral(":-)"));
0238 
0239     // Document:Selection:StartLine
0240     editor->expandText(QStringLiteral("%{Document:Selection:StartLine}"), view, out);
0241     QCOMPARE(out, QStringLiteral("1"));
0242 
0243     // Document:Selection:StartColumn
0244     editor->expandText(QStringLiteral("%{Document:Selection:StartColumn}"), view, out);
0245     QCOMPARE(out, QStringLiteral("0"));
0246 
0247     // Document:Selection:EndLine
0248     editor->expandText(QStringLiteral("%{Document:Selection:EndLine}"), view, out);
0249     QCOMPARE(out, QStringLiteral("1"));
0250 
0251     // Document:Selection:EndColumn
0252     editor->expandText(QStringLiteral("%{Document:Selection:EndColumn}"), view, out);
0253     QCOMPARE(out, QStringLiteral("3"));
0254 
0255     // Document:RowCount
0256     editor->expandText(QStringLiteral("%{Document:RowCount}"), view, out);
0257     QCOMPARE(out, QStringLiteral("2"));
0258 
0259     // Document:Variable:<variable>, since KF 5.78
0260     qobject_cast<KTextEditor::DocumentPrivate *>(doc)->setVariable(QStringLiteral("cow-sound"), QStringLiteral("moo"));
0261     editor->expandText(QStringLiteral("%{Document:Variable:cow-sound}"), view, out);
0262     QCOMPARE(out, QStringLiteral("moo"));
0263 
0264     // Date:Locale
0265     editor->expandText(QStringLiteral("%{Date:Locale}"), view, out);
0266     QVERIFY(!out.isEmpty());
0267 
0268     // Date:ISO
0269     editor->expandText(QStringLiteral("%{Date:ISO}"), view, out);
0270     QVERIFY(!out.isEmpty());
0271 
0272     // Date:yyyy-MM-dd
0273     editor->expandText(QStringLiteral("%{Date:yyyy-MM-dd}"), view, out);
0274     QVERIFY(QDate::fromString(out, QStringLiteral("yyyy-MM-dd")).isValid());
0275 
0276     // Time:Locale
0277     editor->expandText(QStringLiteral("%{Time:Locale}"), view, out);
0278     QVERIFY(!out.isEmpty());
0279 
0280     // Time:ISO
0281     editor->expandText(QStringLiteral("%{Time:ISO}"), view, out);
0282     QVERIFY(!out.isEmpty());
0283 
0284     // Time:hh-mm-ss
0285     editor->expandText(QStringLiteral("%{Time:hh-mm-ss}"), view, out);
0286     QVERIFY(QTime::fromString(out, QStringLiteral("hh-mm-ss")).isValid());
0287 
0288     // ENV:KTE_ENV_VAR_TEST
0289     qputenv("KTE_ENV_VAR_TEST", "KTE_ENV_VAR_TEST_VALUE");
0290     editor->expandText(QStringLiteral("%{ENV:KTE_ENV_VAR_TEST}"), view, out);
0291     QCOMPARE(out, QStringLiteral("KTE_ENV_VAR_TEST_VALUE"));
0292 
0293     // JS:<code>
0294     editor->expandText(QStringLiteral("%{JS:3 + %{JS:2 + 1}}"), view, out);
0295     QCOMPARE(out, QStringLiteral("6"));
0296 
0297     // PercentEncoded: since 5.67
0298     editor->expandText(QStringLiteral("%{PercentEncoded:{a&b+c=d} \"}"), view, out);
0299     QCOMPARE(out, QStringLiteral("%7Ba%26b%2Bc%3Dd%7D%20%22"));
0300 
0301     // UUID
0302     editor->expandText(QStringLiteral("%{UUID}"), view, out);
0303     QCOMPARE(out.count(QLatin1Char('-')), 4);
0304 }
0305 
0306 // kate: indent-mode cstyle; indent-width 4; replace-tabs on;