File indexing completed on 2024-10-06 03:41:16
0001 /* 0002 This file is part of the KDE libraries 0003 SPDX-FileCopyrightText: 2010-2018 Dominik Haumann <dhaumann@kde.org> 0004 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 0008 #include "movingcursor_test.h" 0009 #include "moc_movingcursor_test.cpp" 0010 0011 #include <katedocument.h> 0012 #include <kateglobal.h> 0013 #include <ktexteditor/movingcursor.h> 0014 0015 #include <QTest> 0016 0017 using namespace KTextEditor; 0018 0019 QTEST_MAIN(MovingCursorTest) 0020 0021 MovingCursorTest::MovingCursorTest() 0022 : QObject() 0023 { 0024 KTextEditor::EditorPrivate::enableUnitTestMode(); 0025 } 0026 0027 MovingCursorTest::~MovingCursorTest() 0028 { 0029 } 0030 0031 // tests: 0032 // - MovingCursor with StayOnInsert 0033 // - MovingCursor with MoveOnInsert 0034 void MovingCursorTest::testMovingCursor() 0035 { 0036 KTextEditor::DocumentPrivate doc; 0037 MovingCursor *invalid = doc.newMovingCursor(Cursor::invalid()); 0038 MovingCursor *moveOnInsert = doc.newMovingCursor(Cursor(0, 0), MovingCursor::MoveOnInsert); 0039 MovingCursor *stayOnInsert = doc.newMovingCursor(Cursor(0, 0), MovingCursor::StayOnInsert); 0040 0041 // verify initial conditions 0042 QVERIFY(!invalid->isValid()); 0043 QCOMPARE(moveOnInsert->toCursor(), Cursor(0, 0)); 0044 QCOMPARE(stayOnInsert->toCursor(), Cursor(0, 0)); 0045 0046 // insert some text 0047 doc.insertText(Cursor(0, 0), QStringLiteral("\n1\n22")); 0048 0049 // check new cursor positions 0050 QCOMPARE(moveOnInsert->toCursor(), Cursor(2, 2)); 0051 QCOMPARE(stayOnInsert->toCursor(), Cursor(0, 0)); 0052 0053 // set position to (1, 1) and insert text before cursor 0054 stayOnInsert->setPosition(Cursor(1, 1)); 0055 QCOMPARE(stayOnInsert->toCursor(), Cursor(1, 1)); 0056 doc.insertText(Cursor(1, 0), QStringLiteral("test")); 0057 QCOMPARE(stayOnInsert->toCursor(), Cursor(1, 5)); 0058 doc.undo(); 0059 QCOMPARE(stayOnInsert->toCursor(), Cursor(1, 1)); 0060 0061 // position still at (1, 1). insert text at cursor 0062 doc.insertText(Cursor(1, 1), QStringLiteral("test")); 0063 QCOMPARE(stayOnInsert->toCursor(), Cursor(1, 1)); 0064 doc.undo(); 0065 QCOMPARE(stayOnInsert->toCursor(), Cursor(1, 1)); 0066 0067 // 0068 // same tests with the moveOnInsert cursor 0069 // 0070 // set position to (1, 1) and insert text before cursor 0071 moveOnInsert->setPosition(Cursor(1, 1)); 0072 QCOMPARE(moveOnInsert->toCursor(), Cursor(1, 1)); 0073 doc.insertText(Cursor(1, 0), QStringLiteral("test")); 0074 QCOMPARE(moveOnInsert->toCursor(), Cursor(1, 5)); 0075 doc.undo(); 0076 QCOMPARE(moveOnInsert->toCursor(), Cursor(1, 1)); 0077 0078 // position still at (1, 1). insert text at cursor 0079 doc.insertText(Cursor(1, 1), QStringLiteral("test")); 0080 QCOMPARE(moveOnInsert->toCursor(), Cursor(1, 5)); 0081 doc.undo(); 0082 QCOMPARE(moveOnInsert->toCursor(), Cursor(1, 1)); 0083 0084 // set both cursors to (2, 1) then delete text range that contains cursors 0085 moveOnInsert->setPosition(Cursor(2, 1)); 0086 stayOnInsert->setPosition(Cursor(2, 1)); 0087 doc.removeText(Range(Cursor(2, 0), Cursor(2, 2))); 0088 QCOMPARE(moveOnInsert->toCursor(), Cursor(2, 0)); 0089 QCOMPARE(moveOnInsert->toCursor(), Cursor(2, 0)); 0090 } 0091 0092 // tests: 0093 // - atStartOfDocument 0094 // - atStartOfLine 0095 // - atEndOfDocument 0096 // - atEndOfLine 0097 // - move forward with Wrap 0098 // - move forward with NoWrap 0099 // - move backward 0100 // - gotoNextLine 0101 // - gotoPreviousLine 0102 void MovingCursorTest::testConvenienceApi() 0103 { 0104 KTextEditor::DocumentPrivate doc; 0105 doc.setText( 0106 QStringLiteral("\n" 0107 "1\n" 0108 "22\n" 0109 "333\n" 0110 "4444\n" 0111 "55555")); 0112 0113 // check start and end of document 0114 MovingCursor *startOfDoc = doc.newMovingCursor(Cursor(0, 0)); 0115 MovingCursor *endOfDoc = doc.newMovingCursor(Cursor(5, 5)); 0116 QVERIFY(startOfDoc->atStartOfDocument()); 0117 QVERIFY(startOfDoc->atStartOfLine()); 0118 QVERIFY(endOfDoc->atEndOfDocument()); 0119 QVERIFY(endOfDoc->atEndOfLine()); 0120 0121 // set cursor to (2, 2) and then move to the left two times 0122 MovingCursor *moving = doc.newMovingCursor(Cursor(2, 2)); 0123 QVERIFY(moving->atEndOfLine()); // at 2, 2 0124 QVERIFY(moving->move(-1)); // at 2, 1 0125 QCOMPARE(moving->toCursor(), Cursor(2, 1)); 0126 QVERIFY(!moving->atEndOfLine()); 0127 QVERIFY(moving->move(-1)); // at 2, 0 0128 QCOMPARE(moving->toCursor(), Cursor(2, 0)); 0129 QVERIFY(moving->atStartOfLine()); 0130 0131 // now move again to the left, should wrap to (1, 1) 0132 QVERIFY(moving->move(-1)); // at 1, 1 0133 QCOMPARE(moving->toCursor(), Cursor(1, 1)); 0134 QVERIFY(moving->atEndOfLine()); 0135 0136 // advance 7 characters to position (3, 3) 0137 QVERIFY(moving->move(7)); // at 3, 3 0138 QCOMPARE(moving->toCursor(), Cursor(3, 3)); 0139 0140 // advance 20 characters in NoWrap mode, then go back 10 characters 0141 QVERIFY(moving->move(20, MovingCursor::NoWrap)); // at 3, 23 0142 QCOMPARE(moving->toCursor(), Cursor(3, 23)); 0143 QVERIFY(moving->move(-10)); // at 3, 13 0144 QCOMPARE(moving->toCursor(), Cursor(3, 13)); 0145 0146 // still at invalid text position. move one char to wrap around 0147 QVERIFY(!moving->isValidTextPosition()); // at 3, 13 0148 QVERIFY(moving->move(1)); // at 4, 0 0149 QCOMPARE(moving->toCursor(), Cursor(4, 0)); 0150 0151 // moving 11 characters in wrap mode moves to (5, 6), which is not a valid 0152 // text position anymore. Hence, moving should be rejected. 0153 QVERIFY(!moving->move(11)); 0154 QVERIFY(moving->move(10)); 0155 QVERIFY(moving->atEndOfDocument()); 0156 0157 // try to move to next line, which fails. then go to previous line 0158 QVERIFY(!moving->gotoNextLine()); 0159 QVERIFY(moving->gotoPreviousLine()); 0160 QCOMPARE(moving->toCursor(), Cursor(4, 0)); 0161 } 0162 0163 void MovingCursorTest::testOperators() 0164 { 0165 KTextEditor::DocumentPrivate doc; 0166 doc.setText( 0167 QStringLiteral("--oo--\n" 0168 "--oo--\n" 0169 "--oo--")); 0170 0171 // create lots of cursors for comparison 0172 Cursor invalid = Cursor::invalid(); 0173 Cursor c02(0, 2); 0174 Cursor c04(0, 4); 0175 Cursor c14(1, 4); 0176 0177 MovingCursor *m02 = doc.newMovingCursor(Cursor(0, 2)); 0178 MovingCursor *m04 = doc.newMovingCursor(Cursor(0, 4)); 0179 MovingCursor *m14 = doc.newMovingCursor(Cursor(1, 4)); 0180 0181 // invalid comparison 0182 QVERIFY(invalid == invalid); 0183 QVERIFY(invalid <= c02); 0184 QVERIFY(invalid < c02); 0185 QVERIFY(!(invalid > c02)); 0186 QVERIFY(!(invalid >= c02)); 0187 0188 QVERIFY(!(invalid == *m02)); 0189 QVERIFY(invalid <= *m02); 0190 QVERIFY(invalid < *m02); 0191 QVERIFY(!(invalid > *m02)); 0192 QVERIFY(!(invalid >= *m02)); 0193 0194 QVERIFY(!(*m02 == invalid)); 0195 QVERIFY(!(*m02 <= invalid)); 0196 QVERIFY(!(*m02 < invalid)); 0197 QVERIFY(*m02 > invalid); 0198 QVERIFY(*m02 >= invalid); 0199 0200 // MovingCursor <-> MovingCursor 0201 QVERIFY(*m02 == *m02); 0202 QVERIFY(*m02 <= *m02); 0203 QVERIFY(*m02 >= *m02); 0204 QVERIFY(!(*m02 < *m02)); 0205 QVERIFY(!(*m02 > *m02)); 0206 QVERIFY(!(*m02 != *m02)); 0207 0208 QVERIFY(!(*m02 == *m04)); 0209 QVERIFY(*m02 <= *m04); 0210 QVERIFY(!(*m02 >= *m04)); 0211 QVERIFY(*m02 < *m04); 0212 QVERIFY(!(*m02 > *m04)); 0213 QVERIFY(*m02 != *m04); 0214 0215 QVERIFY(!(*m04 == *m02)); 0216 QVERIFY(!(*m04 <= *m02)); 0217 QVERIFY(*m04 >= *m02); 0218 QVERIFY(!(*m04 < *m02)); 0219 QVERIFY(*m04 > *m02); 0220 QVERIFY(*m04 != *m02); 0221 0222 QVERIFY(!(*m02 == *m14)); 0223 QVERIFY(*m02 <= *m14); 0224 QVERIFY(!(*m02 >= *m14)); 0225 QVERIFY(*m02 < *m14); 0226 QVERIFY(!(*m02 > *m14)); 0227 QVERIFY(*m02 != *m14); 0228 0229 QVERIFY(!(*m14 == *m02)); 0230 QVERIFY(!(*m14 <= *m02)); 0231 QVERIFY(*m14 >= *m02); 0232 QVERIFY(!(*m14 < *m02)); 0233 QVERIFY(*m14 > *m02); 0234 QVERIFY(*m14 != *m02); 0235 0236 // MovingCursor <-> Cursor 0237 QVERIFY(*m02 == c02); 0238 QVERIFY(*m02 <= c02); 0239 QVERIFY(*m02 >= c02); 0240 QVERIFY(!(*m02 < c02)); 0241 QVERIFY(!(*m02 > c02)); 0242 QVERIFY(!(*m02 != c02)); 0243 0244 QVERIFY(!(*m02 == c04)); 0245 QVERIFY(*m02 <= c04); 0246 QVERIFY(!(*m02 >= c04)); 0247 QVERIFY(*m02 < c04); 0248 QVERIFY(!(*m02 > c04)); 0249 QVERIFY(*m02 != c04); 0250 0251 QVERIFY(!(*m04 == c02)); 0252 QVERIFY(!(*m04 <= c02)); 0253 QVERIFY(*m04 >= c02); 0254 QVERIFY(!(*m04 < c02)); 0255 QVERIFY(*m04 > c02); 0256 QVERIFY(*m04 != c02); 0257 0258 QVERIFY(!(*m02 == c14)); 0259 QVERIFY(*m02 <= c14); 0260 QVERIFY(!(*m02 >= c14)); 0261 QVERIFY(*m02 < c14); 0262 QVERIFY(!(*m02 > c14)); 0263 QVERIFY(*m02 != c14); 0264 0265 QVERIFY(!(*m14 == c02)); 0266 QVERIFY(!(*m14 <= c02)); 0267 QVERIFY(*m14 >= c02); 0268 QVERIFY(!(*m14 < c02)); 0269 QVERIFY(*m14 > c02); 0270 QVERIFY(*m14 != c02); 0271 0272 // Cursor <-> MovingCursor 0273 QVERIFY(c02 == *m02); 0274 QVERIFY(c02 <= *m02); 0275 QVERIFY(c02 >= *m02); 0276 QVERIFY(!(c02 < *m02)); 0277 QVERIFY(!(c02 > *m02)); 0278 QVERIFY(!(c02 != *m02)); 0279 0280 QVERIFY(!(c02 == *m04)); 0281 QVERIFY(c02 <= *m04); 0282 QVERIFY(!(c02 >= *m04)); 0283 QVERIFY(c02 < *m04); 0284 QVERIFY(!(c02 > *m04)); 0285 QVERIFY(c02 != *m04); 0286 0287 QVERIFY(!(c04 == *m02)); 0288 QVERIFY(!(c04 <= *m02)); 0289 QVERIFY(c04 >= *m02); 0290 QVERIFY(!(c04 < *m02)); 0291 QVERIFY(c04 > *m02); 0292 QVERIFY(c04 != *m02); 0293 0294 QVERIFY(!(c02 == *m14)); 0295 QVERIFY(c02 <= *m14); 0296 QVERIFY(!(c02 >= *m14)); 0297 QVERIFY(c02 < *m14); 0298 QVERIFY(!(c02 > *m14)); 0299 QVERIFY(c02 != *m14); 0300 0301 QVERIFY(!(c14 == *m02)); 0302 QVERIFY(!(c14 <= *m02)); 0303 QVERIFY(c14 >= *m02); 0304 QVERIFY(!(c14 < *m02)); 0305 QVERIFY(c14 > *m02); 0306 QVERIFY(c14 != *m02); 0307 } 0308 0309 void MovingCursorTest::testInvalidMovingCursor() 0310 { 0311 KTextEditor::DocumentPrivate *doc = new KTextEditor::DocumentPrivate; 0312 0313 // add invalid MovingCursor. Inserts c into KateBuffer::m_invalidCursors 0314 MovingCursor *c = doc->newMovingCursor(Cursor(-1, -1)); 0315 QVERIFY(Cursor(-1, -1) == *c); 0316 0317 c->setPosition(Cursor(0, 0)); 0318 QVERIFY(Cursor(0, 0) == *c); 0319 0320 // now c should be removed from KateBuffer::m_invalidCursors 0321 delete c; 0322 0323 // crash in bug https://bugs.kde.org/show_bug.cgi?id=248926 0324 // if it crashes: c is still in KateBuffer::m_invalidCursors -> double deletion 0325 delete doc; 0326 }