File indexing completed on 2024-10-13 06:37:51
0001 /* 0002 This file is part of the Kate project. 0003 0004 SPDX-FileCopyrightText: 2021 Waqar Ahmed <waqar.17a@gmail.com> 0005 SPDX-License-Identifier: LGPL-2.0-or-later 0006 */ 0007 #include "camelcursortest.h" 0008 0009 #include <katedocument.h> 0010 #include <kateview.h> 0011 0012 #include <QTest> 0013 0014 QTEST_MAIN(CamelCursorTest) 0015 0016 CamelCursorTest::CamelCursorTest(QObject *parent) 0017 : QObject(parent) 0018 { 0019 doc = new KTextEditor::DocumentPrivate(false, false); 0020 view = static_cast<KTextEditor::ViewPrivate *>(doc->createView(nullptr)); 0021 view->resize(100, 100); 0022 view->show(); 0023 } 0024 0025 CamelCursorTest::~CamelCursorTest() 0026 { 0027 delete doc; 0028 } 0029 0030 void CamelCursorTest::testWordMovementSingleRow_data() 0031 { 0032 /** 0033 * NOTE: If you are here to fix a bug, try not to add a new function please. 0034 * Instead consider adding a row here with the label as your bug-number. 0035 * 0036 * The other test cases are small because if this works, they will work automaitcally 0037 * since the core functionality is correct. 0038 */ 0039 0040 // The text for document 0041 QTest::addColumn<QString>("text"); 0042 // The number of Ctrl + Right/Left movements 0043 QTest::addColumn<int>("movements"); 0044 // The expected positions where your cursor is supposed to land 0045 QTest::addColumn<QList<int>>("colPos"); 0046 // Highlighting mode 0047 QTest::addColumn<QString>("HlMode"); 0048 0049 // clang-format off 0050 // row name text no of mov expected positions 0051 QTest::addRow("KateView") << QStringLiteral("KateView") << 2 << QList<int>{4, 8} << QStringLiteral("C++"); 0052 QTest::addRow("Q_LOGGING_CATEGORY") << QStringLiteral("Q_LOGGING_CATEGORY();") << 4 << QList<int>{2, 10, 18, 21} << QStringLiteral("C"); 0053 QTest::addRow("Q_L11GING_CATEG0RY") << QStringLiteral("Q_L11GING_CATEG0RY();") << 7 << QList<int>{2, 5, 10, 14, 16, 18, 21} << QString(); 0054 QTest::addRow("snake_case_name") << QStringLiteral("int snake_case_name = 123;") << 7 << QList<int>{4, 10, 15, 20, 22, 25, 26} << QString(); 0055 QTest::addRow("bad___SNAKE_case__") << QStringLiteral("int bad___SNAKE_case__ = 11;") << 7 << QList<int>{4, 10, 16, 23, 25, 27, 28} << QString(); 0056 QTest::addRow("QApplication") << QStringLiteral("QApplication app;") << 4 << QList<int>{1, 13, 16, 17} << QString(); 0057 QTest::addRow("ABCDead") << QStringLiteral("ABCDead") << 2 << QList<int>{3, 7} << QString(); 0058 QTest::addRow("SE_CheckBoxIndicator") << QStringLiteral("QStyle::SE_CheckBoxIndicator") << 7 << QList<int>{1, 6, 8, 11, 16, 19, 28} << QStringLiteral("C++"); 0059 QTest::addRow("SE_CHECKBoxIndicator") << QStringLiteral("QStyle::SE_CHECKBoxIndicator") << 7 << QList<int>{1, 6, 8, 11, 16, 19, 28} << QString(); 0060 QTest::addRow("SE_CHECKBOXINDICATOR") << QStringLiteral("QStyle::SE_CHECKBOXINDICATOR") << 5 << QList<int>{1, 6, 8, 11, 28} << QString(); 0061 QTest::addRow("abc0_asd") << QStringLiteral("int abc0_asd") << 3 << QList<int>{4, 9, 12} << QString(); 0062 QTest::addRow("abc120_aSD") << QStringLiteral("int abc120_aSD") << 4 << QList<int>{4, 11, 12, 14} << QString(); 0063 QTest::addRow("aQQ_OPEN") << QStringLiteral("aQQ_OPEN") << 3 << QList<int>{1, 4, 8} << QString(); 0064 QTest::addRow("aQQ_OPEN") << QStringLiteral(" aQQ_OPEN") << 4 << QList<int>{4, 5, 8, 12} << QString(); 0065 0066 // PHP stuff that starts with $ 0067 doc->setHighlightingMode(QStringLiteral("PHP/PHP")); 0068 QTest::addRow("$phpVar") << QStringLiteral("$phpVar = 0;") << 6 << QList<int>{1, 4, 8, 10, 11, 12} << QStringLiteral("PHP/PHP"); 0069 QTest::addRow("$php_Var") << QStringLiteral("$php_Var = 0;") << 6 << QList<int>{1, 5, 9, 11, 12, 13} << QStringLiteral("PHP/PHP"); 0070 QTest::addRow("$_SESSION") << QStringLiteral("$_SESSION[\"some\"]") << 6 << QList<int>{1, 2, 9, 11, 15, 17} << QStringLiteral("PHP/PHP"); 0071 0072 // CSS Color 0073 QTest::addRow("#ff00ff") << QStringLiteral("#ff00ff") << 2 << QList<int>{1, 7} << QStringLiteral("CSS"); 0074 QTest::addRow("#00FF00") << QStringLiteral("#00FF00") << 4 << QList<int>{1, 3, 4, 7} << QStringLiteral("HTML"); 0075 0076 QTest::addRow("Bug 448692") << QStringLiteral("asdf a") << 2 << QList<int>{5, 6} << QString(); 0077 // unicode 0078 QTest::addRow("unicode") << QStringLiteral("𝗺𝗮𝘆∕𝗺𝗶𝗴𝗵𝘁") << 3 << QList<int>{6, 7, 17} << QString(); 0079 0080 // clang-format on 0081 } 0082 0083 void CamelCursorTest::testWordMovementSingleRow() 0084 { 0085 QFETCH(QString, text); 0086 QFETCH(int, movements); 0087 QFETCH(QList<int>, colPos); 0088 QFETCH(QString, HlMode); 0089 0090 doc->setHighlightingMode(HlMode); 0091 0092 doc->setText(text); 0093 view->setCursorPosition({0, 0}); 0094 0095 for (int i = 0; i < movements; ++i) { 0096 view->wordRight(); 0097 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, colPos.at(i))); 0098 } 0099 0100 // reverse jumping. Reverse everything but last 0101 // element. Last element will be set to 0 as that 0102 // is our start pos 0103 std::reverse(colPos.begin(), colPos.end() - 1); 0104 colPos.back() = 0; 0105 0106 for (int i = 0; i < movements; ++i) { 0107 view->wordLeft(); 0108 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, colPos.at(i))); 0109 } 0110 0111 QCOMPARE(view->cursorPosition(), KTextEditor::Cursor(0, 0)); 0112 doc->setHighlightingMode(QString()); 0113 } 0114 0115 void CamelCursorTest::testRtlWordMovement() 0116 { 0117 doc->setText(QStringLiteral("اردو کا جملہ")); 0118 view->setCursorPosition({0, 0}); 0119 0120 // for RTL we move left 0121 auto pos = QList<int>{5, 8, 12}; 0122 for (int i = 0; i < 3; ++i) { 0123 view->wordLeft(); 0124 QCOMPARE(view->cursorPosition().column(), pos.at(i)); 0125 } 0126 0127 // now reverse to original pos 0128 pos = QList<int>{8, 5, 0}; 0129 for (int i = 0; i < 3; ++i) { 0130 view->wordRight(); 0131 QCOMPARE(view->cursorPosition().column(), pos.at(i)); 0132 } 0133 } 0134 0135 void CamelCursorTest::testWordMovementMultipleRow_data() 0136 { 0137 QTest::addColumn<QString>("text"); 0138 QTest::addColumn<int>("movements"); 0139 QTest::addColumn<QList<KTextEditor::Cursor>>("expect_cursor"); 0140 0141 using C = KTextEditor::Cursor; 0142 QTest::addRow("2 lines") << QStringLiteral("KateView\nnextLine") << 4 << QList<C>{C(0, 4), C(0, 8), C(1, 0), C(1, 4)}; 0143 QTest::addRow("2 line caps") << QStringLiteral("Kate_VIEW\nNextLINE") << 4 << QList<C>{C(0, 5), C(0, 9), C(1, 0), C(1, 4)}; 0144 QTest::addRow("4 lines") << QStringLiteral("Kate\nView\nNext\nLINE") << 7 << QList<C>{C(0, 4), C(1, 0), C(1, 4), C(2, 0), C(2, 4), C(3, 0), C(3, 4)}; 0145 } 0146 0147 void CamelCursorTest::testWordMovementMultipleRow() 0148 { 0149 QFETCH(QString, text); 0150 QFETCH(int, movements); 0151 QFETCH(QList<KTextEditor::Cursor>, expect_cursor); 0152 0153 doc->setText(text); 0154 view->setCursorPosition({0, 0}); 0155 0156 for (int i = 0; i < movements; ++i) { 0157 view->wordRight(); 0158 QCOMPARE(view->cursorPosition(), expect_cursor.at(i)); 0159 } 0160 0161 std::reverse(expect_cursor.begin(), expect_cursor.end() - 1); 0162 expect_cursor.back() = KTextEditor::Cursor(0, 0); 0163 0164 for (int i = 0; i < movements; ++i) { 0165 view->wordLeft(); 0166 QCOMPARE(view->cursorPosition(), expect_cursor.at(i)); 0167 } 0168 } 0169 0170 void CamelCursorTest::testDeletionRight() 0171 { 0172 doc->setText(QStringLiteral("SomeWord")); 0173 view->setCursorPosition({0, 0}); 0174 0175 view->deleteWordRight(); 0176 QCOMPARE(doc->text(), QStringLiteral("Word")); 0177 view->deleteWordRight(); 0178 QCOMPARE(doc->text(), QString()); 0179 0180 doc->setText(QStringLiteral("Some Word")); 0181 view->setCursorPosition({0, 0}); 0182 0183 view->deleteWordRight(); 0184 QCOMPARE(doc->text(), QStringLiteral("Word")); 0185 view->deleteWordRight(); 0186 QCOMPARE(doc->text(), QString()); 0187 0188 doc->setText(QStringLiteral("Some_WORD")); 0189 view->setCursorPosition({0, 0}); 0190 0191 view->deleteWordRight(); 0192 QCOMPARE(doc->text(), QStringLiteral("WORD")); 0193 view->deleteWordRight(); 0194 QCOMPARE(doc->text(), QString()); 0195 0196 doc->setText(QStringLiteral("Some WORD")); 0197 view->setCursorPosition({0, 0}); 0198 0199 view->deleteWordRight(); 0200 QCOMPARE(doc->text(), QStringLiteral("WORD")); 0201 view->deleteWordRight(); 0202 QCOMPARE(doc->text(), QString()); 0203 } 0204 0205 void CamelCursorTest::testDeletionLeft() 0206 { 0207 doc->setText(QStringLiteral("SomeWord")); 0208 view->setCursorPosition({0, 8}); 0209 view->deleteWordLeft(); 0210 QCOMPARE(doc->text(), QStringLiteral("Some")); 0211 view->deleteWordLeft(); 0212 QCOMPARE(doc->text(), QString()); 0213 0214 doc->setText(QStringLiteral("Some Word")); 0215 view->setCursorPosition({0, 9}); 0216 view->deleteWordLeft(); 0217 QCOMPARE(doc->text(), QStringLiteral("Some ")); 0218 view->deleteWordLeft(); 0219 QCOMPARE(doc->text(), QString()); 0220 0221 doc->setText(QStringLiteral("Some_WORD")); 0222 view->setCursorPosition({0, 9}); 0223 view->deleteWordLeft(); 0224 QCOMPARE(doc->text(), QStringLiteral("Some_")); 0225 view->deleteWordLeft(); 0226 QCOMPARE(doc->text(), QString()); 0227 0228 doc->setText(QStringLiteral("Some WORD")); 0229 view->setCursorPosition({0, 11}); 0230 view->deleteWordLeft(); 0231 QCOMPARE(doc->text(), QStringLiteral("Some ")); 0232 view->deleteWordLeft(); 0233 QCOMPARE(doc->text(), QString()); 0234 } 0235 0236 void CamelCursorTest::testSelectionRight() 0237 { 0238 doc->setText(QStringLiteral("HelloWorld")); 0239 view->setCursorPosition({0, 0}); 0240 view->shiftWordRight(); 0241 QCOMPARE(view->selectionText(), QStringLiteral("Hello")); 0242 QCOMPARE(view->selectionRange(), KTextEditor::Range(0, 0, 0, 5)); 0243 0244 doc->setText(QStringLiteral("Hello\nWorld")); 0245 view->setCursorPosition({0, 0}); 0246 view->shiftWordRight(); 0247 view->shiftWordRight(); 0248 QCOMPARE(view->selectionText(), QStringLiteral("Hello\n")); 0249 QCOMPARE(view->selectionRange(), KTextEditor::Range(0, 0, 1, 0)); 0250 } 0251 0252 void CamelCursorTest::testSelectionLeft() 0253 { 0254 doc->setText(QStringLiteral("HelloWorld")); 0255 view->setCursorPosition({0, 10}); 0256 view->shiftWordLeft(); 0257 QCOMPARE(view->selectionText(), QStringLiteral("World")); 0258 QCOMPARE(view->selectionRange(), KTextEditor::Range(0, 5, 0, 10)); 0259 0260 doc->setText(QStringLiteral("Hello\nWorld")); 0261 view->setCursorPosition({1, 0}); 0262 view->shiftWordLeft(); 0263 view->shiftWordLeft(); 0264 QCOMPARE(view->selectionText(), QStringLiteral("Hello\n")); 0265 QCOMPARE(view->selectionRange(), KTextEditor::Range(0, 0, 1, 0)); 0266 } 0267 0268 #include "moc_camelcursortest.cpp"