X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/caf49dafa557caa9bd985702a240284348c82b40..09a0a44a073cf6396f0a28dc3847d081c4dab24e:/src/tests/kfileitemmodeltest.cpp diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index 679b8ab3a..4c6db590d 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -5,20 +5,20 @@ * SPDX-License-Identifier: GPL-2.0-or-later */ +#include #include -#include #include #include +#include #include -#include #include -#include +#include #include "kitemviews/kfileitemmodel.h" #include "testdir.h" -void myMessageOutput(QtMsgType type, const QMessageLogContext& context, const QString& msg) +void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) { Q_UNUSED(context) @@ -34,7 +34,7 @@ void myMessageOutput(QtMsgType type, const QMessageLogContext& context, const QS fprintf(stderr, "Fatal: %s\n", msg.toLocal8Bit().data()); abort(); default: - break; + break; } } @@ -69,6 +69,7 @@ private Q_SLOTS: void testMakeExpandedItemHidden(); void testRemoveFilteredExpandedItems(); void testSorting(); + void testNaturalSorting(); void testIndexForKeyboardSearch(); void testNameFilter(); void testEmptyPath(); @@ -90,13 +91,16 @@ private Q_SLOTS: void testCollapseFolderWhileLoading(); void testCreateMimeData(); void testDeleteFileMoreThanOnce(); + void testInsertAfterExpand(); + void testCurrentDirRemoved(); + void testSizeSortingAfterRefresh(); private: QStringList itemsInModel() const; private: - KFileItemModel* m_model; - TestDir* m_testDir; + KFileItemModel *m_model; + TestDir *m_testDir; }; void KFileItemModelTest::initTestCase() @@ -154,9 +158,9 @@ void KFileItemModelTest::testDefaultSortRole() QVERIFY(itemsInsertedSpy.wait()); QCOMPARE(m_model->count(), 3); - QCOMPARE(m_model->data(0).value("text").toString(), QString("a.txt")); - QCOMPARE(m_model->data(1).value("text").toString(), QString("b.txt")); - QCOMPARE(m_model->data(2).value("text").toString(), QString("c.txt")); + QCOMPARE(m_model->data(0).value("text").toString(), QStringLiteral("a.txt")); + QCOMPARE(m_model->data(1).value("text").toString(), QStringLiteral("b.txt")); + QCOMPARE(m_model->data(2).value("text").toString(), QStringLiteral("c.txt")); } void KFileItemModelTest::testDefaultGroupedSorting() @@ -259,8 +263,8 @@ void KFileItemModelTest::testSetData() QCOMPARE(itemsChangedSpy.count(), 1); values = m_model->data(0); - QCOMPARE(values.value("customRole1").toString(), QString("Test1")); - QCOMPARE(values.value("customRole2").toString(), QString("Test2")); + QCOMPARE(values.value("customRole1").toString(), QStringLiteral("Test1")); + QCOMPARE(values.value("customRole2").toString(), QStringLiteral("Test2")); QVERIFY(m_model->isConsistent()); } @@ -279,11 +283,11 @@ void KFileItemModelTest::testSetDataWithModifiedSortRole_data() // Index 2 = rating 6 QTest::newRow("Index 0: Rating 3") << 0 << 3 << false << 3 << 4 << 6; - QTest::newRow("Index 0: Rating 5") << 0 << 5 << true << 4 << 5 << 6; - QTest::newRow("Index 0: Rating 8") << 0 << 8 << true << 4 << 6 << 8; + QTest::newRow("Index 0: Rating 5") << 0 << 5 << true << 4 << 5 << 6; + QTest::newRow("Index 0: Rating 8") << 0 << 8 << true << 4 << 6 << 8; - QTest::newRow("Index 2: Rating 1") << 2 << 1 << true << 1 << 2 << 4; - QTest::newRow("Index 2: Rating 3") << 2 << 3 << true << 2 << 3 << 4; + QTest::newRow("Index 2: Rating 1") << 2 << 1 << true << 1 << 2 << 4; + QTest::newRow("Index 2: Rating 3") << 2 << 3 << true << 2 << 3 << 4; QTest::newRow("Index 2: Rating 5") << 2 << 5 << false << 2 << 4 << 5; } @@ -361,7 +365,10 @@ void KFileItemModelTest::testChangeSortRole() m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.jpg" << "c.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.jpg" + << "c.txt"); // Simulate that KFileItemModelRolesUpdater determines the mime type. // Resorting the files by 'type' will only work immediately if their @@ -378,10 +385,14 @@ void KFileItemModelTest::testChangeSortRole() // The actual order of the files might depend on the translation of the // result of KFileItem::mimeComment() in the user's language. QStringList version1; - version1 << "b.jpg" << "a.txt" << "c.txt"; + version1 << "b.jpg" + << "a.txt" + << "c.txt"; QStringList version2; - version2 << "a.txt" << "c.txt" << "b.jpg"; + version2 << "a.txt" + << "c.txt" + << "b.jpg"; const bool ok1 = (itemsInModel() == version1); const bool ok2 = (itemsInModel() == version2); @@ -403,7 +414,10 @@ void KFileItemModelTest::testResortAfterChangingName() m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.txt"); // We rename a.txt to d.txt. Even though the size has not changed at all, // the model must re-sort the items. @@ -412,7 +426,10 @@ void KFileItemModelTest::testResortAfterChangingName() m_model->setData(0, data); QVERIFY(itemsMovedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "b.txt" << "c.txt" << "d.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "b.txt" + << "c.txt" + << "d.txt"); // We rename d.txt back to a.txt using the dir lister's refreshItems() signal. const KFileItem fileItemD = m_model->fileItem(2); @@ -424,7 +441,10 @@ void KFileItemModelTest::testResortAfterChangingName() m_model->slotRefreshItems({qMakePair(fileItemD, fileItemA)}); QVERIFY(itemsMovedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.txt"); } void KFileItemModelTest::testModelConsistencyWhenInsertingItems() @@ -524,15 +544,16 @@ void KFileItemModelTest::testExpandItems() // first three characters. QSet originalModelRoles = m_model->roles(); QSet modelRoles = originalModelRoles; - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a/a/1", "a/a-1/1"}); // Store the URLs of all folders in a set. QSet allFolders; - allFolders << QUrl::fromLocalFile(m_testDir->path() + "/a") - << QUrl::fromLocalFile(m_testDir->path() + "/a/a") + allFolders << QUrl::fromLocalFile(m_testDir->path() + "/a") << QUrl::fromLocalFile(m_testDir->path() + "/a/a") << QUrl::fromLocalFile(m_testDir->path() + "/a/a-1"); m_model->loadDirectory(m_testDir->url()); @@ -568,9 +589,8 @@ void KFileItemModelTest::testExpandItems() m_model->setExpanded(1, true); QVERIFY(m_model->isExpanded(1)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(m_model->count(), 4); // 4 items: "a/", "a/a/", "a/a/1", "a/a-1/" - QCOMPARE(m_model->expandedDirectories(), QSet() << QUrl::fromLocalFile(m_testDir->path() + "/a") - << QUrl::fromLocalFile(m_testDir->path() + "/a/a")); + QCOMPARE(m_model->count(), 4); // 4 items: "a/", "a/a/", "a/a/1", "a/a-1/" + QCOMPARE(m_model->expandedDirectories(), QSet() << QUrl::fromLocalFile(m_testDir->path() + "/a") << QUrl::fromLocalFile(m_testDir->path() + "/a/a")); QCOMPARE(itemsInsertedSpy.count(), 1); itemRangeList = itemsInsertedSpy.takeFirst().at(0).value(); @@ -583,7 +603,7 @@ void KFileItemModelTest::testExpandItems() m_model->setExpanded(3, true); QVERIFY(m_model->isExpanded(3)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" + QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" QCOMPARE(m_model->expandedDirectories(), allFolders); QCOMPARE(itemsInsertedSpy.count(), 1); @@ -612,7 +632,7 @@ void KFileItemModelTest::testExpandItems() m_model->loadDirectory(m_testDir->url()); m_model->restoreExpandedDirectories(allFolders); QVERIFY(loadingCompletedSpy.wait()); - QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" + QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" QVERIFY(m_model->isExpanded(0)); QVERIFY(m_model->isExpanded(1)); QVERIFY(!m_model->isExpanded(2)); @@ -625,11 +645,11 @@ void KFileItemModelTest::testExpandItems() // This is how DolphinView restores the expanded folders when navigating in history. m_model->loadDirectory(QUrl::fromLocalFile(m_testDir->path() + "/a/a/")); QVERIFY(loadingCompletedSpy.wait()); - QCOMPARE(m_model->count(), 1); // 1 item: "1" + QCOMPARE(m_model->count(), 1); // 1 item: "1" m_model->restoreExpandedDirectories(allFolders); m_model->loadDirectory(m_testDir->url()); QVERIFY(loadingCompletedSpy.wait()); - QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" + QCOMPARE(m_model->count(), 5); // 5 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1" QCOMPARE(m_model->expandedDirectories(), allFolders); // Remove all expanded items by changing the roles @@ -660,7 +680,9 @@ void KFileItemModelTest::testExpandParentItems() // a2/b2/c2/ // a2/b2/c2/d2/ QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a 1/b1/c1/file.txt", "a2/b2/c2/d2/file.txt"}); @@ -732,7 +754,9 @@ void KFileItemModelTest::testMakeExpandedItemHidden() QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"1a/2a/3a", "1a/2a/3b", "1a/2b", "1b"}); @@ -755,7 +779,7 @@ void KFileItemModelTest::testMakeExpandedItemHidden() 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(oldUrl, newUrl, KIO::HideProgressInfo); + KIO::SimpleJob *job = KIO::rename(oldUrl, newUrl, KIO::HideProgressInfo); bool ok = job->exec(); QVERIFY(ok); QVERIFY(itemsRemovedSpy.wait()); @@ -766,7 +790,6 @@ void KFileItemModelTest::testMakeExpandedItemHidden() m_model->setExpanded(0, false); QCOMPARE(m_model->count(), 2); - } void KFileItemModelTest::testRemoveFilteredExpandedItems() @@ -775,7 +798,9 @@ void KFileItemModelTest::testRemoveFilteredExpandedItems() QSet originalModelRoles = m_model->roles(); QSet modelRoles = originalModelRoles; - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"folder/child", "file"}); @@ -789,17 +814,24 @@ void KFileItemModelTest::testRemoveFilteredExpandedItems() QVERIFY(!m_model->isExpandable(1)); QVERIFY(!m_model->isExpanded(0)); QVERIFY(!m_model->isExpanded(1)); - QCOMPARE(itemsInModel(), QStringList() << "folder" << "file"); + QCOMPARE(itemsInModel(), + QStringList() << "folder" + << "file"); // Expand "folder" -> "folder/child" becomes visible. m_model->setExpanded(0, true); QVERIFY(m_model->isExpanded(0)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "folder" << "child" << "file"); + QCOMPARE(itemsInModel(), + QStringList() << "folder" + << "child" + << "file"); // Add a name filter. m_model->setNameFilter("f"); - QCOMPARE(itemsInModel(), QStringList() << "folder" << "file"); + QCOMPARE(itemsInModel(), + QStringList() << "folder" + << "file"); m_model->setNameFilter("fo"); QCOMPARE(itemsInModel(), QStringList() << "folder"); @@ -811,7 +843,111 @@ void KFileItemModelTest::testRemoveFilteredExpandedItems() // Remove the name filter and verify that "folder/child" does not reappear. m_model->setNameFilter(QString()); - QCOMPARE(itemsInModel(), QStringList() << "folder" << "file"); + QCOMPARE(itemsInModel(), + QStringList() << "folder" + << "file"); +} + +void KFileItemModelTest::testSizeSortingAfterRefresh() +{ + // testDir structure is as follows + // ./ + // ├─ a + // ├─ b + // ├─ c/ + // │ ├─ c-2/ + // │ │ ├─ c-3 + // │ ├─ c-1 + // ├─ d + // ├─ e + + QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); + QSignalSpy itemsMovedSpy(m_model, &KFileItemModel::itemsMoved); + QVERIFY(itemsMovedSpy.isValid()); + + // Create some files with different sizes and modification times to check the different sorting options + QDateTime now = QDateTime::currentDateTime(); + + QSet roles; + roles.insert("text"); + roles.insert("isExpanded"); + roles.insert("isExpandable"); + roles.insert("expandedParentsCount"); + m_model->setRoles(roles); + + m_testDir->createDir("c/c-2"); + m_testDir->createFile("c/c-2/c-3"); + m_testDir->createFile("c/c-1"); + + m_testDir->createFile("a", "A file", now.addDays(-3)); + m_testDir->createFile("b", "A larger file", now.addDays(0)); + m_testDir->createDir("c", now.addDays(-2)); + m_testDir->createFile("d", "The largest file in this directory", now.addDays(-1)); + m_testDir->createFile("e", "An even larger file", now.addDays(-4)); + + m_model->loadDirectory(m_testDir->url()); + QVERIFY(itemsInsertedSpy.wait()); + + int index = m_model->index(QUrl(m_testDir->url().url() + "/c")); + m_model->setExpanded(index, true); + QVERIFY(itemsInsertedSpy.wait()); + + index = m_model->index(QUrl(m_testDir->url().url() + "/c/c-2")); + m_model->setExpanded(index, true); + QVERIFY(itemsInsertedSpy.wait()); + + // Default: Sort by Name, ascending + QCOMPARE(m_model->sortRole(), QByteArray("text")); + QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "d" + << "e"); + + // Sort by Size, ascending, before refresh + m_model->setSortRole("size"); + QCOMPARE(m_model->sortRole(), QByteArray("size")); + QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "e" + << "d"); + + // Refresh directory + m_model->refreshDirectory(m_model->directory()); + QVERIFY(itemsInsertedSpy.wait()); + + // Expand folders again + index = m_model->index(QUrl(m_testDir->url().url() + "/c")); + m_model->setExpanded(index, true); + QVERIFY(itemsInsertedSpy.wait()); + + index = m_model->index(QUrl(m_testDir->url().url() + "/c/c-2")); + m_model->setExpanded(index, true); + QVERIFY(itemsInsertedSpy.wait()); + + // Sort by Size, ascending, after refresh + QCOMPARE(m_model->sortRole(), QByteArray("size")); + QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "e" + << "d"); } void KFileItemModelTest::testSorting() @@ -880,83 +1016,155 @@ void KFileItemModelTest::testSorting() QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(m_model->sortDirectoriesFirst()); QVERIFY(!m_model->showHiddenFiles()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "d" << "e"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "d" + << "e"); // Sort by Name, ascending, 'Sort Folders First' disabled m_model->setSortDirectoriesFirst(false); QCOMPARE(m_model->sortRole(), QByteArray("text")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "c" + << "c-1" + << "c-2" + << "c-3" + << "d" + << "e"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(0, 6)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 2 << 4 << 5 << 3 << 0 << 1); // Sort by Name, descending m_model->setSortDirectoriesFirst(true); m_model->setSortOrder(Qt::DescendingOrder); QCOMPARE(m_model->sortRole(), QByteArray("text")); QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "d" << "b" << "a"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "e" + << "d" + << "b" + << "a"); QCOMPARE(itemsMovedSpy.count(), 2); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(0, 6)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 4 << 5 << 0 << 3 << 1 << 2); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 4 << 5 << 0 << 3 << 1 << 2); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 4)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 7 << 6 << 5 << 4); // Sort by Date, descending m_model->setSortDirectoriesFirst(true); m_model->setSortRole("modificationtime"); QCOMPARE(m_model->sortRole(), QByteArray("modificationtime")); QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "b" << "d" << "a" << "e"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "b" + << "d" + << "a" + << "e"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 4)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 7 << 5 << 4 << 6); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 7 << 5 << 4 << 6); // Sort by Date, ascending m_model->setSortOrder(Qt::AscendingOrder); QCOMPARE(m_model->sortRole(), QByteArray("modificationtime")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "a" << "d" << "b"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "e" + << "a" + << "d" + << "b"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 4)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 7 << 6 << 5 << 4); // Sort by Date, ascending, 'Sort Folders First' disabled m_model->setSortDirectoriesFirst(false); QCOMPARE(m_model->sortRole(), QByteArray("modificationtime")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(!m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "e" << "a" << "c" << "c-1" << "c-2" << "c-3" << "d" << "b"); + QCOMPARE(itemsInModel(), + QStringList() << "e" + << "a" + << "c" + << "c-1" + << "c-2" + << "c-3" + << "d" + << "b"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(0, 6)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 2 << 4 << 5 << 3 << 0 << 1); // Sort by Name, ascending, 'Sort Folders First' disabled m_model->setSortRole("text"); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(!m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "c" + << "c-1" + << "c-2" + << "c-3" + << "d" + << "e"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(0, 8)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 7 << 0 << 2 << 3 << 4 << 5 << 6 << 1); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 7 << 0 << 2 << 3 << 4 << 5 << 6 << 1); // Sort by Size, ascending, 'Sort Folders First' disabled m_model->setSortRole("size"); QCOMPARE(m_model->sortRole(), QByteArray("size")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(!m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "e" << "d"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "e" + << "d"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(0, 8)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 4 << 5 << 0 << 3 << 1 << 2 << 7 << 6); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 4 << 5 << 0 << 3 << 1 << 2 << 7 << 6); // In 'Sort by Size' mode, folders are always first -> changing 'Sort Folders First' does not resort the model m_model->setSortDirectoriesFirst(true); QCOMPARE(m_model->sortRole(), QByteArray("size")); QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); QVERIFY(m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "e" << "d"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "e" + << "d"); QCOMPARE(itemsMovedSpy.count(), 0); // Sort by Size, descending, 'Sort Folders First' enabled @@ -964,16 +1172,34 @@ void KFileItemModelTest::testSorting() QCOMPARE(m_model->sortRole(), QByteArray("size")); QCOMPARE(m_model->sortOrder(), Qt::DescendingOrder); QVERIFY(m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "d" << "e" << "b" << "a"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "d" + << "e" + << "b" + << "a"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 4)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 7 << 6 << 5 << 4); // 'Show Hidden Files' enabled m_model->setShowHiddenFiles(true); QVERIFY(m_model->showHiddenFiles()); QVERIFY(!m_model->sortHiddenLast()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << ".g" << "d" << "e" << "b" << "a" << ".f"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << ".g" + << "d" + << "e" + << "b" + << "a" + << ".f"); QCOMPARE(itemsMovedSpy.count(), 0); QCOMPARE(itemsInsertedSpy.count(), 1); QCOMPARE(itemsInsertedSpy.takeFirst().at(0).value(), KItemRangeList() << KItemRange(4, 1) << KItemRange(8, 1)); @@ -981,41 +1207,157 @@ void KFileItemModelTest::testSorting() // 'Sort Hidden Files Last' enabled m_model->setSortHiddenLast(true); QVERIFY(m_model->sortHiddenLast()); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "d" << "e" << "b" << "a" << ".g" << ".f"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "d" + << "e" + << "b" + << "a" + << ".g" + << ".f"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsInsertedSpy.count(), 0); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 5)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 8 << 4 << 5 << 6 << 7); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 8 << 4 << 5 << 6 << 7); // Sort by Name m_model->setSortRole("text"); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "e" << "d" << "b" << "a" << ".g" << ".f"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "e" + << "d" + << "b" + << "a" + << ".g" + << ".f"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 2)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 5 << 4); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 5 << 4); // Sort ascending m_model->setSortOrder(Qt::AscendingOrder); - QCOMPARE(itemsInModel(), QStringList() << "c" << "c-2" << "c-3" << "c-1" << "a" << "b" << "d" << "e" << ".g" << ".f"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "c-2" + << "c-3" + << "c-1" + << "a" + << "b" + << "d" + << "e" + << ".g" + << ".f"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(4, 4)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 7 << 6 << 5 << 4); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 7 << 6 << 5 << 4); // 'Sort Folders First' disabled m_model->setSortDirectoriesFirst(false); QVERIFY(!m_model->sortDirectoriesFirst()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c" << "c-1" << "c-2" << "c-3" << "d" << "e" << ".f" << ".g"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "c" + << "c-1" + << "c-2" + << "c-3" + << "d" + << "e" + << ".f" + << ".g"); QCOMPARE(itemsMovedSpy.count(), 1); QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(0, 10)); - QCOMPARE(itemsMovedSpy.takeFirst().at(1).value >(), QList() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7 << 9 << 8); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 2 << 4 << 5 << 3 << 0 << 1 << 6 << 7 << 9 << 8); +} + +void KFileItemModelTest::testNaturalSorting() +{ + QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); + QSignalSpy itemsMovedSpy(m_model, &KFileItemModel::itemsMoved); + QVERIFY(itemsMovedSpy.isValid()); + + m_model->setSortRole("text"); + m_model->setShowHiddenFiles(true); + + m_testDir->createFiles({".a", "a.txt", "b.txt", "a 1.txt", "a 2.txt", "a 10.txt", "a.tar", "b.tar"}); + m_model->loadDirectory(m_testDir->url()); + QVERIFY(itemsInsertedSpy.wait()); + + // Sort by Name, ascending, natural sorting enabled + QCOMPARE(m_model->sortRole(), QByteArray("text")); + QCOMPARE(m_model->sortOrder(), Qt::AscendingOrder); + QCOMPARE(itemsInModel(), + QStringList() << ".a" + << "a.tar" + << "a.txt" + << "a 1.txt" + << "a 2.txt" + << "a 10.txt" + << "b.tar" + << "b.txt"); + + // Sort by Extension + m_model->setSortRole("extension"); + QCOMPARE(m_model->sortRole(), QByteArray("extension")); + QCOMPARE(itemsInModel(), + QStringList() << ".a" + << "a.tar" + << "b.tar" + << "a.txt" + << "a 1.txt" + << "a 2.txt" + << "a 10.txt" + << "b.txt"); + QCOMPARE(itemsMovedSpy.count(), 1); + QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(2, 5)); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 3 << 4 << 5 << 6 << 2); + + // Disable natural sorting, refresh directory for the change to take effect + m_model->m_naturalSorting = false; + m_model->refreshDirectory(m_model->directory()); + QVERIFY(itemsInsertedSpy.wait()); + + // Sort by Extension, ascending, natural sorting disabled + QCOMPARE(m_model->sortRole(), QByteArray("extension")); + QCOMPARE(itemsInModel(), + QStringList() << ".a" + << "a.tar" + << "b.tar" + << "a 1.txt" + << "a 10.txt" + << "a 2.txt" + << "a.txt" + << "b.txt"); + + // Sort by Name + m_model->setSortRole("text"); + QCOMPARE(m_model->sortRole(), QByteArray("text")); + QCOMPARE(itemsInModel(), + QStringList() << ".a" + << "a 1.txt" + << "a 10.txt" + << "a 2.txt" + << "a.tar" + << "a.txt" + << "b.tar" + << "b.txt"); + QCOMPARE(itemsMovedSpy.count(), 1); + QCOMPARE(itemsMovedSpy.first().at(0).value(), KItemRange(1, 6)); + QCOMPARE(itemsMovedSpy.takeFirst().at(1).value>(), QList() << 4 << 6 << 1 << 2 << 3 << 5); } void KFileItemModelTest::testIndexForKeyboardSearch() { QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); - m_testDir->createFiles({"a", "aa", "Image.jpg", "Image.png", "Text", "Text1", "Text2", "Text11"}); + m_testDir->createFiles({"a", "aa", "Image.jpg", "Image.png", "Text", "Text1", "Text2", "Text11", "U", "Ü", "Üu", "Ž"}); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); @@ -1032,6 +1374,9 @@ void KFileItemModelTest::testIndexForKeyboardSearch() QCOMPARE(m_model->indexForKeyboardSearch("text1", 0), 5); QCOMPARE(m_model->indexForKeyboardSearch("text2", 0), 6); QCOMPARE(m_model->indexForKeyboardSearch("text11", 0), 7); + QCOMPARE(m_model->indexForKeyboardSearch("u", 0), 8); + QCOMPARE(m_model->indexForKeyboardSearch("üu", 0), 10); + QCOMPARE(m_model->indexForKeyboardSearch("ž", 0), 11); // Start a search somewhere in the middle QCOMPARE(m_model->indexForKeyboardSearch("a", 1), 1); @@ -1058,6 +1403,12 @@ void KFileItemModelTest::testIndexForKeyboardSearch() QCOMPARE(m_model->indexForKeyboardSearch("TexT", 5), 5); QCOMPARE(m_model->indexForKeyboardSearch("IMAGE", 4), 2); + // Test searches that match items with marks + QCOMPARE(m_model->indexForKeyboardSearch("u", 9), 9); + QCOMPARE(m_model->indexForKeyboardSearch("u", 10), 10); + QCOMPARE(m_model->indexForKeyboardSearch("uu", 0), 10); + QCOMPARE(m_model->indexForKeyboardSearch("z", 0), 11); + // TODO: Maybe we should also test keyboard searches in directories which are not sorted by Name? } @@ -1125,7 +1476,9 @@ void KFileItemModelTest::testRefreshExpandedItem() QVERIFY(itemsChangedSpy.isValid()); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a/1", "a/2", "3", "4"}); @@ -1156,7 +1509,9 @@ void KFileItemModelTest::testAddItemToFilteredExpandedFolder() QSignalSpy fileItemsChangedSpy(m_model, &KFileItemModel::fileItemsChanged); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFile("a/b/file"); @@ -1167,7 +1522,7 @@ void KFileItemModelTest::testAddItemToFilteredExpandedFolder() // Expand "a/". m_model->setExpanded(0, true); - QVERIFY(itemsInsertedSpy.wait()); + QVERIFY(itemsInsertedSpy.wait()); // Expand "a/b/". m_model->setExpanded(1, true); @@ -1186,7 +1541,10 @@ void KFileItemModelTest::testAddItemToFilteredExpandedFolder() // Entire parental chain should now be shown QCOMPARE(m_model->count(), 3); // 3 items: "a/", "a/b/", "a/b/newItem.txt" - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "newItem.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "newItem.txt"); // Items should be indented in hierarchy QCOMPARE(m_model->expandedParentsCount(0), 0); @@ -1202,9 +1560,11 @@ void KFileItemModelTest::testDeleteItemsWithExpandedFolderWithFilter() { QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); - + QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFile("a/b/file"); @@ -1215,7 +1575,7 @@ void KFileItemModelTest::testDeleteItemsWithExpandedFolderWithFilter() // Expand "a/". m_model->setExpanded(0, true); - QVERIFY(itemsInsertedSpy.wait()); + QVERIFY(itemsInsertedSpy.wait()); // Expand "a/b/". m_model->setExpanded(1, true); @@ -1259,7 +1619,10 @@ void KFileItemModelTest::testRefreshItemsWithFilter() // Set a filter that matches ".txt" extension m_model->setNameFilter("*.txt"); QCOMPARE(m_model->count(), 3); // Still all items are shown - QCOMPARE(itemsInModel(), QStringList() << "b.txt" << "c.txt" << "d.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "b.txt" + << "c.txt" + << "d.txt"); // Objects used to rename const KFileItem fileItemC_txt = m_model->fileItem(1); @@ -1289,22 +1652,28 @@ void KFileItemModelTest::testRefreshItemsWithFilter() QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(1, 1)); // Re-sorting is done asynchronously: - QCOMPARE(itemsInModel(), QStringList() << "b.txt" << "a.txt"); // Files should still be in the incorrect order + QCOMPARE(itemsInModel(), + QStringList() << "b.txt" + << "a.txt"); // Files should still be in the incorrect order QVERIFY(itemsMovedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt"); // Files were re-sorted and should now be in the correct order + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt"); // Files were re-sorted and should now be in the correct order } - /** * Verifies that parental chains are hidden and shown as needed while their children get filtered/unfiltered due to renaming. * Also verifies that the "isExpanded" and "expandedParentsCount" values are kept for expanded folders that get refreshed. */ -void KFileItemModelTest::testRefreshExpandedFolderWithFilter() { +void KFileItemModelTest::testRefreshExpandedFolderWithFilter() +{ QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFile("a/b/someFolder/someFile"); @@ -1316,7 +1685,7 @@ void KFileItemModelTest::testRefreshExpandedFolderWithFilter() { // Expand "a/". m_model->setExpanded(0, true); - QVERIFY(itemsInsertedSpy.wait()); + QVERIFY(itemsInsertedSpy.wait()); // Expand "a/b/". m_model->setExpanded(1, true); @@ -1334,7 +1703,7 @@ void KFileItemModelTest::testRefreshExpandedFolderWithFilter() { // Objects used to rename const KFileItem fileItemA = m_model->fileItem(0); KFileItem fileItemARenamed = fileItemA; - fileItemARenamed.setUrl(QUrl("a_renamed")); + fileItemARenamed.setUrl(QUrl("a_renamed")); const KFileItem fileItemSomeFolder = m_model->fileItem(2); KFileItem fileItemRenamedFolder = fileItemSomeFolder; @@ -1344,7 +1713,10 @@ void KFileItemModelTest::testRefreshExpandedFolderWithFilter() { // This way we test if the algorithm is sane as to NOT hide "a_renamed" since it will have visible children m_model->slotRefreshItems({qMakePair(fileItemA, fileItemARenamed)}); QCOMPARE(m_model->count(), 3); // Entire parental chain must still be shown - QCOMPARE(itemsInModel(), QStringList() << "a_renamed" << "b" << "someFolder"); + QCOMPARE(itemsInModel(), + QStringList() << "a_renamed" + << "b" + << "someFolder"); // Rename "a_renamed" back to "a"; and "someFolder" to "renamedFolder" m_model->slotRefreshItems({qMakePair(fileItemARenamed, fileItemA), qMakePair(fileItemSomeFolder, fileItemRenamedFolder)}); @@ -1353,7 +1725,10 @@ void KFileItemModelTest::testRefreshExpandedFolderWithFilter() { // Rename "renamedFolder" back to "someFolder". Filter is passing again m_model->slotRefreshItems({qMakePair(fileItemRenamedFolder, fileItemSomeFolder)}); QCOMPARE(m_model->count(), 3); // Entire parental chain is shown again - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "someFolder"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "someFolder"); // slotRefreshItems() should preserve "isExpanded" and "expandedParentsCount" values explicitly in this case QCOMPARE(m_model->m_itemData.at(2)->values.value("isExpanded").toBool(), true); @@ -1378,21 +1753,41 @@ void KFileItemModelTest::testRemoveHiddenItems() m_model->setShowHiddenFiles(true); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << ".a" << ".b" << "c" << "d" <<".f" << ".g" << "h" << "i"); + QCOMPARE(itemsInModel(), + QStringList() << ".a" + << ".b" + << "c" + << "d" + << ".f" + << ".g" + << "h" + << "i"); QCOMPARE(itemsInsertedSpy.count(), 1); QCOMPARE(itemsRemovedSpy.count(), 0); KItemRangeList itemRangeList = itemsInsertedSpy.takeFirst().at(0).value(); QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 8)); m_model->setShowHiddenFiles(false); - QCOMPARE(itemsInModel(), QStringList() << "c" << "d" << "h" << "i"); + QCOMPARE(itemsInModel(), + QStringList() << "c" + << "d" + << "h" + << "i"); QCOMPARE(itemsInsertedSpy.count(), 0); QCOMPARE(itemsRemovedSpy.count(), 1); itemRangeList = itemsRemovedSpy.takeFirst().at(0).value(); QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 2) << KItemRange(4, 2)); m_model->setShowHiddenFiles(true); - QCOMPARE(itemsInModel(), QStringList() << ".a" << ".b" << "c" << "d" <<".f" << ".g" << "h" << "i"); + QCOMPARE(itemsInModel(), + QStringList() << ".a" + << ".b" + << "c" + << "d" + << ".f" + << ".g" + << "h" + << "i"); QCOMPARE(itemsInsertedSpy.count(), 1); QCOMPARE(itemsRemovedSpy.count(), 0); itemRangeList = itemsInsertedSpy.takeFirst().at(0).value(); @@ -1419,7 +1814,9 @@ void KFileItemModelTest::collapseParentOfHiddenItems() QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a/1", "a/b/1", "a/b/c/1", "a/b/c/d/1"}); @@ -1446,10 +1843,10 @@ void KFileItemModelTest::collapseParentOfHiddenItems() // Set a name filter that matches nothing -> nothing should remain. m_model->setNameFilter("xyz"); QCOMPARE(itemsRemovedSpy.count(), 1); - QCOMPARE(m_model->count(), 0); //Everything is hidden + QCOMPARE(m_model->count(), 0); // Everything is hidden QCOMPARE(itemsInModel(), QStringList()); - //Filter by the file names. Folder "d" will be hidden since it was collapsed + // Filter by the file names. Folder "d" will be hidden since it was collapsed m_model->setNameFilter("1"); QCOMPARE(itemsRemovedSpy.count(), 1); // nothing was removed, itemsRemovedSpy count will remain the same: QCOMPARE(m_model->count(), 6); // 6 items: "a/", "a/b/", "a/b/c", "a/b/c/1", "a/b/1", "a/1" @@ -1476,7 +1873,9 @@ void KFileItemModelTest::removeParentOfHiddenItems() QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a/1", "a/b/1", "a/b/c/1", "a/b/c/d/1"}); @@ -1510,7 +1909,10 @@ void KFileItemModelTest::removeParentOfHiddenItems() m_model->setNameFilter("c"); QCOMPARE(itemsRemovedSpy.count(), 1); // nothing was removed, itemsRemovedSpy count will remain the same: QCOMPARE(m_model->count(), 3); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "c"); // Simulate the deletion of the directory "a/b/". m_model->slotItemsDeleted(KFileItemList() << m_model->fileItem(1)); @@ -1520,7 +1922,9 @@ void KFileItemModelTest::removeParentOfHiddenItems() // Remove the filter -> only the file "a/1" should appear. m_model->setNameFilter(QString()); QCOMPARE(m_model->count(), 2); - QCOMPARE(itemsInModel(), QStringList() << "a" << "1"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "1"); } /** @@ -1534,31 +1938,53 @@ void KFileItemModelTest::testGeneralParentChildRelationships() QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"parent1/realChild1/realGrandChild1", "parent2/realChild2/realGrandChild2"}); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "parent2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "parent2"); // Expand all folders. m_model->setExpanded(0, true); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "parent2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "parent2"); m_model->setExpanded(1, true); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "parent2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "realGrandChild1" + << "parent2"); m_model->setExpanded(3, true); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "parent2" << "realChild2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "realGrandChild1" + << "parent2" + << "realChild2"); m_model->setExpanded(4, true); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "parent2" << "realChild2" << "realGrandChild2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "realGrandChild1" + << "parent2" + << "realChild2" + << "realGrandChild2"); // Add some more children and grand-children. const QUrl parent1 = m_model->fileItem(0).url(); @@ -1568,19 +1994,53 @@ void KFileItemModelTest::testGeneralParentChildRelationships() m_model->slotItemsAdded(parent1, KFileItemList() << KFileItem(QUrl("child1"), QString(), KFileItem::Unknown)); m_model->slotCompleted(); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "realGrandChild1" << "child1" << "parent2" << "realChild2" << "realGrandChild2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "realGrandChild1" + << "child1" + << "parent2" + << "realChild2" + << "realGrandChild2"); 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"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "realGrandChild1" + << "child1" + << "parent2" + << "realChild2" + << "realGrandChild2" + << "child2"); 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"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "grandChild1" + << "realGrandChild1" + << "child1" + << "parent2" + << "realChild2" + << "realGrandChild2" + << "child2"); 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"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "grandChild1" + << "realGrandChild1" + << "child1" + << "parent2" + << "realChild2" + << "grandChild2" + << "realGrandChild2" + << "child2"); // Set a name filter that matches nothing -> nothing will remain. m_model->setNameFilter("xyz"); @@ -1592,12 +2052,19 @@ void KFileItemModelTest::testGeneralParentChildRelationships() // Set a name filter that matches only "realChild". Their prarents should still show. m_model->setNameFilter("realChild"); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "realChild1" << "parent2" << "realChild2"); - QCOMPARE(itemsRemovedSpy.count(), 0); // nothing was removed, itemsRemovedSpy will not be called this time + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "realChild1" + << "parent2" + << "realChild2"); + QCOMPARE(itemsRemovedSpy.count(), 0); // nothing was removed, itemsRemovedSpy will not be called this time // Collapse "parent1". m_model->setExpanded(0, false); - QCOMPARE(itemsInModel(), QStringList() << "parent1" << "parent2" << "realChild2"); + QCOMPARE(itemsInModel(), + QStringList() << "parent1" + << "parent2" + << "realChild2"); QCOMPARE(itemsRemovedSpy.count(), 1); arguments = itemsRemovedSpy.takeFirst(); itemRangeList = arguments.at(0).value(); @@ -1629,9 +2096,13 @@ void KFileItemModelTest::testNameRoleGroups() m_model->setGroupedSorting(true); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "b.txt" << "c.txt" << "d.txt" << "e.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "b.txt" + << "c.txt" + << "d.txt" + << "e.txt"); - QList > expectedGroups; + QList> expectedGroups; expectedGroups << QPair(0, QLatin1String("B")); expectedGroups << QPair(1, QLatin1String("C")); expectedGroups << QPair(2, QLatin1String("D")); @@ -1643,7 +2114,11 @@ void KFileItemModelTest::testNameRoleGroups() data.insert("text", "a.txt"); m_model->setData(2, data); QVERIFY(itemsMovedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "e.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.txt" + << "e.txt"); expectedGroups.clear(); expectedGroups << QPair(0, QLatin1String("A")); @@ -1656,7 +2131,11 @@ void KFileItemModelTest::testNameRoleGroups() data.insert("text", "d.txt"); m_model->setData(2, data); QVERIFY(groupsChangedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "d.txt" << "e.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "d.txt" + << "e.txt"); expectedGroups.clear(); expectedGroups << QPair(0, QLatin1String("A")); @@ -1674,7 +2153,11 @@ void KFileItemModelTest::testNameRoleGroups() m_model->slotRefreshItems({qMakePair(fileItemD, fileItemC)}); QVERIFY(groupsChangedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "e.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.txt" + << "e.txt"); expectedGroups.clear(); expectedGroups << QPair(0, QLatin1String("A")); @@ -1689,7 +2172,9 @@ void KFileItemModelTest::testNameRoleGroupsWithExpandedItems() QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a/b.txt", "a/c.txt", "d/e.txt", "d/f.txt"}); @@ -1697,9 +2182,11 @@ void KFileItemModelTest::testNameRoleGroupsWithExpandedItems() m_model->setGroupedSorting(true); m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "d"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "d"); - QList > expectedGroups; + QList> expectedGroups; expectedGroups << QPair(0, QLatin1String("A")); expectedGroups << QPair(1, QLatin1String("D")); QCOMPARE(m_model->groups(), expectedGroups); @@ -1712,13 +2199,23 @@ void KFileItemModelTest::testNameRoleGroupsWithExpandedItems() m_model->setExpanded(0, true); QVERIFY(m_model->isExpanded(0)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b.txt" << "c.txt" << "d"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b.txt" + << "c.txt" + << "d"); QCOMPARE(m_model->groups(), expectedGroups); m_model->setExpanded(3, true); QVERIFY(m_model->isExpanded(3)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b.txt" << "c.txt" << "d" << "e.txt" << "f.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b.txt" + << "c.txt" + << "d" + << "e.txt" + << "f.txt"); QCOMPARE(m_model->groups(), expectedGroups); } @@ -1727,7 +2224,9 @@ void KFileItemModelTest::testInconsistentModel() QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFiles({"a/b/c1.txt", "a/b/c2.txt"}); @@ -1740,12 +2239,18 @@ void KFileItemModelTest::testInconsistentModel() m_model->setExpanded(0, true); QVERIFY(m_model->isExpanded(0)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b"); m_model->setExpanded(1, true); QVERIFY(m_model->isExpanded(1)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c1.txt" << "c2.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "c1.txt" + << "c2.txt"); // Add the files "c1.txt" and "c2.txt" to the model also as top-level items. // Such a thing can in principle happen when performing a search, and there @@ -1763,19 +2268,29 @@ void KFileItemModelTest::testInconsistentModel() items << newItem << m_model->fileItem(2) << m_model->fileItem(3); m_model->slotItemsAdded(m_model->directory(), items); m_model->slotCompleted(); - QCOMPARE(itemsInModel(), QStringList() << "a" << "b" << "c1.txt" << "c2.txt" << "a2" << "c1.txt" << "c2.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "b" + << "c1.txt" + << "c2.txt" + << "a2" + << "c1.txt" + << "c2.txt"); m_model->setExpanded(0, false); // Test that the right items have been removed, see // https://bugs.kde.org/show_bug.cgi?id=324371 - QCOMPARE(itemsInModel(), QStringList() << "a" << "a2" << "c1.txt" << "c2.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a" + << "a2" + << "c1.txt" + << "c2.txt"); // Test that resorting does not cause a crash, see // https://bugs.kde.org/show_bug.cgi?id=325359 // The crash is not 100% reproducible, but Valgrind will report an invalid memory access. m_model->resortAllItems(); - } void KFileItemModelTest::testChangeRolesForFilteredItems() @@ -1790,7 +2305,10 @@ void KFileItemModelTest::testChangeRolesForFilteredItems() m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "aa.txt" << "aaa.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "aa.txt" + << "aaa.txt"); for (int index = 0; index < m_model->count(); ++index) { // All items should have the "text" and "owner" roles, but not "group". @@ -1809,7 +2327,9 @@ void KFileItemModelTest::testChangeRolesForFilteredItems() // Modify the filter, such that "aa.txt" reappears, and verify that all items have the expected roles. m_model->setNameFilter("aa"); - QCOMPARE(itemsInModel(), QStringList() << "aa.txt" << "aaa.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "aa.txt" + << "aaa.txt"); for (int index = 0; index < m_model->count(); ++index) { // All items should have the "text", "owner", and "group" roles. @@ -1824,7 +2344,10 @@ void KFileItemModelTest::testChangeRolesForFilteredItems() // Clear the filter, and verify that all items have the expected roles m_model->setNameFilter(QString()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "aa.txt" << "aaa.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "aa.txt" + << "aaa.txt"); for (int index = 0; index < m_model->count(); ++index) { // All items should have the "text" and "group" roles, but now "owner". @@ -1850,7 +2373,7 @@ void KFileItemModelTest::testChangeSortRoleWhileFiltering() entry[2].fastInsert(KIO::UDSEntry::UDS_USER, "user-a"); for (int i = 0; i < 3; ++i) { - entry[i].fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, 0100000); // S_IFREG might not be defined on non-Unix platforms. + entry[i].fastInsert(KIO::UDSEntry::UDS_FILE_TYPE, 0100000); // S_IFREG might not be defined on non-Unix platforms. entry[i].fastInsert(KIO::UDSEntry::UDS_ACCESS, 07777); entry[i].fastInsert(KIO::UDSEntry::UDS_SIZE, 0); entry[i].fastInsert(KIO::UDSEntry::UDS_MODIFICATION_TIME, 0); @@ -1862,7 +2385,10 @@ void KFileItemModelTest::testChangeSortRoleWhileFiltering() m_model->slotItemsAdded(m_testDir->url(), items); m_model->slotCompleted(); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.txt"); // Add a filter. m_model->setNameFilter("a"); @@ -1873,7 +2399,10 @@ void KFileItemModelTest::testChangeSortRoleWhileFiltering() // Clear the filter, and verify that the items are sorted correctly. m_model->setNameFilter(QString()); - QCOMPARE(itemsInModel(), QStringList() << "c.txt" << "a.txt" << "b.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "c.txt" + << "a.txt" + << "b.txt"); } void KFileItemModelTest::testRefreshFilteredItems() @@ -1884,13 +2413,19 @@ void KFileItemModelTest::testRefreshFilteredItems() m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.jpg" << "d.jpg"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.jpg" + << "d.jpg"); const KFileItem fileItemC = m_model->fileItem(2); // Show only the .txt files. m_model->setNameFilter(".txt"); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt"); // Rename one of the .jpg files. KFileItem fileItemE = fileItemC; @@ -1902,7 +2437,11 @@ void KFileItemModelTest::testRefreshFilteredItems() // 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"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "d.jpg" + << "e.jpg"); } void KFileItemModelTest::testCreateMimeData() @@ -1910,7 +2449,9 @@ void KFileItemModelTest::testCreateMimeData() QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFile("a/1"); @@ -1922,13 +2463,15 @@ void KFileItemModelTest::testCreateMimeData() // Expand "a/". m_model->setExpanded(0, true); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a" << "1"); + 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); + QMimeData *mimeData = m_model->createMimeData(selection); delete mimeData; } @@ -1937,7 +2480,9 @@ void KFileItemModelTest::testCollapseFolderWhileLoading() QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); QSet modelRoles = m_model->roles(); - modelRoles << "isExpanded" << "isExpandable" << "expandedParentsCount"; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; m_model->setRoles(modelRoles); m_testDir->createFile("a2/b/c1.txt"); @@ -1950,13 +2495,18 @@ void KFileItemModelTest::testCollapseFolderWhileLoading() m_model->setExpanded(0, true); QVERIFY(m_model->isExpanded(0)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a2" << "b"); + QCOMPARE(itemsInModel(), + QStringList() << "a2" + << "b"); // Expand "a2/b/". m_model->setExpanded(1, true); QVERIFY(m_model->isExpanded(1)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a2" << "b" << "c1.txt"); + 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. @@ -1969,7 +2519,10 @@ void KFileItemModelTest::testCollapseFolderWhileLoading() const QUrl urlB = m_model->fileItem(1).url(); m_model->slotItemsAdded(urlB, KFileItemList() << fileItemC2); - QCOMPARE(itemsInModel(), QStringList() << "a2" << "b" << "c1.txt"); + 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. @@ -1988,7 +2541,9 @@ void KFileItemModelTest::testCollapseFolderWhileLoading() m_model->setExpanded(0, true); QVERIFY(m_model->isExpanded(0)); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a2" << "b"); + 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. @@ -1999,13 +2554,17 @@ void KFileItemModelTest::testCollapseFolderWhileLoading() fileItemA1.setUrl(urlA1); m_model->slotItemsAdded(m_model->directory(), KFileItemList() << fileItemA1); - QCOMPARE(itemsInModel(), QStringList() << "a2" << "b"); + 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"); + QCOMPARE(itemsInModel(), + QStringList() << "a1" + << "a2"); QVERIFY(!m_model->isExpanded(0)); QVERIFY(!m_model->isExpanded(1)); } @@ -2018,7 +2577,11 @@ void KFileItemModelTest::testDeleteFileMoreThanOnce() m_model->loadDirectory(m_testDir->url()); QVERIFY(itemsInsertedSpy.wait()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "d.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "b.txt" + << "c.txt" + << "d.txt"); const KFileItem fileItemB = m_model->fileItem(1); @@ -2028,7 +2591,122 @@ void KFileItemModelTest::testDeleteFileMoreThanOnce() m_model->slotItemsDeleted(list); QVERIFY(m_model->isConsistent()); - QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "c.txt" << "d.txt"); + QCOMPARE(itemsInModel(), + QStringList() << "a.txt" + << "c.txt" + << "d.txt"); +} + +void KFileItemModelTest::testInsertAfterExpand() +{ + m_model->m_dirLister->setAutoUpdate(true); + + QSignalSpy itemsInsertedSpy(m_model, &KFileItemModel::itemsInserted); + QVERIFY(itemsInsertedSpy.isValid()); + QSignalSpy itemsRemovedSpy(m_model, &KFileItemModel::itemsRemoved); + QVERIFY(itemsRemovedSpy.isValid()); + QSignalSpy loadingCompletedSpy(m_model, &KFileItemModel::directoryLoadingCompleted); + QVERIFY(loadingCompletedSpy.isValid()); + + // Test expanding subfolders in a folder with the items "a/", "a/a/" + QSet originalModelRoles = m_model->roles(); + QSet modelRoles = originalModelRoles; + modelRoles << "isExpanded" + << "isExpandable" + << "expandedParentsCount"; + m_model->setRoles(modelRoles); + + m_testDir->createFile("a/b/1"); + + m_model->loadDirectory(m_testDir->url()); + QVERIFY(itemsInsertedSpy.wait()); + + // So far, the model contains only "a/" + QCOMPARE(m_model->count(), 1); + QVERIFY(m_model->isExpandable(0)); + QVERIFY(!m_model->isExpanded(0)); + QVERIFY(m_model->expandedDirectories().empty()); + + QCOMPARE(itemsInsertedSpy.count(), 1); + { + KItemRangeList itemRangeList = itemsInsertedSpy.takeFirst().at(0).value(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 1)); // 1 new item "a/" with index 0 + QCOMPARE(m_model->expandedParentsCount(0), 0); + } + itemsInsertedSpy.clear(); + + // Expand the folder "a/" -> "a/b" become visible + m_model->setExpanded(0, true); + QVERIFY(m_model->isExpanded(0)); + QVERIFY(itemsInsertedSpy.wait()); + QCOMPARE(m_model->count(), 2); // 3 items: "a/", "a/a/" + QCOMPARE(m_model->expandedDirectories(), QSet({QUrl::fromLocalFile(m_testDir->path() + "/a")})); + + QCOMPARE(itemsInsertedSpy.count(), 1); + { + KItemRangeList itemRangeList = itemsInsertedSpy.takeFirst().at(0).value(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(1, 1)); // 1 new item "a/b" with index 1 + QCOMPARE(m_model->expandedParentsCount(1), 1); + } + itemsInsertedSpy.clear(); + + // Expand "a/b" -> "a/b/1" becomes visible + m_model->setExpanded(1, true); + QVERIFY(itemsInsertedSpy.wait()); + QCOMPARE(m_model->expandedDirectories(), QSet({QUrl::fromLocalFile(m_testDir->path() + "/a"), QUrl::fromLocalFile(m_testDir->path() + "/a/b")})); + + QCOMPARE(itemsInsertedSpy.count(), 1); + { + KItemRangeList itemRangeList = itemsInsertedSpy.takeFirst().at(0).value(); + QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(2, 1)); // 1 new item "a/b/1" with index 2 + QCOMPARE(m_model->expandedParentsCount(2), 2); + } + itemsInsertedSpy.clear(); + + // Collapse "a" whilst leaving "b" expanded + m_model->setExpanded(0, false); + + // Insert additional files into "a/b/" + m_testDir->createFile("a/b/2"); + + QVERIFY(!itemsInsertedSpy.wait(5000)); + + QCOMPARE(itemsInModel(), {"a"}); + + m_model->setExpanded(0, true); + ; + QTRY_COMPARE(itemsInModel(), QStringList({"a", "b", "1", "2"})); + + QCOMPARE(m_model->expandedParentsCount(0), 0); // a + QCOMPARE(m_model->expandedParentsCount(1), 1); // a/b + QCOMPARE(m_model->expandedParentsCount(2), 2); // a/b/1 + QCOMPARE(m_model->expandedParentsCount(3), 2); // a/b/2 +} + +void KFileItemModelTest::testCurrentDirRemoved() +{ + m_model->m_dirLister->setAutoUpdate(true); + QSignalSpy currentDirectoryRemovedSpy(m_model, &KFileItemModel::currentDirectoryRemoved); + QVERIFY(currentDirectoryRemovedSpy.isValid()); + QSignalSpy loadingCompletedSpy(m_model, &KFileItemModel::directoryLoadingCompleted); + QVERIFY(loadingCompletedSpy.isValid()); + QSignalSpy dirListerClearSpy(m_model->m_dirLister, &KCoreDirLister::clear); + QVERIFY(dirListerClearSpy.isValid()); + + m_testDir->createFiles({"dir/a.txt", "dir/b.txt"}); + m_model->loadDirectory(QUrl::fromLocalFile(m_testDir->path() + "/dir/")); + QVERIFY(loadingCompletedSpy.wait()); + QCOMPARE(m_model->count(), 2); + QVERIFY(m_model->isConsistent()); + + m_testDir->removeDir("dir"); + QVERIFY(currentDirectoryRemovedSpy.wait()); + + // dirLister calls clear + QCOMPARE(dirListerClearSpy.count(), 2); + QVERIFY(m_model->isConsistent()); + QVERIFY(m_model->m_itemData.isEmpty()); + QCOMPARE(m_model->count(), 0); } QStringList KFileItemModelTest::itemsInModel() const