File indexing completed on 2024-05-05 04:35:29
0001 /* 0002 * This file is part of KDevelop Krazy2 Plugin. 0003 * 0004 * Copyright 2012 Daniel Calviño Sánchez <danxuliu@gmail.com> 0005 * 0006 * This program is free software; you can redistribute it and/or 0007 * modify it under the terms of the GNU General Public License 0008 * as published by the Free Software Foundation; either version 2 0009 * of the License, or (at your option) any later version. 0010 * 0011 * This program is distributed in the hope that it will be useful, 0012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0014 * GNU General Public License for more details. 0015 * 0016 * You should have received a copy of the GNU General Public License 0017 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0018 */ 0019 0020 #include <QTest> 0021 0022 #include <QListView> 0023 #include <QFileDialog> 0024 #include <QDialogButtonBox> 0025 #include <QPushButton> 0026 #include <QFileSystemModel> 0027 #include <QLineEdit> 0028 0029 #include <QTimer> 0030 0031 #include "../settings/selectpathswidget.h" 0032 0033 class SelectPathsWidgetTest: public QObject { 0034 Q_OBJECT 0035 private slots: 0036 0037 void initTestCase(); 0038 void init(); 0039 0040 void testConstructor(); 0041 void testConstructorWithPathsDuplicatedAndNotSorted(); 0042 void testConstructorWithInvalidPaths(); 0043 0044 void testAddFile(); 0045 void testAddFiles(); 0046 void testAddDuplicatedAndNotSortedFiles(); 0047 void testRemoveButtonDisabledWhenFileAdded(); 0048 0049 void testRemove(); 0050 void testRemoveSeveralPaths(); 0051 0052 void testSelectAndDeselect(); 0053 0054 private: 0055 0056 bool examplesInSubdirectory() const; 0057 0058 QPushButton* addButton(const SelectPathsWidget* widget) const; 0059 QPushButton* removeButton(const SelectPathsWidget* widget) const; 0060 QListView* pathsView(const SelectPathsWidget* widget) const; 0061 0062 void assertPaths(const SelectPathsWidget* widget, const QStringList& paths) const; 0063 0064 void queueSelectPaths(const SelectPathsWidget* widget, 0065 const QString& directory, 0066 const QStringList& paths); 0067 0068 QString m_examplesPath; 0069 }; 0070 0071 void SelectPathsWidgetTest::initTestCase() 0072 { 0073 m_examplesPath = QStringLiteral(EXAMPLETESTDATA_PATH); 0074 } 0075 0076 void SelectPathsWidgetTest::init() { 0077 if (!examplesInSubdirectory()) { 0078 QString message = "The examples were not found in the 'examples' directory (" + m_examplesPath + ')'; 0079 QSKIP(message.toLatin1(), SkipAll); 0080 } 0081 } 0082 0083 void SelectPathsWidgetTest::testConstructor() { 0084 QWidget parent; 0085 QStringList paths; 0086 paths << m_examplesPath + "severalIssuesSeveralCheckers.cpp"; 0087 paths << m_examplesPath + "singleIssue.cpp"; 0088 paths << m_examplesPath + "subdirectory"; 0089 auto widget = new SelectPathsWidget(paths, &parent); 0090 0091 QCOMPARE(widget->parent(), &parent); 0092 0093 assertPaths(widget, QStringList() << m_examplesPath + "severalIssuesSeveralCheckers.cpp" 0094 << m_examplesPath + "singleIssue.cpp" 0095 << m_examplesPath + "subdirectory/"); 0096 0097 QCOMPARE(pathsView(widget)->editTriggers(), QAbstractItemView::NoEditTriggers); 0098 } 0099 0100 void SelectPathsWidgetTest::testConstructorWithPathsDuplicatedAndNotSorted() { 0101 QWidget parent; 0102 QStringList paths; 0103 paths << m_examplesPath + "singleIssue.cpp"; 0104 paths << m_examplesPath + "subdirectory"; 0105 paths << m_examplesPath + "subdirectory/"; 0106 paths << m_examplesPath + "severalIssuesSeveralCheckers.cpp"; 0107 paths << m_examplesPath + "singleIssue.cpp"; 0108 auto widget = new SelectPathsWidget(paths, &parent); 0109 0110 QCOMPARE(widget->parent(), &parent); 0111 0112 assertPaths(widget, QStringList() << m_examplesPath + "severalIssuesSeveralCheckers.cpp" 0113 << m_examplesPath + "singleIssue.cpp" 0114 << m_examplesPath + "subdirectory/"); 0115 } 0116 0117 void SelectPathsWidgetTest::testConstructorWithInvalidPaths() { 0118 QWidget parent; 0119 QStringList paths; 0120 paths << m_examplesPath + "severalIssuesSeveralCheckers.cpp"; 0121 paths << m_examplesPath + "singleIssue.cpp"; 0122 paths << "examples/severalIssuesSingleChecker.cpp"; 0123 paths << m_examplesPath + "subdirectory"; 0124 paths << m_examplesPath + "fileThatDoesNotExist.cpp"; 0125 auto widget = new SelectPathsWidget(paths, &parent); 0126 0127 QCOMPARE(widget->parent(), &parent); 0128 0129 assertPaths(widget, QStringList() << m_examplesPath + "severalIssuesSeveralCheckers.cpp" 0130 << m_examplesPath + "singleIssue.cpp" 0131 << m_examplesPath + "subdirectory/"); 0132 } 0133 0134 void SelectPathsWidgetTest::testAddFile() { 0135 QStringList paths; 0136 SelectPathsWidget widget(paths); 0137 0138 queueSelectPaths(&widget, m_examplesPath, 0139 QStringList() << "singleIssue.cpp"); 0140 addButton(&widget)->click(); 0141 0142 assertPaths(&widget, QStringList() << m_examplesPath + "singleIssue.cpp"); 0143 } 0144 0145 void SelectPathsWidgetTest::testAddFiles() { 0146 QStringList paths; 0147 SelectPathsWidget widget(paths); 0148 0149 queueSelectPaths(&widget, m_examplesPath, 0150 QStringList() << "singleExtraIssue.cpp" 0151 << QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp")); 0152 addButton(&widget)->click(); 0153 0154 assertPaths(&widget, QStringList() << m_examplesPath + "singleExtraIssue.cpp" 0155 << m_examplesPath + QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp")); 0156 } 0157 0158 void SelectPathsWidgetTest::testAddDuplicatedAndNotSortedFiles() { 0159 QStringList paths; 0160 paths << m_examplesPath + "singleExtraIssue.cpp"; 0161 SelectPathsWidget widget(paths); 0162 0163 queueSelectPaths(&widget, m_examplesPath, 0164 QStringList() << "singleExtraIssue.cpp" 0165 << QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp") 0166 << QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp") 0167 << QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp")); 0168 addButton(&widget)->click(); 0169 0170 assertPaths(&widget, QStringList() << m_examplesPath + "singleExtraIssue.cpp" 0171 << m_examplesPath + QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp")); 0172 } 0173 0174 void SelectPathsWidgetTest::testRemoveButtonDisabledWhenFileAdded() { 0175 QStringList paths; 0176 paths << m_examplesPath + "singleIssue.cpp"; 0177 SelectPathsWidget widget(paths); 0178 0179 QVERIFY(!removeButton(&widget)->isEnabled()); 0180 0181 QModelIndex index = pathsView(&widget)->model()->index(0, 0); 0182 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::SelectCurrent); 0183 0184 QVERIFY(removeButton(&widget)->isEnabled()); 0185 0186 queueSelectPaths(&widget, m_examplesPath, 0187 QStringList() << "singleExtraIssue.cpp"); 0188 addButton(&widget)->click(); 0189 0190 QVERIFY(pathsView(&widget)->selectionModel()->selectedIndexes().isEmpty()); 0191 QVERIFY(!removeButton(&widget)->isEnabled()); 0192 } 0193 0194 void SelectPathsWidgetTest::testRemove() { 0195 QStringList paths; 0196 paths << m_examplesPath + "severalIssuesSeveralCheckers.cpp"; 0197 paths << m_examplesPath + "singleIssue.cpp"; 0198 SelectPathsWidget widget(paths); 0199 0200 QVERIFY(!removeButton(&widget)->isEnabled()); 0201 0202 QModelIndex index = pathsView(&widget)->model()->index(1, 0); 0203 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::SelectCurrent); 0204 0205 QVERIFY(removeButton(&widget)->isEnabled()); 0206 0207 removeButton(&widget)->click(); 0208 0209 assertPaths(&widget, QStringList() << m_examplesPath + "severalIssuesSeveralCheckers.cpp"); 0210 0211 QVERIFY(!removeButton(&widget)->isEnabled()); 0212 } 0213 0214 void SelectPathsWidgetTest::testRemoveSeveralPaths() { 0215 QStringList paths; 0216 paths << m_examplesPath + "severalIssuesSeveralCheckers.cpp"; 0217 paths << m_examplesPath + "singleExtraIssue.cpp"; 0218 paths << m_examplesPath + "singleIssue.cpp"; 0219 0220 SelectPathsWidget widget(paths); 0221 0222 QVERIFY(!removeButton(&widget)->isEnabled()); 0223 0224 QModelIndex index = pathsView(&widget)->model()->index(0, 0); 0225 QVERIFY(index.isValid()); 0226 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::Select); 0227 0228 QVERIFY(removeButton(&widget)->isEnabled()); 0229 0230 index = pathsView(&widget)->model()->index(2, 0); 0231 QVERIFY(index.isValid()); 0232 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::Select); 0233 0234 QVERIFY(removeButton(&widget)->isEnabled()); 0235 0236 removeButton(&widget)->click(); 0237 0238 assertPaths(&widget, QStringList() << m_examplesPath + "singleExtraIssue.cpp"); 0239 0240 QVERIFY(!removeButton(&widget)->isEnabled()); 0241 } 0242 0243 void SelectPathsWidgetTest::testSelectAndDeselect() { 0244 QStringList paths; 0245 paths << m_examplesPath + "severalIssuesSeveralCheckers.cpp"; 0246 paths << m_examplesPath + "singleIssue.cpp"; 0247 paths << m_examplesPath + "singleExtraIssue.cpp"; 0248 SelectPathsWidget widget(paths); 0249 0250 QModelIndex index = pathsView(&widget)->model()->index(0, 0); 0251 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::Select); 0252 0253 QVERIFY(removeButton(&widget)->isEnabled()); 0254 0255 index = pathsView(&widget)->model()->index(2, 0); 0256 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::Select); 0257 0258 QVERIFY(removeButton(&widget)->isEnabled()); 0259 0260 index = pathsView(&widget)->model()->index(0, 0); 0261 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::Deselect); 0262 0263 QVERIFY(removeButton(&widget)->isEnabled()); 0264 0265 index = pathsView(&widget)->model()->index(2, 0); 0266 pathsView(&widget)->selectionModel()->select(index, QItemSelectionModel::Deselect); 0267 0268 QVERIFY(!removeButton(&widget)->isEnabled()); 0269 } 0270 0271 ///////////////////////////////// Helpers ////////////////////////////////////// 0272 0273 bool SelectPathsWidgetTest::examplesInSubdirectory() const { 0274 if (QFile(m_examplesPath + "singleIssue.cpp").exists() && 0275 QFile(m_examplesPath + "singleExtraIssue.cpp").exists() && 0276 QFile(m_examplesPath + QString::fromUtf8("singleIssueNonAsciiFileNameḶḷambión.cpp")).exists() && 0277 QFile(m_examplesPath + ".singleIssueHiddenUnixFileName.cpp").exists() && 0278 QFile(m_examplesPath + "severalIssuesSingleChecker.cpp").exists() && 0279 QFile(m_examplesPath + "severalIssuesSeveralCheckers.cpp").exists() && 0280 QFile(m_examplesPath + "severalIssuesSeveralCheckersUnknownFileType.dqq").exists() && 0281 QFile(m_examplesPath + "subdirectory/singleIssue.desktop").exists() && 0282 QFile(m_examplesPath + "subdirectory/severalIssuesSeveralCheckers.qml").exists()) { 0283 return true; 0284 } 0285 0286 return false; 0287 } 0288 0289 QPushButton* SelectPathsWidgetTest::addButton(const SelectPathsWidget* widget) const { 0290 return widget->findChild<QPushButton*>("addButton"); 0291 } 0292 0293 QPushButton* SelectPathsWidgetTest::removeButton(const SelectPathsWidget* widget) const { 0294 return widget->findChild<QPushButton*>("removeButton"); 0295 } 0296 0297 QListView* SelectPathsWidgetTest::pathsView(const SelectPathsWidget* widget) const { 0298 return widget->findChild<QListView*>("pathsView"); 0299 } 0300 0301 void SelectPathsWidgetTest::assertPaths(const SelectPathsWidget* widget, 0302 const QStringList& paths) const { 0303 QCOMPARE(widget->selectedFilesAndDirectories().count(), paths.count()); 0304 for (int i=0; i<paths.count(); ++i) { 0305 QCOMPARE(widget->selectedFilesAndDirectories()[i], paths[i]); 0306 } 0307 0308 QCOMPARE(pathsView(widget)->model()->rowCount(), paths.count()); 0309 for (int i=0; i<paths.count(); ++i) { 0310 QModelIndex index = pathsView(widget)->model()->index(i, 0); 0311 QCOMPARE(pathsView(widget)->model()->data(index).toString(), paths[i]); 0312 } 0313 } 0314 0315 //The file dialog is modal, so it won't return to the test code until it is 0316 //closed. Thus, the actions to be performed while the file dialog is being shown 0317 //(like accepting the file dialog itself) must be "queued". 0318 //Instead of queueing them to be performed after some fixed amount of time, 0319 //it is checked if the action can be performed and, if not, the action is 0320 //retried again after a little amount of time. 0321 class QueuedSelectPathsAction: public QObject { 0322 Q_OBJECT 0323 public: 0324 0325 const SelectPathsWidget* m_widget; 0326 QString m_directory; 0327 QStringList m_paths; 0328 0329 QueuedSelectPathsAction(QObject* parent): QObject(parent) { 0330 } 0331 0332 public Q_SLOTS: 0333 0334 void selectPaths() { 0335 QFileDialog* fileDialog = m_widget->findChild<QFileDialog*>(); 0336 if (!fileDialog || !fileDialog->isVisible()) { 0337 QTimer::singleShot(100, this, SLOT(selectPaths())); 0338 return; 0339 } 0340 0341 fileDialog->setDirectory(m_directory); 0342 0343 QListView *lv = fileDialog->findChild<QListView*>("listView"); 0344 QVERIFY(lv != nullptr); 0345 0346 QFileSystemModel *model = dynamic_cast<QFileSystemModel*>(lv->model()); 0347 QVERIFY(model != nullptr); 0348 0349 QLineEdit *lineEdit = fileDialog->findChild<QLineEdit*>("fileNameEdit"); 0350 QVERIFY(lineEdit != nullptr); 0351 0352 foreach (const QString& path, m_paths) { 0353 QModelIndex idx = model->index(m_directory + QStringLiteral("/") + path); 0354 if (!idx.isValid()) 0355 continue; 0356 lv->selectionModel()->select(idx, QItemSelectionModel::Select); 0357 } 0358 0359 QString line; 0360 foreach (const QString& path, m_paths) { 0361 line += '"'; 0362 line += path; 0363 line += '"'; 0364 line += ' '; 0365 } 0366 line.resize(line.size() - 1); 0367 lineEdit->setText(line); 0368 0369 QDialogButtonBox *box = fileDialog->findChild<QDialogButtonBox*>(); 0370 QVERIFY(box != nullptr); 0371 QPushButton *button = box->button(QDialogButtonBox::Open); 0372 QVERIFY(button != nullptr); 0373 QVERIFY(button->isEnabled()); 0374 button->click(); 0375 } 0376 0377 }; 0378 0379 void SelectPathsWidgetTest::queueSelectPaths(const SelectPathsWidget* widget, 0380 const QString& directory, 0381 const QStringList& paths) { 0382 auto helper = new QueuedSelectPathsAction(this); 0383 helper->m_widget = widget; 0384 helper->m_directory = directory; 0385 helper->m_paths = paths; 0386 helper->selectPaths(); 0387 } 0388 0389 QTEST_MAIN(SelectPathsWidgetTest) 0390 0391 #include "selectpathswidgettest.moc"