File indexing completed on 2025-04-20 03:41:54
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2010 Bernhard Beschow <bbeschow@cs.tu-berlin.de> 0004 SPDX-FileCopyrightText: 2009-2018 Dominik Haumann <dhaumann@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.0-or-later 0007 */ 0008 0009 #include "undomanager_test.h" 0010 0011 #include <katedocument.h> 0012 #include <kateglobal.h> 0013 #include <kateundomanager.h> 0014 #include <kateview.h> 0015 0016 #include <QTest> 0017 0018 QTEST_MAIN(UndoManagerTest) 0019 0020 using namespace KTextEditor; 0021 0022 UndoManagerTest::UndoManagerTest() 0023 : QObject() 0024 { 0025 KTextEditor::EditorPrivate::enableUnitTestMode(); 0026 } 0027 0028 void UndoManagerTest::testUndoRedoCount() 0029 { 0030 KTextEditor::DocumentPrivate doc; 0031 0032 // no undo/redo items at the beginning 0033 QCOMPARE(doc.undoCount(), 0u); 0034 QCOMPARE(doc.redoCount(), 0u); 0035 0036 doc.insertText(Cursor(0, 0), QStringLiteral("a")); 0037 0038 // create one insert-group 0039 QCOMPARE(doc.undoCount(), 1u); 0040 QCOMPARE(doc.redoCount(), 0u); 0041 0042 doc.undo(); 0043 0044 // move insert-group to redo items 0045 QCOMPARE(doc.undoCount(), 0u); 0046 QCOMPARE(doc.redoCount(), 1u); 0047 0048 doc.redo(); 0049 0050 // move insert-group back to undo items 0051 QCOMPARE(doc.undoCount(), 1u); 0052 QCOMPARE(doc.redoCount(), 0u); 0053 0054 doc.insertText(Cursor(0, 1), QStringLiteral("b")); 0055 0056 // merge "b" into insert-group 0057 QCOMPARE(doc.undoCount(), 1u); 0058 QCOMPARE(doc.redoCount(), 0u); 0059 0060 doc.removeText(Range(0, 1, 0, 2)); 0061 0062 // create an additional remove-group 0063 QCOMPARE(doc.undoCount(), 2u); 0064 QCOMPARE(doc.redoCount(), 0u); 0065 0066 doc.undo(); 0067 0068 // move remove-group to redo items 0069 QCOMPARE(doc.undoCount(), 1u); 0070 QCOMPARE(doc.redoCount(), 1u); 0071 0072 doc.insertText(Cursor(0, 1), QStringLiteral("b")); 0073 0074 // merge "b" into insert-group 0075 // and remove remove-group 0076 QCOMPARE(doc.undoCount(), 1u); 0077 QCOMPARE(doc.redoCount(), 0u); 0078 } 0079 0080 void UndoManagerTest::testSafePoint() 0081 { 0082 KTextEditor::DocumentPrivate doc; 0083 KateUndoManager *undoManager = doc.undoManager(); 0084 0085 doc.insertText(Cursor(0, 0), QStringLiteral("a")); 0086 0087 // create one undo group 0088 QCOMPARE(doc.undoCount(), 1u); 0089 QCOMPARE(doc.redoCount(), 0u); 0090 0091 undoManager->undoSafePoint(); 0092 doc.insertText(Cursor(0, 1), QStringLiteral("b")); 0093 0094 // create a second undo group (don't merge) 0095 QCOMPARE(doc.undoCount(), 2u); 0096 0097 doc.undo(); 0098 0099 // move second undo group to redo items 0100 QCOMPARE(doc.undoCount(), 1u); 0101 QCOMPARE(doc.redoCount(), 1u); 0102 0103 doc.insertText(Cursor(0, 1), QStringLiteral("b")); 0104 0105 // create a second undo group again, (don't merge) 0106 QCOMPARE(doc.undoCount(), 2u); 0107 QCOMPARE(doc.redoCount(), 0u); 0108 0109 doc.editStart(); 0110 doc.insertText(Cursor(0, 2), QStringLiteral("c")); 0111 undoManager->undoSafePoint(); 0112 doc.insertText(Cursor(0, 3), QStringLiteral("d")); 0113 doc.editEnd(); 0114 0115 // merge both edits into second undo group 0116 QCOMPARE(doc.undoCount(), 2u); 0117 QCOMPARE(doc.redoCount(), 0u); 0118 0119 doc.insertText(Cursor(0, 4), QStringLiteral("e")); 0120 0121 // create a third undo group (don't merge) 0122 QCOMPARE(doc.undoCount(), 3u); 0123 QCOMPARE(doc.redoCount(), 0u); 0124 } 0125 0126 void UndoManagerTest::testCursorPosition() 0127 { 0128 KTextEditor::DocumentPrivate doc; 0129 KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr)); 0130 0131 doc.setText( 0132 QStringLiteral("aaaa bbbb cccc\n" 0133 "dddd ffff")); 0134 view->setCursorPosition(KTextEditor::Cursor(1, 5)); 0135 0136 doc.typeChars(view, QStringLiteral("eeee")); 0137 0138 // cursor position: "dddd eeee| ffff" 0139 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 9)); 0140 0141 // undo once to remove "eeee", cursor position: "dddd | ffff" 0142 doc.undo(); 0143 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 5)); 0144 0145 // redo once to insert "eeee" again. cursor position: "dddd eeee| ffff" 0146 doc.redo(); 0147 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 9)); 0148 0149 delete view; 0150 } 0151 0152 void UndoManagerTest::testSelectionUndo() 0153 { 0154 KTextEditor::DocumentPrivate doc; 0155 KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr)); 0156 0157 doc.setText( 0158 QStringLiteral("aaaa bbbb cccc\n" 0159 "dddd eeee ffff")); 0160 view->setCursorPosition(KTextEditor::Cursor(1, 9)); 0161 KTextEditor::Range selectionRange(KTextEditor::Cursor(0, 5), KTextEditor::Cursor(1, 9)); 0162 view->setSelection(selectionRange); 0163 0164 doc.typeChars(view, QStringLiteral("eeee")); 0165 0166 // cursor position: "aaaa eeee| ffff", no selection anymore 0167 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, 9)); 0168 QCOMPARE(view->selection(), false); 0169 0170 // undo to remove "eeee" and add selection and text again 0171 doc.undo(); 0172 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 9)); 0173 QCOMPARE(view->selection(), true); 0174 QCOMPARE(view->selectionRange(), selectionRange); 0175 0176 // redo to insert "eeee" again and remove selection 0177 // cursor position: "aaaa eeee| ffff", no selection anymore 0178 doc.redo(); 0179 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, 9)); 0180 QCOMPARE(view->selection(), false); 0181 0182 delete view; 0183 } 0184 0185 void UndoManagerTest::testUndoWordWrapBug301367() 0186 { 0187 KTextEditor::DocumentPrivate doc; 0188 doc.setWordWrap(true); 0189 doc.setWordWrapAt(20); 0190 KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr)); 0191 0192 QString text = QString::fromLatin1( 0193 "1234 1234 1234 1234\n" 0194 "1234 1234 1234 1234"); 0195 0196 doc.setText(text); 0197 view->setCursorPosition(KTextEditor::Cursor(0, 0)); 0198 0199 doc.typeChars(view, QStringLiteral(" ")); 0200 0201 while (doc.undoCount() > 1) { 0202 doc.undo(); 0203 } 0204 0205 // test must be exactly the same as before 0206 QCOMPARE(doc.text(), text); 0207 0208 while (doc.redoCount() > 1) { 0209 doc.redo(); 0210 } 0211 0212 while (doc.undoCount() > 1) { 0213 doc.undo(); 0214 } 0215 0216 // test must be exactly the same as before 0217 QCOMPARE(doc.text(), text); 0218 0219 delete view; 0220 } 0221 0222 void UndoManagerTest::testUndoIndentBug373009() 0223 { 0224 KTextEditor::DocumentPrivate doc; 0225 KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr)); 0226 0227 doc.setMode(QStringLiteral("C")); 0228 0229 QString text = QString::fromLatin1( 0230 " while (whatever) printf (\"please fix indentation.\\n\");\n" 0231 " return 0;"); 0232 doc.setText(text); 0233 0234 // position cursor right before return 0235 view->setCursorPosition(KTextEditor::Cursor(1, 4)); 0236 0237 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 4)); 0238 QCOMPARE(doc.characterAt(view->cursorPosition()), QLatin1Char('r')); 0239 0240 view->keyReturn(); 0241 0242 QCOMPARE(doc.undoCount(), 2); 0243 0244 // After indent we should be able to revert with 0245 // one undo operation 0246 doc.undo(); 0247 QCOMPARE(doc.text(), text); 0248 0249 delete view; 0250 } 0251 0252 void UndoManagerTest::testUndoAfterPastingWrappingLine() 0253 { 0254 KTextEditor::DocumentPrivate doc; 0255 std::unique_ptr<KTextEditor::ViewPrivate> view(static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr))); 0256 0257 const QString originalText = QStringLiteral("First Line\nSecond Line Four Words"); 0258 doc.setText(originalText); 0259 0260 // put cursor in first line and copy the whole line 0261 view->setCursorPosition({0, 0}); 0262 view->copy(); 0263 0264 // select 3rd word in line 0265 view->setSelection(KTextEditor::Range(1, 12, 1, 16)); 0266 0267 // paste the copied stuff 0268 view->paste(); 0269 0270 view->show(); 0271 0272 // undo the paste 0273 while (doc.undoCount() > 1) { 0274 doc.undo(); 0275 } 0276 0277 // text should be same as original now 0278 QCOMPARE(doc.text(), originalText); 0279 } 0280 0281 #include "moc_undomanager_test.cpp"