File indexing completed on 2024-12-01 12:38:40
0001 /* 0002 This file is part of the Kate project. 0003 SPDX-FileCopyrightText: 2013 Dominik Haumann <dhaumann@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "katefoldingtest.h" 0009 0010 #include <katebuffer.h> 0011 #include <kateconfig.h> 0012 #include <katedocument.h> 0013 #include <kateglobal.h> 0014 #include <katetextfolding.h> 0015 #include <kateview.h> 0016 0017 #include <QJsonDocument> 0018 #include <QtTestWidgets> 0019 0020 #include <memory> 0021 0022 using namespace KTextEditor; 0023 0024 QTEST_MAIN(KateFoldingTest) 0025 0026 void KateFoldingTest::initTestCase() 0027 { 0028 KTextEditor::EditorPrivate::enableUnitTestMode(); 0029 } 0030 0031 void KateFoldingTest::cleanupTestCase() 0032 { 0033 } 0034 0035 // This is a unit test for bug 311866 (https://bugs.kde.org/show_bug.cgi?id=311866) 0036 // It loads 5 lines of C++ code, places the cursor in line 4, and then folds 0037 // the code. 0038 // Expected behavior: the cursor should be moved so it stays visible 0039 // Buggy behavior: the cursor is hidden, and moving the hidden cursor crashes kate 0040 void KateFoldingTest::testCrash311866() 0041 { 0042 KTextEditor::DocumentPrivate doc; 0043 const QUrl url = QUrl::fromLocalFile(QLatin1String(TEST_DATA_DIR "bug311866.cpp")); 0044 doc.openUrl(url); 0045 doc.setHighlightingMode("C++"); 0046 doc.buffer().ensureHighlighted(6); 0047 0048 const std::unique_ptr<ViewPrivate> view{static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr))}; 0049 view->show(); 0050 view->resize(400, 300); 0051 view->setCursorPosition(Cursor(3, 0)); 0052 QTest::qWait(100); 0053 0054 view->slotFoldToplevelNodes(); 0055 doc.buffer().ensureHighlighted(6); 0056 0057 qDebug() << "!!! Does the next line crash?"; 0058 view->up(); 0059 } 0060 0061 // This test makes sure that, 0062 // - if you have selected text 0063 // - that spans a folded range, 0064 // - and the cursor is at the end of the text selection, 0065 // - and you type a char, e.g. 'x', 0066 // then the resulting text is correct, and changing region 0067 // visibility does not mess around with the text cursor. 0068 // 0069 // See https://bugs.kde.org/show_bug.cgi?id=295632 0070 void KateFoldingTest::testBug295632() 0071 { 0072 KTextEditor::DocumentPrivate doc; 0073 QString text = 0074 "oooossssssss\n" 0075 "{\n" 0076 "\n" 0077 "}\n" 0078 "ssssss----------"; 0079 doc.setText(text); 0080 0081 // view must be visible... 0082 const std::unique_ptr<ViewPrivate> view{static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr))}; 0083 view->show(); 0084 view->resize(400, 300); 0085 0086 qint64 foldId = view->textFolding().newFoldingRange(KTextEditor::Range(1, 0, 3, 1)); 0087 view->textFolding().foldRange(foldId); 0088 QVERIFY(view->textFolding().isLineVisible(0)); 0089 QVERIFY(view->textFolding().isLineVisible(1)); 0090 QVERIFY(!view->textFolding().isLineVisible(2)); 0091 QVERIFY(!view->textFolding().isLineVisible(3)); 0092 QVERIFY(view->textFolding().isLineVisible(4)); 0093 0094 view->setSelection(Range(Cursor(0, 4), Cursor(4, 6))); 0095 view->setCursorPosition(Cursor(4, 6)); 0096 0097 QTest::qWait(100); 0098 doc.typeChars(view.get(), "x"); 0099 QTest::qWait(100); 0100 0101 QString line = doc.line(0); 0102 QCOMPARE(line, QString("oooox----------")); 0103 } 0104 0105 // This testcase tests the following: 0106 // - the cursor is first set into the word 'hello' 0107 // - then lines 0-3 are folded. 0108 // - the real text cursor is still in the word 'hello' 0109 // - the important issue is: The display cursor must be in the visible line range 0110 // --> if this test passes, KateViewInternal's m_displayCursor is properly adapted. 0111 void KateFoldingTest::testCrash367466() 0112 { 0113 KTextEditor::DocumentPrivate doc; 0114 0115 // we use only x to have equal width characters, else we fail for non-fixed width fonts 0116 QString text = 0117 "xxxx xxxx\n" 0118 "\n" 0119 "\n" 0120 "xxxx xxx\n" 0121 "xxxxx\n" 0122 "xxxxx\n"; 0123 doc.setText(text); 0124 0125 // view must be visible... 0126 const std::unique_ptr<ViewPrivate> view{static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr))}; 0127 view->show(); 0128 view->resize(400, 300); 0129 view->setCursorPosition(KTextEditor::Cursor(5, 2)); 0130 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(5, 2)); 0131 qint64 foldId = view->textFolding().newFoldingRange(KTextEditor::Range(0, 0, 3, 8)); 0132 0133 view->textFolding().foldRange(foldId); 0134 QVERIFY(view->textFolding().isLineVisible(0)); 0135 QVERIFY(!view->textFolding().isLineVisible(1)); 0136 QVERIFY(!view->textFolding().isLineVisible(2)); 0137 QVERIFY(!view->textFolding().isLineVisible(3)); 0138 QVERIFY(view->textFolding().isLineVisible(4)); 0139 QVERIFY(view->textFolding().isLineVisible(5)); 0140 0141 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(5, 2)); 0142 view->up(); 0143 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(4, 2)); 0144 } 0145 0146 void KateFoldingTest::testUnfoldingInImportFoldingRanges() 0147 { 0148 DocumentPrivate doc; 0149 const auto text = QStringLiteral( 0150 "int f(bool one) {\n" 0151 " if (one) {\n" 0152 " return 1;\n" 0153 " } else {\n" 0154 " return 0;\n" 0155 " }\n" 0156 "}\n" 0157 "\n" 0158 "int g() {\n" 0159 " return 123;\n" 0160 "}\n"); 0161 doc.setText(text); 0162 0163 // view must be visible... 0164 const std::unique_ptr<ViewPrivate> view{static_cast<ViewPrivate *>(doc.createView(nullptr))}; 0165 view->show(); 0166 view->resize(400, 300); 0167 0168 auto &textFolding = view->textFolding(); 0169 0170 const auto addFoldedRange = [&textFolding](Range range, Kate::TextFolding::FoldingRangeFlags extraFlags = {}) { 0171 textFolding.newFoldingRange(range, Kate::TextFolding::Folded | extraFlags); 0172 }; 0173 addFoldedRange(Range(0, 16, 6, 1)); // f() 0174 addFoldedRange(Range(8, 8, 10, 1)); // g() 0175 addFoldedRange(Range(1, 13, 3, 5), Kate::TextFolding::Persistent); // if 0176 addFoldedRange(Range(3, 11, 5, 5)); // else 0177 0178 textFolding.importFoldingRanges(QJsonDocument{}); 0179 // TextFolding::importFoldingRanges() should remove all existing folding ranges 0180 // - both top-level and nested - before importing new ones. 0181 QCOMPARE(textFolding.debugDump(), QLatin1String("tree - folded ")); 0182 } 0183 0184 #include "moc_katefoldingtest.cpp"