]> 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 20d5daebdb9505a34b979e4d6f11090171cdce6e..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>
 
@@ -40,11 +37,105 @@ class DolphinDetailsViewTest : public TestBase
 
 private slots:
 
+    void testExpandedUrls();
+
     void bug217447_shiftArrowSelection();
     void bug234600_overlappingIconsWhenZooming();
+    void bug257401_longFilenamesKeyboardNavigation();
+
+private:
+
+    /**
+     * 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 named a, b, c) each.
+ * Each of those contains 3 further subfolders of the same name.
+ */
+
+void DolphinDetailsViewTest::testExpandedUrls()
+{
+    QStringList files;
+    QStringList subFolderNames;
+    subFolderNames << "a" << "b" << "c";
+
+    foreach(const QString& level1, subFolderNames) {
+        foreach(const QString& level2, subFolderNames) {
+            foreach(const QString& level3, subFolderNames) {
+                files << level1 + "/" + level2 + "/" + level3 + "/testfile";
+            }
+        }
+    }
+
+    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);
+
+    // 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(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.
+        waitForFinishedPathLoading(&view);
+    }
+
+    // Collapse URLs one by one and verify the result of DolphinDetailsView::expandedUrls()
+    QStringList itemsToCollapse;
+    itemsToCollapse << "b/c" << "b/a/c" << "c" << "b/a" << "b";
+
+    foreach(const QString& item, itemsToCollapse) {
+        KUrl url(dir.name() + item);
+        detailsView->collapse(proxyModelIndexForUrl(&view, url));
+        expectedExpandedUrls -= url;
+        QCOMPARE(detailsView->expandedUrls(), expectedExpandedUrls);
+    }
+}
+
 /**
  * When the first item in the view is active and Shift is held while the "arrow down"
  * key is pressed repeatedly, the selection should grow by one item for each key press.
@@ -67,17 +158,12 @@ private slots:
 
 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);
@@ -121,9 +207,6 @@ void DolphinDetailsViewTest::bug217447_shiftArrowSelection()
 
         current++;
     }
-
-    m_view->hide();
-    cleanupTestDir();
 }
 
 /**
@@ -139,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);
@@ -155,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);
@@ -165,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"