diff options
Diffstat (limited to 'src/plugins/texteditor')
-rw-r--r-- | src/plugins/texteditor/CMakeLists.txt | 1 | ||||
-rw-r--r-- | src/plugins/texteditor/basehoverhandler.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/codeassist/codeassistant.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/colorpreviewhoverhandler.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/highlighter_test.cpp | 195 | ||||
-rw-r--r-- | src/plugins/texteditor/highlighter_test.h | 26 | ||||
-rw-r--r-- | src/plugins/texteditor/snippets/snippet.cpp | 4 | ||||
-rw-r--r-- | src/plugins/texteditor/textdocumentlayout.cpp | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.cpp | 8 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditor.qbs | 2 | ||||
-rw-r--r-- | src/plugins/texteditor/texteditorplugin.cpp | 2 |
11 files changed, 237 insertions, 9 deletions
diff --git a/src/plugins/texteditor/CMakeLists.txt b/src/plugins/texteditor/CMakeLists.txt index 048cd40b1d5..2a99947b933 100644 --- a/src/plugins/texteditor/CMakeLists.txt +++ b/src/plugins/texteditor/CMakeLists.txt @@ -115,5 +115,6 @@ extend_qtc_plugin(TextEditor CONDITION WITH_TESTS SOURCES codeassist/codeassist_test.cpp codeassist/codeassist_test.h + highlighter_test.cpp highlighter_test.h texteditor_test.cpp ) diff --git a/src/plugins/texteditor/basehoverhandler.cpp b/src/plugins/texteditor/basehoverhandler.cpp index 203ecc36e20..45949fb8863 100644 --- a/src/plugins/texteditor/basehoverhandler.cpp +++ b/src/plugins/texteditor/basehoverhandler.cpp @@ -121,7 +121,7 @@ void BaseHoverHandler::process(TextEditorWidget *widget, int pos, ReportPriority void BaseHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, ReportPriority report) { - const auto cleanup = qScopeGuard([this, report] { report(priority()); }); + const QScopeGuard cleanup([this, report] { report(priority()); }); QString tooltip = editorWidget->extraSelectionTooltip(pos); if (!tooltip.isEmpty()) diff --git a/src/plugins/texteditor/codeassist/codeassistant.cpp b/src/plugins/texteditor/codeassist/codeassistant.cpp index 0da6571da8f..0bdf34efaba 100644 --- a/src/plugins/texteditor/codeassist/codeassistant.cpp +++ b/src/plugins/texteditor/codeassist/codeassistant.cpp @@ -158,7 +158,7 @@ void CodeAssistantPrivate::requestProposal(AssistReason reason, bool isUpdate) { // make sure to cleanup old proposals if we cannot find a new assistant - auto cleanup = qScopeGuard([this] { destroyContext(); }); + QScopeGuard cleanup([this] { destroyContext(); }); if (isWaitingForProposal()) cancelCurrentRequest(); diff --git a/src/plugins/texteditor/colorpreviewhoverhandler.cpp b/src/plugins/texteditor/colorpreviewhoverhandler.cpp index 1a66392c550..7e3134e8c27 100644 --- a/src/plugins/texteditor/colorpreviewhoverhandler.cpp +++ b/src/plugins/texteditor/colorpreviewhoverhandler.cpp @@ -335,7 +335,7 @@ static QColor colorFromFuncAndArgs(const QString &func, const QStringList &args) void ColorPreviewHoverHandler::identifyMatch(TextEditorWidget *editorWidget, int pos, ReportPriority report) { - const auto cleanup = qScopeGuard([this, report] { report(priority()); }); + const QScopeGuard cleanup([this, report] { report(priority()); }); if (editorWidget->extraSelectionTooltip(pos).isEmpty()) { const QTextBlock tb = editorWidget->document()->findBlock(pos); diff --git a/src/plugins/texteditor/highlighter_test.cpp b/src/plugins/texteditor/highlighter_test.cpp new file mode 100644 index 00000000000..f0652a780b3 --- /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 diff --git a/src/plugins/texteditor/highlighter_test.h b/src/plugins/texteditor/highlighter_test.h new file mode 100644 index 00000000000..30c2848c5c1 --- /dev/null +++ b/src/plugins/texteditor/highlighter_test.h @@ -0,0 +1,26 @@ +// Copyright (C) 2023 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 + +#pragma once + +#include <QObject> + +namespace TextEditor { class BaseTextEditor; } + +namespace TextEditor::Internal { + +class GenerigHighlighterTests : public QObject +{ + Q_OBJECT +private slots: + void initTestCase(); + void testHighlight_data(); + void testHighlight(); + void testChange(); + void cleanupTestCase(); + +private: + TextEditor::BaseTextEditor *m_editor = nullptr; +}; + +} // namespace TextEditor::Internal diff --git a/src/plugins/texteditor/snippets/snippet.cpp b/src/plugins/texteditor/snippets/snippet.cpp index 74a4dc543c3..0b3bd080e7a 100644 --- a/src/plugins/texteditor/snippets/snippet.cpp +++ b/src/plugins/texteditor/snippets/snippet.cpp @@ -189,7 +189,7 @@ SnippetParseResult Snippet::parse(const QString &snippet) if (!errorMessage.isEmpty()) return {SnippetParseError{errorMessage, {}, -1}}; - const int count = preprocessedSnippet.count(); + const int count = preprocessedSnippet.size(); NameMangler *mangler = nullptr; QMap<QString, int> variableIndexes; @@ -404,7 +404,7 @@ void Internal::TextEditorPlugin::testSnippetParsing() QCOMPARE(manglerId, expected.manglerId); }; - for (int i = 0; i < parts.count(); ++i) + for (int i = 0; i < parts.size(); ++i) rangesCompare(snippet.parts.at(i), parts.at(i)); } #endif diff --git a/src/plugins/texteditor/textdocumentlayout.cpp b/src/plugins/texteditor/textdocumentlayout.cpp index 703f9563bf1..08c1e21117b 100644 --- a/src/plugins/texteditor/textdocumentlayout.cpp +++ b/src/plugins/texteditor/textdocumentlayout.cpp @@ -596,6 +596,8 @@ bool TextDocumentLayout::updateSuggestion(const QTextBlock &block, { if (TextSuggestion *suggestion = TextDocumentLayout::suggestion(block)) { auto positionInBlock = position - block.position(); + if (positionInBlock < suggestion->position()) + return false; const QString start = block.text().left(positionInBlock); const QString end = block.text().mid(positionInBlock); const QString replacement = suggestion->document()->firstBlock().text(); diff --git a/src/plugins/texteditor/texteditor.cpp b/src/plugins/texteditor/texteditor.cpp index 97c878e4425..33323b3b76a 100644 --- a/src/plugins/texteditor/texteditor.cpp +++ b/src/plugins/texteditor/texteditor.cpp @@ -1426,7 +1426,7 @@ void TextEditorWidgetPrivate::print(QPrinter *printer) return; doc = doc->clone(doc); - const auto cleanup = qScopeGuard([doc] { delete doc; }); + const QScopeGuard cleanup([doc] { delete doc; }); QTextOption opt = doc->defaultTextOption(); opt.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere); @@ -2546,7 +2546,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) { ICore::restartTrimmer(); - auto clearBlockSelectionGuard = qScopeGuard([&]() { d->clearBlockSelection(); }); + QScopeGuard cleanup([&] { d->clearBlockSelection(); }); if (!isModifier(e) && mouseHidingEnabled()) viewport()->setCursor(Qt::BlankCursor); @@ -2825,7 +2825,7 @@ void TextEditorWidget::keyPressEvent(QKeyEvent *e) } if (blockSelectionOperation != QTextCursor::NoMove) { - clearBlockSelectionGuard.dismiss(); + cleanup.dismiss(); d->handleMoveBlockSelection(blockSelectionOperation); } else if (!d->cursorMoveKeyEvent(e)) { QTextCursor cursor = textCursor(); @@ -5275,7 +5275,7 @@ void TextEditorWidgetPrivate::paintTextMarks(QPainter &painter, const ExtraAreaP int yoffset = blockBoundingRect.top(); painter.save(); - const auto cleanup = qScopeGuard([&painter, size, yoffset, xoffset, overrideIcon] { + const QScopeGuard cleanup([&painter, size, yoffset, xoffset, overrideIcon] { if (!overrideIcon.isNull()) { const QRect r(xoffset, yoffset, size, size); overrideIcon.paint(&painter, r, Qt::AlignCenter); diff --git a/src/plugins/texteditor/texteditor.qbs b/src/plugins/texteditor/texteditor.qbs index 071e0b5fc2a..fa8441f29ef 100644 --- a/src/plugins/texteditor/texteditor.qbs +++ b/src/plugins/texteditor/texteditor.qbs @@ -226,6 +226,8 @@ Project { files: [ "codeassist/codeassist_test.cpp", "codeassist/codeassist_test.h", + "highlighter_test.cpp", + "highlighter_test.h", "texteditor_test.cpp", ] } diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index 4d5c2268d1e..f82155c0a54 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -22,6 +22,7 @@ #ifdef WITH_TESTS #include "codeassist/codeassist_test.h" +#include "highlighter_test.h" #endif #include <coreplugin/actionmanager/actioncontainer.h> @@ -149,6 +150,7 @@ void TextEditorPlugin::initialize() #ifdef WITH_TESTS addTest<CodeAssistTests>(); + addTest<GenerigHighlighterTests>(); #endif } |