aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/plugins/texteditor/syntaxhighlighter.cpp16
-rw-r--r--src/plugins/texteditor/syntaxhighlighter.h5
-rw-r--r--tests/auto/CMakeLists.txt1
-rw-r--r--tests/auto/auto.qbs1
-rw-r--r--tests/auto/texteditor/CMakeLists.txt1
-rw-r--r--tests/auto/texteditor/highlighter/CMakeLists.txt4
-rw-r--r--tests/auto/texteditor/highlighter/highlighter.qbs15
-rw-r--r--tests/auto/texteditor/highlighter/tst_highlighter.cpp317
-rw-r--r--tests/auto/texteditor/texteditor.qbs6
9 files changed, 365 insertions, 1 deletions
diff --git a/src/plugins/texteditor/syntaxhighlighter.cpp b/src/plugins/texteditor/syntaxhighlighter.cpp
index de72c7b0db6..6d2616193ef 100644
--- a/src/plugins/texteditor/syntaxhighlighter.cpp
+++ b/src/plugins/texteditor/syntaxhighlighter.cpp
@@ -23,8 +23,12 @@ class SyntaxHighlighterPrivate
Q_DECLARE_PUBLIC(SyntaxHighlighter)
public:
SyntaxHighlighterPrivate()
+ : SyntaxHighlighterPrivate(TextEditorSettings::fontSettings())
+ { }
+
+ SyntaxHighlighterPrivate(const FontSettings &fontSettings)
{
- updateFormats(TextEditorSettings::fontSettings());
+ updateFormats(fontSettings);
}
QPointer<QTextDocument> doc;
@@ -76,6 +80,16 @@ void SyntaxHighlighter::delayedRehighlight()
rehighlight();
}
+#ifdef WITH_TESTS
+SyntaxHighlighter::SyntaxHighlighter(QTextDocument *parent, const FontSettings &fontsettings)
+ : QObject(parent), d_ptr(new SyntaxHighlighterPrivate(fontsettings))
+{
+ d_ptr->q_ptr = this;
+ if (parent)
+ setDocument(parent);
+}
+#endif
+
void SyntaxHighlighterPrivate::applyFormatChanges(int from, int charsRemoved, int charsAdded)
{
bool formatsChanged = false;
diff --git a/src/plugins/texteditor/syntaxhighlighter.h b/src/plugins/texteditor/syntaxhighlighter.h
index 7a1822e4667..1b66e2ff56a 100644
--- a/src/plugins/texteditor/syntaxhighlighter.h
+++ b/src/plugins/texteditor/syntaxhighlighter.h
@@ -91,6 +91,11 @@ private:
void delayedRehighlight();
QScopedPointer<SyntaxHighlighterPrivate> d_ptr;
+
+#ifdef WITH_TESTS
+ friend class tst_highlighter;
+ SyntaxHighlighter(QTextDocument *parent, const FontSettings &fontsettings);
+#endif
};
} // namespace TextEditor
diff --git a/tests/auto/CMakeLists.txt b/tests/auto/CMakeLists.txt
index 9849f8776ec..5dcd026a7af 100644
--- a/tests/auto/CMakeLists.txt
+++ b/tests/auto/CMakeLists.txt
@@ -20,6 +20,7 @@ add_subdirectory(qml)
add_subdirectory(runextensions)
add_subdirectory(sdktool)
add_subdirectory(solutions)
+add_subdirectory(texteditor)
add_subdirectory(toolchaincache)
add_subdirectory(tracing)
add_subdirectory(treeviewfind)
diff --git a/tests/auto/auto.qbs b/tests/auto/auto.qbs
index 063977537ba..603b5cd1b15 100644
--- a/tests/auto/auto.qbs
+++ b/tests/auto/auto.qbs
@@ -23,6 +23,7 @@ Project {
"runextensions/runextensions.qbs",
"sdktool/sdktool.qbs",
"solutions/solutions.qbs",
+ "texteditor/texteditor.qbs",
"toolchaincache/toolchaincache.qbs",
"tracing/tracing.qbs",
"treeviewfind/treeviewfind.qbs",
diff --git a/tests/auto/texteditor/CMakeLists.txt b/tests/auto/texteditor/CMakeLists.txt
new file mode 100644
index 00000000000..23684431c43
--- /dev/null
+++ b/tests/auto/texteditor/CMakeLists.txt
@@ -0,0 +1 @@
+add_subdirectory(highlighter)
diff --git a/tests/auto/texteditor/highlighter/CMakeLists.txt b/tests/auto/texteditor/highlighter/CMakeLists.txt
new file mode 100644
index 00000000000..76370bf8255
--- /dev/null
+++ b/tests/auto/texteditor/highlighter/CMakeLists.txt
@@ -0,0 +1,4 @@
+add_qtc_test(tst_highlighter
+ DEPENDS TextEditor Utils Qt::Widgets
+ SOURCES tst_highlighter.cpp
+)
diff --git a/tests/auto/texteditor/highlighter/highlighter.qbs b/tests/auto/texteditor/highlighter/highlighter.qbs
new file mode 100644
index 00000000000..641a71ef66d
--- /dev/null
+++ b/tests/auto/texteditor/highlighter/highlighter.qbs
@@ -0,0 +1,15 @@
+import qbs
+
+QtcAutotest {
+
+ Depends { name: "TextEditor" }
+ Depends { name: "Utils" }
+ Depends { name: "Qt.widgets" } // For QTextDocument & friends
+
+ name: "Highlighter autotest"
+
+ Group {
+ name: "Source Files"
+ files: "tst_highlighter.cpp"
+ }
+}
diff --git a/tests/auto/texteditor/highlighter/tst_highlighter.cpp b/tests/auto/texteditor/highlighter/tst_highlighter.cpp
new file mode 100644
index 00000000000..163699c0cb1
--- /dev/null
+++ b/tests/auto/texteditor/highlighter/tst_highlighter.cpp
@@ -0,0 +1,317 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#ifndef WITH_TESTS
+#define WITH_TESTS
+#endif
+
+#include <texteditor/semantichighlighter.h>
+#include <texteditor/syntaxhighlighter.h>
+#include <texteditor/texteditorsettings.h>
+
+#include <QObject>
+#include <QTextBlock>
+#include <QTextDocument>
+#include <QtTest>
+
+namespace TextEditor {
+
+class tst_highlighter: public QObject
+{
+ Q_OBJECT
+
+private slots:
+ void init_testCase();
+ void init();
+ void test_setExtraAdditionalFormats();
+ void test_clearExtraFormats();
+ void test_incrementalApplyAdditionalFormats();
+ void cleanup();
+
+private:
+ QTextDocument *doc = nullptr;
+ SyntaxHighlighter *highlighter = nullptr;
+ FontSettings fontsettings;
+ QHash<int, QTextCharFormat> formatHash;
+ QTextCharFormat whitespaceFormat;
+};
+
+void tst_highlighter::init_testCase()
+{
+ QTextCharFormat c0;
+ c0.setFontItalic(true);
+ formatHash[0] = c0;
+ QTextCharFormat c1;
+ c1.setFontOverline(true);
+ formatHash[1] = c1;
+}
+
+void tst_highlighter::init()
+{
+ const QString text =
+R"(First
+Second with spaces
+
+Last)";
+
+
+ doc = new QTextDocument();
+ doc->setPlainText(text);
+
+ highlighter = new SyntaxHighlighter(doc, fontsettings);
+}
+
+static const HighlightingResults &highlightingResults()
+{
+ static HighlightingResults results{HighlightingResult(),
+ HighlightingResult(1, 1, 5, 0),
+ HighlightingResult(2, 4, 7, 0),
+ HighlightingResult(2, 17, 5, 1),
+ HighlightingResult(4, 1, 8, 0),
+ HighlightingResult(6, 1, 8, 1)};
+ return results;
+}
+
+void tst_highlighter::test_setExtraAdditionalFormats()
+{
+ QCOMPARE(doc->blockCount(), 4);
+
+ SemanticHighlighter::setExtraAdditionalFormats(highlighter, highlightingResults(), formatHash);
+
+ for (auto block = doc->firstBlock(); block.isValid(); block = block.next()) {
+ QVERIFY(block.blockNumber() < 4);
+ QVERIFY(block.layout());
+ auto formats = block.layout()->formats();
+ switch (block.blockNumber()) {
+ case 0: // First
+ QCOMPARE(formats.size(), 1);
+ QCOMPARE(formats.at(0).format.fontItalic(), true);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 5);
+ break;
+ case 1: // Second with spaces
+ QCOMPARE(formats.size(), 4);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 6);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), false);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 11);
+ QCOMPARE(formats.at(1).length, 1);
+
+ QCOMPARE(formats.at(2).format.fontItalic(), true);
+ QCOMPARE(formats.at(2).format.fontOverline(), false);
+ QCOMPARE(formats.at(2).start, 3);
+ QCOMPARE(formats.at(2).length, 7);
+
+ QCOMPARE(formats.at(3).format.fontItalic(), false);
+ QCOMPARE(formats.at(3).format.fontOverline(), true);
+ QCOMPARE(formats.at(3).start, 16);
+ QCOMPARE(formats.at(3).length, 3);
+ break;
+ case 2: //
+ QCOMPARE(formats.size(), 1);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), true);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 1);
+ break;
+ case 3: // Last
+ QCOMPARE(formats.size(), 2);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), true);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), true);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 0);
+ QCOMPARE(formats.at(1).length, 5);
+ break;
+ }
+ }
+}
+
+void tst_highlighter::test_clearExtraFormats()
+{
+ QCOMPARE(doc->blockCount(), 4);
+
+ SemanticHighlighter::setExtraAdditionalFormats(highlighter, highlightingResults(), formatHash);
+
+ QTextBlock firstBlock = doc->findBlockByNumber(0);
+ QTextBlock spacesLineBlock = doc->findBlockByNumber(1);
+ QTextBlock emptyLineBlock = doc->findBlockByNumber(2);
+ QTextBlock lastBlock = doc->findBlockByNumber(3);
+
+ highlighter->clearExtraFormats(emptyLineBlock);
+ QVERIFY(emptyLineBlock.layout()->formats().isEmpty());
+
+ highlighter->clearExtraFormats(spacesLineBlock);
+
+ auto formats = spacesLineBlock.layout()->formats();
+ // the spaces are not extra formats and should remain when clearing extra formats
+ QCOMPARE(formats.size(), 2);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 6);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), false);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 11);
+ QCOMPARE(formats.at(1).length, 1);
+
+ // first and last should be untouched
+ formats = firstBlock.layout()->formats();
+ QCOMPARE(formats.size(), 1);
+ QCOMPARE(formats.at(0).format.fontItalic(), true);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 5);
+
+ formats = lastBlock.layout()->formats();
+ QCOMPARE(formats.size(), 2);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), true);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), true);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 0);
+ QCOMPARE(formats.at(1).length, 5);
+
+ highlighter->clearAllExtraFormats();
+
+ QVERIFY(firstBlock.layout()->formats().isEmpty());
+ QVERIFY(emptyLineBlock.layout()->formats().isEmpty());
+ formats = spacesLineBlock.layout()->formats();
+
+ QCOMPARE(formats.size(), 2);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 6);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), false);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 11);
+ QCOMPARE(formats.at(1).length, 1);
+
+ QVERIFY(lastBlock.layout()->formats().isEmpty());
+}
+
+void tst_highlighter::test_incrementalApplyAdditionalFormats()
+{
+ const HighlightingResults newResults{HighlightingResult(),
+ HighlightingResult(1, 1, 5, 0),
+ HighlightingResult(2, 4, 7, 0),
+ HighlightingResult(4, 1, 8, 0),
+ HighlightingResult(6, 1, 8, 1)};
+
+ QCOMPARE(doc->blockCount(), 4);
+ QTextBlock firstBlock = doc->findBlockByNumber(0);
+ QTextBlock spacesLineBlock = doc->findBlockByNumber(1);
+ QTextBlock emptyLineBlock = doc->findBlockByNumber(2);
+ QTextBlock lastBlock = doc->findBlockByNumber(3);
+
+ QFutureInterface<HighlightingResult> fiOld;
+ fiOld.reportResults(highlightingResults());
+ SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
+ fiOld.future(),
+ 2,
+ 0,
+ formatHash);
+ auto formats = firstBlock.layout()->formats();
+ QVERIFY(formats.isEmpty());
+
+ SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
+ fiOld.future(),
+ 0,
+ 2,
+ formatHash);
+
+ formats = firstBlock.layout()->formats();
+ QCOMPARE(formats.at(0).format.fontItalic(), true);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 5);
+
+ formats = spacesLineBlock.layout()->formats();
+ QCOMPARE(formats.size(), 2);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 6);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), false);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 11);
+ QCOMPARE(formats.at(1).length, 1);
+
+ SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
+ fiOld.future(),
+ 3,
+ 6,
+ formatHash);
+
+ formats = firstBlock.layout()->formats();
+ QCOMPARE(formats.at(0).format.fontItalic(), true);
+ QCOMPARE(formats.at(0).format.fontOverline(), false);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 5);
+
+ formats = lastBlock.layout()->formats();
+ QCOMPARE(formats.size(), 2);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), true);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 1);
+
+ QCOMPARE(formats.at(1).format.fontItalic(), true);
+ QCOMPARE(formats.at(1).format.fontOverline(), false);
+ QCOMPARE(formats.at(1).start, 0);
+ QCOMPARE(formats.at(1).length, 5);
+
+ QFutureInterface<HighlightingResult> fiNew;
+ fiNew.reportResults(newResults);
+ SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
+ fiNew.future(),
+ 0,
+ 3,
+ formatHash);
+
+ // should still contain the highlight from oldResults
+ formats = emptyLineBlock.layout()->formats();
+ QCOMPARE(formats.size(), 1);
+ QCOMPARE(formats.at(0).format.fontItalic(), false);
+ QCOMPARE(formats.at(0).format.fontOverline(), true);
+ QCOMPARE(formats.at(0).start, 0);
+ QCOMPARE(formats.at(0).length, 1);
+
+ SemanticHighlighter::incrementalApplyExtraAdditionalFormats(highlighter,
+ fiNew.future(),
+ 3,
+ 4,
+ formatHash);
+
+ // should have no results since the new results do not contain a highlight at that position
+ formats = emptyLineBlock.layout()->formats();
+ QVERIFY(formats.isEmpty());
+}
+
+void tst_highlighter::cleanup()
+{
+ delete doc;
+ doc = nullptr;
+ highlighter = nullptr;
+}
+
+} // namespace TextEditor
+
+QTEST_MAIN(TextEditor::tst_highlighter)
+
+#include "tst_highlighter.moc"
diff --git a/tests/auto/texteditor/texteditor.qbs b/tests/auto/texteditor/texteditor.qbs
new file mode 100644
index 00000000000..957bb448f16
--- /dev/null
+++ b/tests/auto/texteditor/texteditor.qbs
@@ -0,0 +1,6 @@
+import qbs
+
+Project {
+ name: "TextEditor autotests"
+ references: [ "highlighter/highlighter.qbs" ]
+}