File indexing completed on 2024-04-28 15:30:14

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 <QtTestWidgets>
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     KateUndoManager *undoManager = doc.undoManager();
0032 
0033     // no undo/redo items at the beginning
0034     QCOMPARE(undoManager->undoCount(), 0u);
0035     QCOMPARE(undoManager->redoCount(), 0u);
0036 
0037     doc.insertText(Cursor(0, 0), QLatin1String("a"));
0038 
0039     // create one insert-group
0040     QCOMPARE(undoManager->undoCount(), 1u);
0041     QCOMPARE(undoManager->redoCount(), 0u);
0042 
0043     doc.undo();
0044 
0045     // move insert-group to redo items
0046     QCOMPARE(undoManager->undoCount(), 0u);
0047     QCOMPARE(undoManager->redoCount(), 1u);
0048 
0049     doc.redo();
0050 
0051     // move insert-group back to undo items
0052     QCOMPARE(undoManager->undoCount(), 1u);
0053     QCOMPARE(undoManager->redoCount(), 0u);
0054 
0055     doc.insertText(Cursor(0, 1), QLatin1String("b"));
0056 
0057     // merge "b" into insert-group
0058     QCOMPARE(undoManager->undoCount(), 1u);
0059     QCOMPARE(undoManager->redoCount(), 0u);
0060 
0061     doc.removeText(Range(0, 1, 0, 2));
0062 
0063     // create an additional remove-group
0064     QCOMPARE(undoManager->undoCount(), 2u);
0065     QCOMPARE(undoManager->redoCount(), 0u);
0066 
0067     doc.undo();
0068 
0069     // move remove-group to redo items
0070     QCOMPARE(undoManager->undoCount(), 1u);
0071     QCOMPARE(undoManager->redoCount(), 1u);
0072 
0073     doc.insertText(Cursor(0, 1), QLatin1String("b"));
0074 
0075     // merge "b" into insert-group
0076     // and remove remove-group
0077     QCOMPARE(undoManager->undoCount(), 1u);
0078     QCOMPARE(undoManager->redoCount(), 0u);
0079 }
0080 
0081 void UndoManagerTest::testSafePoint()
0082 {
0083     KTextEditor::DocumentPrivate doc;
0084     KateUndoManager *undoManager = doc.undoManager();
0085 
0086     doc.insertText(Cursor(0, 0), QLatin1String("a"));
0087 
0088     // create one undo group
0089     QCOMPARE(undoManager->undoCount(), 1u);
0090     QCOMPARE(undoManager->redoCount(), 0u);
0091 
0092     undoManager->undoSafePoint();
0093     doc.insertText(Cursor(0, 1), QLatin1String("b"));
0094 
0095     // create a second undo group (don't merge)
0096     QCOMPARE(undoManager->undoCount(), 2u);
0097 
0098     doc.undo();
0099 
0100     // move second undo group to redo items
0101     QCOMPARE(undoManager->undoCount(), 1u);
0102     QCOMPARE(undoManager->redoCount(), 1u);
0103 
0104     doc.insertText(Cursor(0, 1), QLatin1String("b"));
0105 
0106     // create a second undo group again, (don't merge)
0107     QCOMPARE(undoManager->undoCount(), 2u);
0108     QCOMPARE(undoManager->redoCount(), 0u);
0109 
0110     doc.editStart();
0111     doc.insertText(Cursor(0, 2), QLatin1String("c"));
0112     undoManager->undoSafePoint();
0113     doc.insertText(Cursor(0, 3), QLatin1String("d"));
0114     doc.editEnd();
0115 
0116     // merge both edits into second undo group
0117     QCOMPARE(undoManager->undoCount(), 2u);
0118     QCOMPARE(undoManager->redoCount(), 0u);
0119 
0120     doc.insertText(Cursor(0, 4), QLatin1String("e"));
0121 
0122     // create a third undo group (don't merge)
0123     QCOMPARE(undoManager->undoCount(), 3u);
0124     QCOMPARE(undoManager->redoCount(), 0u);
0125 }
0126 
0127 void UndoManagerTest::testCursorPosition()
0128 {
0129     KTextEditor::DocumentPrivate doc;
0130     KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr));
0131 
0132     doc.setText(
0133         QLatin1String("aaaa bbbb cccc\n"
0134                       "dddd  ffff"));
0135     view->setCursorPosition(KTextEditor::Cursor(1, 5));
0136 
0137     doc.typeChars(view, QLatin1String("eeee"));
0138 
0139     // cursor position: "dddd eeee| ffff"
0140     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 9));
0141 
0142     // undo once to remove "eeee", cursor position: "dddd | ffff"
0143     doc.undo();
0144     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 5));
0145 
0146     // redo once to insert "eeee" again. cursor position: "dddd eeee| ffff"
0147     doc.redo();
0148     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 9));
0149 
0150     delete view;
0151 }
0152 
0153 void UndoManagerTest::testSelectionUndo()
0154 {
0155     KTextEditor::DocumentPrivate doc;
0156     KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr));
0157 
0158     doc.setText(
0159         QLatin1String("aaaa bbbb cccc\n"
0160                       "dddd eeee ffff"));
0161     view->setCursorPosition(KTextEditor::Cursor(1, 9));
0162     KTextEditor::Range selectionRange(KTextEditor::Cursor(0, 5), KTextEditor::Cursor(1, 9));
0163     view->setSelection(selectionRange);
0164 
0165     doc.typeChars(view, QLatin1String(QLatin1String("eeee")));
0166 
0167     // cursor position: "aaaa eeee| ffff", no selection anymore
0168     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, 9));
0169     QCOMPARE(view->selection(), false);
0170 
0171     // undo to remove "eeee" and add selection and text again
0172     doc.undo();
0173     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 9));
0174     QCOMPARE(view->selection(), true);
0175     QCOMPARE(view->selectionRange(), selectionRange);
0176 
0177     // redo to insert "eeee" again and remove selection
0178     // cursor position: "aaaa eeee| ffff", no selection anymore
0179     doc.redo();
0180     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, 9));
0181     QCOMPARE(view->selection(), false);
0182 
0183     delete view;
0184 }
0185 
0186 void UndoManagerTest::testUndoWordWrapBug301367()
0187 {
0188     KTextEditor::DocumentPrivate doc;
0189     doc.setWordWrap(true);
0190     doc.setWordWrapAt(20);
0191     KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr));
0192 
0193     QString text = QString::fromLatin1(
0194         "1234 1234 1234 1234\n"
0195         "1234 1234 1234 1234");
0196 
0197     doc.setText(text);
0198     view->setCursorPosition(KTextEditor::Cursor(0, 0));
0199 
0200     doc.typeChars(view, QLatin1String("           "));
0201 
0202     while (doc.undoCount() > 1) {
0203         doc.undo();
0204     }
0205 
0206     // test must be exactly the same as before
0207     QCOMPARE(doc.text(), text);
0208 
0209     while (doc.redoCount() > 1) {
0210         doc.redo();
0211     }
0212 
0213     while (doc.undoCount() > 1) {
0214         doc.undo();
0215     }
0216 
0217     // test must be exactly the same as before
0218     QCOMPARE(doc.text(), text);
0219 
0220     delete view;
0221 }
0222 
0223 void UndoManagerTest::testUndoIndentBug373009()
0224 {
0225     KTextEditor::DocumentPrivate doc;
0226     KTextEditor::ViewPrivate *view = static_cast<KTextEditor::ViewPrivate *>(doc.createView(nullptr));
0227 
0228     doc.setMode("C");
0229 
0230     QString text = QString::fromLatin1(
0231         "    while (whatever) printf (\"please fix indentation.\\n\");\n"
0232         "    return 0;");
0233     doc.setText(text);
0234 
0235     // position cursor right before return
0236     view->setCursorPosition(KTextEditor::Cursor(1, 4));
0237 
0238     QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(1, 4));
0239     QCOMPARE(doc.characterAt(view->cursorPosition()), 'r');
0240 
0241     view->keyReturn();
0242 
0243     QCOMPARE(doc.undoCount(), 2);
0244 
0245     // After indent we should be able to revert with
0246     // one undo operation
0247     doc.undo();
0248     QCOMPARE(doc.text(), text);
0249 
0250     delete view;
0251 }
0252 
0253 #include "moc_undomanager_test.cpp"