]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/tests/kfileitemmodeltest.cpp
make use of initializer lists
[dolphin.git] / src / tests / kfileitemmodeltest.cpp
index 9079e584ecb9b562ce932afa1c75d66b1facb637..d224e1a2e2ad0c07a5e44374d001d8e43ec976de 100644 (file)
@@ -20,7 +20,6 @@
 
 #include <qtest_kde.h>
 
-#include <KDirLister>
 #include <kio/job.h>
 
 #include "kitemviews/kfileitemmodel.h"
@@ -93,6 +92,9 @@ private slots:
     void testChangeRolesForFilteredItems();
     void testChangeSortRoleWhileFiltering();
     void testRefreshFilteredItems();
+    void testCollapseFolderWhileLoading();
+    void testCreateMimeData();
+    void testDeleteFileMoreThanOnce();
 
 private:
     QStringList itemsInModel() const;
@@ -197,7 +199,7 @@ void KFileItemModelTest::testDirLoadingCompleted()
     QSignalSpy itemsInsertedSpy(m_model, SIGNAL(itemsInserted(KItemRangeList)));
     QSignalSpy itemsRemovedSpy(m_model, SIGNAL(itemsRemoved(KItemRangeList)));
 
-    m_testDir->createFiles(QStringList() << "a.txt" << "b.txt" << "c.txt");
+    m_testDir->createFiles({"a.txt", "b.txt", "c.txt"});
 
     m_model->loadDirectory(m_testDir->url());
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout));
@@ -206,7 +208,7 @@ void KFileItemModelTest::testDirLoadingCompleted()
     QCOMPARE(itemsRemovedSpy.count(), 0);
     QCOMPARE(m_model->count(), 3);
 
-    m_testDir->createFiles(QStringList() << "d.txt" << "e.txt");
+    m_testDir->createFiles({"d.txt", "e.txt"});
     m_model->m_dirLister->updateDirectory(m_testDir->url());
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout));
     QCOMPARE(loadingCompletedSpy.count(), 2);
@@ -402,11 +404,11 @@ void KFileItemModelTest::testResortAfterChangingName()
     // We rename d.txt back to a.txt using the dir lister's refreshItems() signal.
     const KFileItem fileItemD = m_model->fileItem(2);
     KFileItem fileItemA = fileItemD;
-    KUrl urlA = fileItemA.url();
-    urlA.setFileName("a.txt");
+    QUrl urlA = fileItemA.url().adjusted(QUrl::RemoveFilename);
+    urlA.setPath(urlA.path() + "a.txt");
     fileItemA.setUrl(urlA);
 
-    m_model->slotRefreshItems(QList<QPair<KFileItem, KFileItem> >() << qMakePair(fileItemD, fileItemA));
+    m_model->slotRefreshItems({qMakePair(fileItemD, fileItemA)});
 
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsMoved(KItemRange,QList<int>)), DefaultTimeout));
     QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt");
@@ -514,8 +516,10 @@ void KFileItemModelTest::testExpandItems()
     m_testDir->createFiles(files);
 
     // Store the URLs of all folders in a set.
-    QSet<KUrl> allFolders;
-    allFolders << KUrl(m_testDir->name() + 'a') << KUrl(m_testDir->name() + "a/a") << KUrl(m_testDir->name() + "a/a-1");
+    QSet<QUrl> allFolders;
+    allFolders << QUrl::fromLocalFile(m_testDir->name() + 'a')
+               << QUrl::fromLocalFile(m_testDir->name() + "a/a")
+               << QUrl::fromLocalFile(m_testDir->name() + "a/a-1");
 
     m_model->loadDirectory(m_testDir->url());
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
@@ -533,7 +537,7 @@ void KFileItemModelTest::testExpandItems()
     QVERIFY(m_model->isExpanded(0));
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
     QCOMPARE(m_model->count(), 3); // 3 items: "a/", "a/a/", "a/a-1/"
-    QCOMPARE(m_model->expandedDirectories(), QSet<KUrl>() << KUrl(m_testDir->name() + 'a'));
+    QCOMPARE(m_model->expandedDirectories(), QSet<QUrl>() << QUrl::fromLocalFile(m_testDir->name() + 'a'));
 
     QCOMPARE(spyInserted.count(), 1);
     KItemRangeList itemRangeList = spyInserted.takeFirst().at(0).value<KItemRangeList>();
@@ -549,7 +553,7 @@ void KFileItemModelTest::testExpandItems()
     QVERIFY(m_model->isExpanded(1));
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
     QCOMPARE(m_model->count(), 4);  // 4 items: "a/", "a/a/", "a/a/1", "a/a-1/"
-    QCOMPARE(m_model->expandedDirectories(), QSet<KUrl>() << KUrl(m_testDir->name() + 'a') << KUrl(m_testDir->name() + "a/a"));
+    QCOMPARE(m_model->expandedDirectories(), QSet<QUrl>() << QUrl::fromLocalFile(m_testDir->name() + 'a') << QUrl::fromLocalFile(m_testDir->name() + "a/a"));
 
     QCOMPARE(spyInserted.count(), 1);
     itemRangeList = spyInserted.takeFirst().at(0).value<KItemRangeList>();
@@ -578,7 +582,7 @@ void KFileItemModelTest::testExpandItems()
     m_model->setExpanded(0, false);
     QVERIFY(!m_model->isExpanded(0));
     QCOMPARE(m_model->count(), 1);
-    QVERIFY(!m_model->expandedDirectories().contains(KUrl(m_testDir->name() + 'a'))); // TODO: Make sure that child URLs are also removed
+    QVERIFY(!m_model->expandedDirectories().contains(QUrl::fromLocalFile(m_testDir->name() + 'a'))); // TODO: Make sure that child URLs are also removed
 
     QCOMPARE(spyRemoved.count(), 1);
     itemRangeList = spyRemoved.takeFirst().at(0).value<KItemRangeList>();
@@ -604,7 +608,7 @@ void KFileItemModelTest::testExpandItems()
 
     // Move to a sub folder, then call restoreExpandedFolders() *before* going back.
     // This is how DolphinView restores the expanded folders when navigating in history.
-    m_model->loadDirectory(KUrl(m_testDir->name() + "a/a/"));
+    m_model->loadDirectory(QUrl::fromLocalFile(m_testDir->name() + "a/a/"));
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout));
     QCOMPARE(m_model->count(), 1);  // 1 item: "1"
     m_model->restoreExpandedDirectories(allFolders);
@@ -618,7 +622,7 @@ void KFileItemModelTest::testExpandItems()
     m_model->setRoles(originalModelRoles);
     QVERIFY(!m_model->isExpanded(0));
     QCOMPARE(m_model->count(), 1);
-    QVERIFY(!m_model->expandedDirectories().contains(KUrl(m_testDir->name() + 'a')));
+    QVERIFY(!m_model->expandedDirectories().contains(QUrl::fromLocalFile(m_testDir->name() + 'a')));
 
     QCOMPARE(spyRemoved.count(), 1);
     itemRangeList = spyRemoved.takeFirst().at(0).value<KItemRangeList>();
@@ -652,7 +656,7 @@ void KFileItemModelTest::testExpandParentItems()
     QVERIFY(m_model->expandedDirectories().empty());
 
     // Expand the parents of "a2/b2/c2".
-    m_model->expandParentDirectories(KUrl(m_testDir->name() + "a2/b2/c2"));
+    m_model->expandParentDirectories(QUrl::fromLocalFile(m_testDir->name() + "a2/b2/c2"));
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout));
 
     // The model should now contain "a 1/", "a2/", "a2/b2/", and "a2/b2/c2/".
@@ -664,7 +668,7 @@ void KFileItemModelTest::testExpandParentItems()
     QVERIFY(!m_model->isExpanded(3));
 
     // Expand the parents of "a 1/b1".
-    m_model->expandParentDirectories(KUrl(m_testDir->name() + "a 1/b1"));
+    m_model->expandParentDirectories(QUrl::fromLocalFile(m_testDir->name() + "a 1/b1"));
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(directoryLoadingCompleted()), DefaultTimeout));
 
     // The model should now contain "a 1/", "a 1/b1/", "a2/", "a2/b2", and "a2/b2/c2/".
@@ -732,10 +736,10 @@ void KFileItemModelTest::testMakeExpandedItemHidden()
     QCOMPARE(m_model->count(), 6);
 
     // Rename "1a/2" and make it hidden.
-    const QString oldPath = m_model->fileItem(0).url().path() + "/2a";
-    const QString newPath = m_model->fileItem(0).url().path() + "/.2a";
+    const QUrl oldUrl = QUrl::fromLocalFile(m_model->fileItem(0).url().path() + "/2a");
+    const QUrl newUrl = QUrl::fromLocalFile(m_model->fileItem(0).url().path() + "/.2a");
 
-    KIO::SimpleJob* job = KIO::rename(oldPath, newPath, KIO::HideProgressInfo);
+    KIO::SimpleJob* job = KIO::rename(oldUrl, newUrl, KIO::HideProgressInfo);
     bool ok = job->exec();
     QVERIFY(ok);
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsRemoved(KItemRangeList)), DefaultTimeout));
@@ -820,11 +824,11 @@ void KFileItemModelTest::testSorting()
     m_model->loadDirectory(m_testDir->url());
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
 
-    int index = m_model->index(KUrl(m_testDir->url().url() + 'c'));
+    int index = m_model->index(QUrl(m_testDir->url().url() + 'c'));
     m_model->setExpanded(index, true);
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
 
-    index = m_model->index(KUrl(m_testDir->url().url() + "c/c-2"));
+    index = m_model->index(QUrl(m_testDir->url().url() + "c/c-2"));
     m_model->setExpanded(index, true);
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
 
@@ -1019,10 +1023,10 @@ void KFileItemModelTest::testEmptyPath()
     roles.insert("expandedParentsCount");
     m_model->setRoles(roles);
 
-    const KUrl emptyUrl;
+    const QUrl emptyUrl;
     QVERIFY(emptyUrl.path().isEmpty());
 
-    const KUrl url("file:///test/");
+    const QUrl url("file:///test/");
 
     KFileItemList items;
     items << KFileItem(emptyUrl, QString(), KFileItem::Unknown) << KFileItem(url, QString(), KFileItem::Unknown);
@@ -1056,7 +1060,7 @@ void KFileItemModelTest::testRefreshExpandedItem()
     QSignalSpy spyItemsChanged(m_model, SIGNAL(itemsChanged(KItemRangeList,QSet<QByteArray>)));
 
     const KFileItem item = m_model->fileItem(0);
-    m_model->slotRefreshItems(QList<QPair<KFileItem, KFileItem> >() << qMakePair(item, item));
+    m_model->slotRefreshItems({qMakePair(item, item)});
     QVERIFY(!spyItemsChanged.isEmpty());
 
     QCOMPARE(m_model->count(), 5); // "a/", "a/1", "a/2", "3", "4"
@@ -1073,7 +1077,7 @@ void KFileItemModelTest::testRemoveHiddenItems()
     m_testDir->createDir(".b");
     m_testDir->createDir("c");
     m_testDir->createDir("d");
-    m_testDir->createFiles(QStringList() << ".f" << ".g" << "h" << "i");
+    m_testDir->createFiles({".f", ".g", "h", "i"});
 
     QSignalSpy spyItemsInserted(m_model, SIGNAL(itemsInserted(KItemRangeList)));
     QSignalSpy spyItemsRemoved(m_model, SIGNAL(itemsRemoved(KItemRangeList)));
@@ -1249,28 +1253,28 @@ void KFileItemModelTest::testGeneralParentChildRelationships()
     QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "parent2" << "realChild2" << "realGrandChild2");
 
     // Add some more children and grand-children.
-    const KUrl parent1 = m_model->fileItem(0).url();
-    const KUrl parent2 = m_model->fileItem(3).url();
-    const KUrl realChild1 = m_model->fileItem(1).url();
-    const KUrl realChild2 = m_model->fileItem(4).url();
+    const QUrl parent1 = m_model->fileItem(0).url();
+    const QUrl parent2 = m_model->fileItem(3).url();
+    const QUrl realChild1 = m_model->fileItem(1).url();
+    const QUrl realChild2 = m_model->fileItem(4).url();
 
-    m_model->slotItemsAdded(parent1, KFileItemList() << KFileItem(KUrl("child1"), QString(), KFileItem::Unknown));
+    m_model->slotItemsAdded(parent1, KFileItemList() << KFileItem(QUrl("child1"), QString(), KFileItem::Unknown));
     m_model->slotCompleted();
     QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "child1" << "parent2" << "realChild2" << "realGrandChild2");
 
-    m_model->slotItemsAdded(parent2, KFileItemList() << KFileItem(KUrl("child2"), QString(), KFileItem::Unknown));
+    m_model->slotItemsAdded(parent2, KFileItemList() << KFileItem(QUrl("child2"), QString(), KFileItem::Unknown));
     m_model->slotCompleted();
     QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "child1" << "parent2" << "realChild2" << "realGrandChild2" << "child2");
 
-    m_model->slotItemsAdded(realChild1, KFileItemList() << KFileItem(KUrl("grandChild1"), QString(), KFileItem::Unknown));
+    m_model->slotItemsAdded(realChild1, KFileItemList() << KFileItem(QUrl("grandChild1"), QString(), KFileItem::Unknown));
     m_model->slotCompleted();
     QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "grandChild1" << "realGrandChild1" << "child1" << "parent2" << "realChild2" << "realGrandChild2" << "child2");
 
-    m_model->slotItemsAdded(realChild1, KFileItemList() << KFileItem(KUrl("grandChild1"), QString(), KFileItem::Unknown));
+    m_model->slotItemsAdded(realChild1, KFileItemList() << KFileItem(QUrl("grandChild1"), QString(), KFileItem::Unknown));
     m_model->slotCompleted();
     QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "grandChild1" << "realGrandChild1" << "child1" << "parent2" << "realChild2" << "realGrandChild2" << "child2");
 
-    m_model->slotItemsAdded(realChild2, KFileItemList() << KFileItem(KUrl("grandChild2"), QString(), KFileItem::Unknown));
+    m_model->slotItemsAdded(realChild2, KFileItemList() << KFileItem(QUrl("grandChild2"), QString(), KFileItem::Unknown));
     m_model->slotCompleted();
     QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "grandChild1" << "realGrandChild1" << "child1" << "parent2" << "realChild2" << "grandChild2" << "realGrandChild2" << "child2");
 
@@ -1353,11 +1357,11 @@ void KFileItemModelTest::testNameRoleGroups()
     // Change d.txt back to c.txt, but this time using the dir lister's refreshItems() signal.
     const KFileItem fileItemD = m_model->fileItem(2);
     KFileItem fileItemC = fileItemD;
-    KUrl urlC = fileItemC.url();
-    urlC.setFileName("c.txt");
+    QUrl urlC = fileItemC.url().adjusted(QUrl::RemoveFilename);
+    urlC.setPath(urlC.path() + "c.txt");
     fileItemC.setUrl(urlC);
 
-    m_model->slotRefreshItems(QList<QPair<KFileItem, KFileItem> >() << qMakePair(fileItemD, fileItemC));
+    m_model->slotRefreshItems({qMakePair(fileItemD, fileItemC)});
     QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(groupsChanged()), DefaultTimeout));
     QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "e.txt");
 
@@ -1443,7 +1447,7 @@ void KFileItemModelTest::testInconsistentModel()
     // Note that the first item in the list of added items must be new (i.e., not
     // in the model yet). Otherwise, KFileItemModel::slotItemsAdded() will see that
     // it receives items that are in the model already and ignore them.
-    KUrl url(m_model->directory().url() + "/a2");
+    QUrl url(m_model->directory().url() + "/a2");
     KFileItem newItem(KFileItem::Unknown, KFileItem::Unknown, url);
 
     KFileItemList items;
@@ -1580,17 +1584,143 @@ void KFileItemModelTest::testRefreshFilteredItems()
 
     // Rename one of the .jpg files.
     KFileItem fileItemE = fileItemC;
-    KUrl urlE = fileItemE.url();
-    urlE.setFileName("e.jpg");
+    QUrl urlE = fileItemE.url().adjusted(QUrl::RemoveFilename);
+    urlE.setPath(urlE.path() + "e.jpg");
     fileItemE.setUrl(urlE);
 
-    m_model->slotRefreshItems(QList<QPair<KFileItem, KFileItem> >() << qMakePair(fileItemC, fileItemE));
+    m_model->slotRefreshItems({qMakePair(fileItemC, fileItemE)});
 
     // Show all files again, and verify that the model has updated the file name.
     m_model->setNameFilter(QString());
     QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "d.jpg" << "e.jpg");
 }
 
+void KFileItemModelTest::testCreateMimeData()
+{
+    QSet<QByteArray> modelRoles = m_model->roles();
+    modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount";
+    m_model->setRoles(modelRoles);
+
+    QStringList files;
+    files << "a/1";
+    m_testDir->createFiles(files);
+
+    m_model->loadDirectory(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a");
+
+    // Expand "a/".
+    m_model->setExpanded(0, true);
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a" << "1");
+
+    // Verify that creating the MIME data for a child of an expanded folder does
+    // not cause a crash, see https://bugs.kde.org/show_bug.cgi?id=329119
+    KItemSet selection;
+    selection.insert(1);
+    QMimeData* mimeData = m_model->createMimeData(selection);
+    delete mimeData;
+}
+
+void KFileItemModelTest::testCollapseFolderWhileLoading()
+{
+    QSet<QByteArray> modelRoles = m_model->roles();
+    modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount";
+    m_model->setRoles(modelRoles);
+
+    QStringList files;
+    files << "a2/b/c1.txt";
+    m_testDir->createFiles(files);
+
+    m_model->loadDirectory(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a2");
+
+    // Expand "a2/".
+    m_model->setExpanded(0, true);
+    QVERIFY(m_model->isExpanded(0));
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a2" << "b");
+
+    // Expand "a2/b/".
+    m_model->setExpanded(1, true);
+    QVERIFY(m_model->isExpanded(1));
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a2" << "b" << "c1.txt");
+
+    // Simulate that a new item "c2.txt" appears, but that the dir lister's completed()
+    // signal is not emitted yet.
+    const KFileItem fileItemC1 = m_model->fileItem(2);
+    KFileItem fileItemC2 = fileItemC1;
+    QUrl urlC2 = fileItemC2.url();
+    urlC2.adjusted(QUrl::RemoveFilename);
+    urlC2.setPath(urlC2.path() + "c2.txt");
+    fileItemC2.setUrl(urlC2);
+
+    const QUrl urlB = m_model->fileItem(1).url();
+    m_model->slotItemsAdded(urlB, KFileItemList() << fileItemC2);
+    QCOMPARE(itemsInModel(), QStringList() << "a2" << "b" << "c1.txt");
+
+    // Collapse "a2/". This should also remove all its (indirect) children from
+    // the model and from the model's m_pendingItemsToInsert member.
+    m_model->setExpanded(0, false);
+    QCOMPARE(itemsInModel(), QStringList() << "a2");
+
+    // Simulate that the dir lister's completed() signal is emitted. If "c2.txt"
+    // is still in m_pendingItemsToInsert, then we might get a crash, see
+    // https://bugs.kde.org/show_bug.cgi?id=332102. Even if the crash is not
+    // reproducible here, Valgrind will complain, and the item "c2.txt" will appear
+    // without parent in the model.
+    m_model->slotCompleted();
+    QCOMPARE(itemsInModel(), QStringList() << "a2");
+
+    // Expand "a2/" again.
+    m_model->setExpanded(0, true);
+    QVERIFY(m_model->isExpanded(0));
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a2" << "b");
+
+    // Now simulate that a new folder "a1/" is appears, but that the dir lister's
+    // completed() signal is not emitted yet.
+    const KFileItem fileItemA2 = m_model->fileItem(0);
+    KFileItem fileItemA1 = fileItemA2;
+    QUrl urlA1 = fileItemA1.url().adjusted(QUrl::RemoveFilename);
+    urlA1.setPath(urlA1.path() + "a1");
+    fileItemA1.setUrl(urlA1);
+
+    m_model->slotItemsAdded(m_model->directory(), KFileItemList() << fileItemA1);
+    QCOMPARE(itemsInModel(), QStringList() << "a2" << "b");
+
+    // Collapse "a2/". Note that this will cause "a1/" to be added to the model,
+    // i.e., the index of "a2/" will change from 0 to 1. Check that this does not
+    // confuse the code which collapses the folder.
+    m_model->setExpanded(0, false);
+    QCOMPARE(itemsInModel(), QStringList() << "a1" << "a2");
+    QVERIFY(!m_model->isExpanded(0));
+    QVERIFY(!m_model->isExpanded(1));
+}
+
+void KFileItemModelTest::testDeleteFileMoreThanOnce()
+{
+    QStringList files;
+    files << "a.txt" << "b.txt" << "c.txt" << "d.txt";
+    m_testDir->createFiles(files);
+
+    m_model->loadDirectory(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "d.txt");
+
+    const KFileItem fileItemB = m_model->fileItem(1);
+
+    // Tell the model that a list of items has been deleted, where "b.txt" appears twice in the list.
+    KFileItemList list;
+    list << fileItemB << fileItemB;
+    m_model->slotItemsDeleted(list);
+
+    QVERIFY(m_model->isConsistent());
+    QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "c.txt" << "d.txt");
+}
+
 QStringList KFileItemModelTest::itemsInModel() const
 {
     QStringList items;