]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/tests/dolphindetailsviewtest.cpp
Improve stability of unit tests when running them with Valgrind
[dolphin.git] / src / tests / dolphindetailsviewtest.cpp
index 0ca19bdddce76b67e42af92973936ec4b40acf87..31b4a57cdde64e630b0decad2e1de0b1b6f5cf3e 100644 (file)
 #include <qtest_kde.h>
 
 #include "testbase.h"
+#include "testdir.h"
 
 #include "views/dolphindetailsview.h"
 #include "views/dolphinview.h"
 #include "views/dolphinmodel.h"
-#include "views/dolphindirlister.h"
 #include "views/dolphinsortfilterproxymodel.h"
 #include "views/zoomlevelinfo.h"
 
-#include <KTempDir>
-
-#include <QtCore/QDir>
 #include <qtestmouse.h>
 #include <qtestkeyboard.h>
 
@@ -44,18 +41,48 @@ private slots:
 
     void bug217447_shiftArrowSelection();
     void bug234600_overlappingIconsWhenZooming();
+    void bug257401_longFilenamesKeyboardNavigation();
 
 private:
 
-    QModelIndex proxyModelIndexForUrl(const KUrl& url) const {
-        const QModelIndex index = m_dolphinModel->indexForUrl(url);
-        return m_proxyModel->mapFromSource(index);
+    /**
+     * initView(DolphinView*) sets the correct view mode, shows the view on the screen, and waits
+     * until loading the folder in the view is finished.
+     *
+     * Many unit tests need access to the internal DolphinDetailsView in DolphinView.
+     * Therefore, a pointer to the details view is returned by initView(DolphinView*).
+     */
+    DolphinDetailsView* initView(DolphinView* view) const {
+        QSignalSpy spyFinishedPathLoading(view, SIGNAL(finishedPathLoading(const KUrl&)));
+        view->setMode(DolphinView::DetailsView);
+        DolphinDetailsView* detailsView = qobject_cast<DolphinDetailsView*>(itemView(view));
+        Q_ASSERT(detailsView);
+        detailsView->setFoldersExpandable(true);
+        view->resize(400, 400);
+        view->show();
+        QTest::qWaitForWindowShown(view);
+
+        // If the DolphinView's finishedPathLoading(const KUrl&) signal has not been received yet,
+        // we have to wait a bit more.
+        // The reason why the if-statement is needed here is that the signal might have been emitted
+        // while we were waiting in QTest::qWaitForWindowShown(view)
+        // -> waitForFinishedPathLoading(view) would fail in that case.
+        if (spyFinishedPathLoading.isEmpty()) {
+            waitForFinishedPathLoading(view);
+        }
+
+        return detailsView;
+    }
+
+    QModelIndex proxyModelIndexForUrl(const DolphinView* view, const KUrl& url) const {
+        const QModelIndex index = view->m_viewAccessor.m_dolphinModel->indexForUrl(url);
+        return view->m_viewAccessor.m_proxyModel->mapFromSource(index);
     }
 };
 
 /**
  * This test verifies that DolphinDetailsView::expandedUrls() returns the right set of URLs.
- * The test creates a folder hierarchy: 3 folders (a, b, c) contain 3 subfolders (also names a, b, c) each.
+ * The test creates a folder hierarchy: 3 folders (a, b, c) contain 3 subfolders (also named a, b, c) each.
  * Each of those contains 3 further subfolders of the same name.
  */
 
@@ -73,42 +100,28 @@ void DolphinDetailsViewTest::testExpandedUrls()
         }
     }
 
-    createFiles(files);
-
-    m_view->setMode(DolphinView::DetailsView);
-    DolphinDetailsView* detailsView = qobject_cast<DolphinDetailsView*>(itemView());
-    QVERIFY(detailsView);
-    detailsView->setFoldersExpandable(true);
-    m_view->resize(400, 400);
-    m_view->show();
-    QTest::qWaitForWindowShown(m_view);
-    reloadViewAndWait();
+    TestDir dir;
+    dir.createFiles(files);
+    DolphinView view(dir.url(), 0);
+    DolphinDetailsView* detailsView = initView(&view);
 
     // We start with an empty set of expanded URLs.
     QSet<KUrl> expectedExpandedUrls;
     QCOMPARE(detailsView->expandedUrls(), expectedExpandedUrls);
 
-    // Every time we expand a folder, we have to wait until the view has finished loading
-    // its contents before we can expand further subfolders. We keep track of the reloading
-    // using a signal spy.
-    QSignalSpy spyFinishedPathLoading(m_view, SIGNAL(finishedPathLoading(const KUrl&)));
-
     // Expand URLs one by one and verify the result of DolphinDetailsView::expandedUrls()
     QStringList itemsToExpand;
     itemsToExpand << "b" << "b/a" << "b/a/c" << "b/c" << "c";
 
     foreach(const QString& item, itemsToExpand) {
-        KUrl url(m_path + item);
-        detailsView->expand(proxyModelIndexForUrl(url));
+        KUrl url(dir.name() + item);
+        detailsView->expand(proxyModelIndexForUrl(&view, url));
         expectedExpandedUrls += url;
         QCOMPARE(detailsView->expandedUrls(), expectedExpandedUrls);
 
         // Before we proceed, we have to make sure that the view has finished
         // loading the contents of the expanded folder.
-        while (spyFinishedPathLoading.isEmpty()) {
-            QTest::qWait(10);
-        }
-        spyFinishedPathLoading.takeFirst();
+        waitForFinishedPathLoading(&view);
     }
 
     // Collapse URLs one by one and verify the result of DolphinDetailsView::expandedUrls()
@@ -116,14 +129,11 @@ void DolphinDetailsViewTest::testExpandedUrls()
     itemsToCollapse << "b/c" << "b/a/c" << "c" << "b/a" << "b";
 
     foreach(const QString& item, itemsToCollapse) {
-        KUrl url(m_path + item);
-        detailsView->collapse(proxyModelIndexForUrl(url));
+        KUrl url(dir.name() + item);
+        detailsView->collapse(proxyModelIndexForUrl(&view, url));
         expectedExpandedUrls -= url;
         QCOMPARE(detailsView->expandedUrls(), expectedExpandedUrls);
     }
-
-    m_view->hide();
-    cleanupTestDir();
 }
 
 /**
@@ -148,17 +158,12 @@ void DolphinDetailsViewTest::testExpandedUrls()
 
 void DolphinDetailsViewTest::bug217447_shiftArrowSelection()
 {
+    TestDir dir;
     for (int i = 0; i < 100; i++) {
-        createFile(QString("%1").arg(i));
+        dir.createFile(QString("%1").arg(i));
     }
-
-    m_view->setMode(DolphinView::DetailsView);
-    DolphinDetailsView* detailsView = qobject_cast<DolphinDetailsView*>(itemView());
-    QVERIFY(detailsView);
-    m_view->resize(1000, 400);
-    m_view->show();
-    QTest::qWaitForWindowShown(m_view);
-    reloadViewAndWait();
+    DolphinView view(dir.url(), 0);
+    DolphinDetailsView* detailsView = initView(&view);
 
     // Select the first item
     QModelIndex index0 = detailsView->model()->index(0, 0);
@@ -202,9 +207,6 @@ void DolphinDetailsViewTest::bug217447_shiftArrowSelection()
 
         current++;
     }
-
-    m_view->hide();
-    cleanupTestDir();
 }
 
 /**
@@ -220,15 +222,11 @@ void DolphinDetailsViewTest::bug234600_overlappingIconsWhenZooming()
 {
     QStringList files;
     files << "a" << "b" << "c" << "d";
-    createFiles(files);
 
-    m_view->setMode(DolphinView::DetailsView);
-    DolphinDetailsView* detailsView = qobject_cast<DolphinDetailsView*>(itemView());
-    QVERIFY(detailsView);
-    m_view->resize(400, 400);
-    m_view->show();
-    QTest::qWaitForWindowShown(m_view);
-    reloadViewAndWait();
+    TestDir dir;
+    dir.createFiles(files);
+    DolphinView view(dir.url(), 0);
+    DolphinDetailsView* detailsView = initView(&view);
 
     QModelIndex index0 = detailsView->model()->index(0, 0);
     detailsView->setCurrentIndex(index0);
@@ -236,8 +234,9 @@ void DolphinDetailsViewTest::bug234600_overlappingIconsWhenZooming()
 
     // Setting the zoom level to the minimum value and triggering DolphinDetailsView::currentChanged(...)
     // should make sure that the bug is triggered.
+    int zoomLevelBackup = view.zoomLevel();
     int zoomLevel = ZoomLevelInfo::minimumLevel();
-    m_view->setZoomLevel(zoomLevel);
+    view.setZoomLevel(zoomLevel);
 
     QModelIndex index1 = detailsView->model()->index(1, 0);
     detailsView->setCurrentIndex(index1);
@@ -246,16 +245,60 @@ void DolphinDetailsViewTest::bug234600_overlappingIconsWhenZooming()
     // Increase the zoom level successively to the maximum.
     while(zoomLevel < ZoomLevelInfo::maximumLevel()) {
         zoomLevel++;
-        m_view->setZoomLevel(zoomLevel);
+        view.setZoomLevel(zoomLevel);
+        QCOMPARE(view.zoomLevel(), zoomLevel);
 
         //Check for each zoom level that the height of each item is at least the icon size.
         QVERIFY(detailsView->visualRect(index1).height() >= ZoomLevelInfo::iconSizeForZoomLevel(zoomLevel));
     }
 
-    m_view->hide();
-    cleanupTestDir();
+    view.setZoomLevel(zoomLevelBackup);
+}
+
+/**
+ * The width of the visualRect of an item is usually replaced by the width of the file name.
+ * However, if the file name is wider then the view's name column, this leads to problems with
+ * keyboard navigation if files with very long names are present in the current folder, see
+ *
+ * https://bugs.kde.org/show_bug.cgi?id=257401
+ *
+ * This test checks that the visualRect of an item is never wider than the "Name" column.
+ */
+
+void DolphinDetailsViewTest::bug257401_longFilenamesKeyboardNavigation() {
+    TestDir dir;
+    QString name;
+    for (int i = 0; i < 20; i++) {
+        name += "mmmmmmmmmm";
+        dir.createFile(name);
+    }
+    DolphinView view(dir.url(), 0);
+    DolphinDetailsView* detailsView = initView(&view);
+
+    // Select the first item
+    QModelIndex index0 = detailsView->model()->index(0, 0);
+    detailsView->setCurrentIndex(index0);
+    QCOMPARE(detailsView->currentIndex(), index0);
+    QVERIFY(detailsView->visualRect(index0).width() < detailsView->columnWidth(DolphinModel::Name));
+
+    QItemSelectionModel* selectionModel = detailsView->selectionModel();
+    QModelIndexList selectedIndexes = selectionModel->selectedIndexes();
+    QCOMPARE(selectedIndexes.count(), 1);
+    QVERIFY(selectedIndexes.contains(index0));
+
+    // Move down successively using the "Down" key and check that current item
+    // and selection are as expected.
+    for (int i = 0; i < 19; i++) {
+        QTest::keyClick(detailsView->viewport(), Qt::Key_Down, Qt::NoModifier);
+        QModelIndex currentIndex = detailsView->model()->index(i + 1, 0);
+        QCOMPARE(detailsView->currentIndex(), currentIndex);
+        QVERIFY(detailsView->visualRect(currentIndex).width() <= detailsView->columnWidth(DolphinModel::Name));
+        selectedIndexes = selectionModel->selectedIndexes();
+        QCOMPARE(selectedIndexes.count(), 1);
+        QVERIFY(selectedIndexes.contains(currentIndex));
+    }
 }
 
 QTEST_KDEMAIN(DolphinDetailsViewTest, GUI)
 
-#include "dolphindetailsviewtest.moc"
\ No newline at end of file
+#include "dolphindetailsviewtest.moc"