aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/texteditor/highlighter_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/texteditor/highlighter_test.cpp')
-rw-r--r--src/plugins/texteditor/highlighter_test.cpp195
1 files changed, 195 insertions, 0 deletions
diff --git a/src/plugins/texteditor/highlighter_test.cpp b/src/plugins/texteditor/highlighter_test.cpp
new file mode 100644
index 0000000000..f0652a780b
--- /dev/null
+++ b/src/plugins/texteditor/highlighter_test.cpp
@@ -0,0 +1,195 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "syntaxhighlighter.h"
+
+#include "highlighter_test.h"
+
+#include "fontsettings.h"
+#include "textdocument.h"
+#include "texteditor.h"
+#include "texteditorsettings.h"
+
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/editormanager/editormanager.h>
+#include <utils/mimeutils.h>
+
+#include <QtTest/QtTest>
+
+namespace TextEditor::Internal {
+
+constexpr auto json = R"(
+{
+ "name": "Test",
+ "scope": "source.test",
+ "uuid": "test",
+ "patterns": [
+ {
+ "match": "a",
+ "name": "keyword.test"
+ }
+ ]
+}
+)";
+
+void GenerigHighlighterTests::initTestCase()
+{
+ QString title = "test.json";
+
+ Core::IEditor *editor = Core::EditorManager::openEditorWithContents(
+ Core::Constants::K_DEFAULT_TEXT_EDITOR_ID, &title, json);
+ QVERIFY(editor);
+ m_editor = qobject_cast<BaseTextEditor *>(editor);
+ m_editor->editorWidget()->configureGenericHighlighter(Utils::mimeTypeForName("application/json"));
+ QVERIFY(m_editor);
+ m_editor->textDocument()->syntaxHighlighter()->rehighlight();
+}
+
+using FormatRanges = QList<QTextLayout::FormatRange>;
+
+QTextCharFormat toFormat(const TextStyle &style)
+{
+ const static FontSettings fontSettings = TextEditorSettings::fontSettings();
+ auto format = fontSettings.toTextCharFormat(style);
+ if (style == C_FUNCTION)
+ format.setFontWeight(QFont::Bold); // is explicitly set by the ksyntax format definition
+ if (style == C_TEXT) {
+ format = QTextCharFormat();
+ format.setFontWeight(QFont::Bold); // is explicitly set by the ksyntax format definition
+ }
+ return format;
+};
+
+void GenerigHighlighterTests::testHighlight_data()
+{
+ QTest::addColumn<int>("blockNumber");
+ QTest::addColumn<QList<QTextLayout::FormatRange>>("formatRanges");
+
+ // clang-format off
+ QTest::addRow("0:<empty block>")
+ << 0
+ << FormatRanges();
+ QTest::addRow("1:{")
+ << 1
+ << FormatRanges{{0, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("2: \"name\": \"Test\",")
+ << 2
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 6, toFormat(C_TYPE)},
+ {10, 1, toFormat(C_FUNCTION)},
+ {11, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 6, toFormat(C_STRING)},
+ {18, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("3: \"scope\": \"source.test\",")
+ << 3
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 7, toFormat(C_TYPE)},
+ {11, 1, toFormat(C_FUNCTION)},
+ {12, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {13, 13, toFormat(C_STRING)},
+ {26, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("4: \"uuid\": \"test\",")
+ << 4
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 6, toFormat(C_TYPE)},
+ {10, 1, toFormat(C_FUNCTION)},
+ {11, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 6, toFormat(C_STRING)},
+ {18, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("5: \"patterns\": [")
+ << 5
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 10, toFormat(C_TYPE)},
+ {14, 1, toFormat(C_FUNCTION)},
+ {15, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {16, 1, toFormat(C_TEXT)}};
+ QTest::addRow("6: {")
+ << 6
+ << FormatRanges{{0, 8, toFormat(C_VISUAL_WHITESPACE)},
+ {8, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("7: \"match\": \"a\",")
+ << 7
+ << FormatRanges{{0, 12, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 7, toFormat(C_TYPE)},
+ {19, 1, toFormat(C_FUNCTION)},
+ {20, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {21, 3, toFormat(C_STRING)},
+ {24, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("8: \"name\": \"keyword.test\"")
+ << 8
+ << FormatRanges{{0, 12, toFormat(C_VISUAL_WHITESPACE)},
+ {12, 6, toFormat(C_TYPE)},
+ {18, 1, toFormat(C_FUNCTION)},
+ {19, 1, toFormat(C_VISUAL_WHITESPACE)},
+ {20, 14, toFormat(C_STRING)}};
+ QTest::addRow("9: }")
+ << 9
+ << FormatRanges{{0, 8, toFormat(C_VISUAL_WHITESPACE)},
+ {8, 1, toFormat(C_FUNCTION)}};
+ QTest::addRow("10: ]")
+ << 10
+ << FormatRanges{{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 1, toFormat(C_TEXT)}};
+ QTest::addRow("11:}")
+ << 11
+ << FormatRanges{{0, 1, toFormat(C_FUNCTION)}};
+ // clang-format on
+}
+
+void compareFormats(const QTextLayout::FormatRange &actual, const QTextLayout::FormatRange &expected)
+{
+ QCOMPARE(actual.start, expected.start);
+ QCOMPARE(actual.length, expected.length);
+ QCOMPARE(actual.format.foreground(), expected.format.foreground());
+ QCOMPARE(actual.format.background(), expected.format.background());
+ QCOMPARE(actual.format.fontWeight(), expected.format.fontWeight());
+ QCOMPARE(actual.format.fontItalic(), expected.format.fontItalic());
+ QCOMPARE(actual.format.underlineStyle(), expected.format.underlineStyle());
+ QCOMPARE(actual.format.underlineColor(), expected.format.underlineColor());
+}
+
+void GenerigHighlighterTests::testHighlight()
+{
+ QFETCH(int, blockNumber);
+ QFETCH(FormatRanges, formatRanges);
+
+ QTextBlock block = m_editor->textDocument()->document()->findBlockByNumber(blockNumber);
+ QVERIFY(block.isValid());
+
+ const QList<QTextLayout::FormatRange> actualFormats = block.layout()->formats();
+ // full hash calculation for QTextCharFormat fails so just check the important entries of format
+ QCOMPARE(actualFormats.size(), formatRanges.size());
+ for (int i = 0; i < formatRanges.size(); ++i)
+ compareFormats(actualFormats.at(i), formatRanges.at(i));
+}
+
+void GenerigHighlighterTests::testChange()
+{
+ QTextBlock block = m_editor->textDocument()->document()->findBlockByNumber(10);
+ QVERIFY(block.isValid());
+
+ QTextCursor c(block);
+ c.movePosition(QTextCursor::NextBlock, QTextCursor::KeepAnchor);
+ c.removeSelectedText();
+ m_editor->textDocument()->document()->undo();
+
+ block = m_editor->textDocument()->document()->findBlockByNumber(10);
+ QVERIFY(block.isValid());
+
+ const FormatRanges formatRanges = {{0, 4, toFormat(C_VISUAL_WHITESPACE)},
+ {4, 1, toFormat(C_TEXT)}};
+ const QList<QTextLayout::FormatRange> actualFormats = block.layout()->formats();
+ // full hash calculation for QTextCharFormat fails so just check the important entries of format
+ QCOMPARE(actualFormats.size(), formatRanges.size());
+ for (int i = 0; i < formatRanges.size(); ++i)
+ compareFormats(actualFormats.at(i), formatRanges.at(i));
+}
+
+void GenerigHighlighterTests::cleanupTestCase()
+{
+ if (m_editor)
+ Core::EditorManager::closeEditors({m_editor});
+ QVERIFY(Core::EditorManager::currentEditor() == nullptr);
+}
+
+} // namespace TextEditor::Internal