]> cloud.milkyroute.net Git - dolphin.git/blobdiff - src/tests/kfileitemmodeltest.cpp
KItemListKeyboardSearchManager improvements and unit tests
[dolphin.git] / src / tests / kfileitemmodeltest.cpp
index 0e40b3bc44343f1901ca2a22b997802cc1916ce7..f8398c57816b07726f9f93bcd261c510c6d7d0a4 100644 (file)
@@ -1,5 +1,6 @@
 /***************************************************************************
  *   Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com>             *
+ *   Copyright (C) 2011 by Frank Reininghaus <frank78ac@googlemail.com>    *
  *                                                                         *
  *   This program is free software; you can redistribute it and/or modify  *
  *   it under the terms of the GNU General Public License as published by  *
@@ -41,12 +42,16 @@ private slots:
     void testDefaultSortRole();
     void testDefaultGroupRole();
     void testNewItems();
+    void testRemoveItems();
     void testModelConsistencyWhenInsertingItems();
     void testItemRangeConsistencyWhenInsertingItems();
+    void testExpandItems();
 
     void testExpansionLevelsCompare_data();
     void testExpansionLevelsCompare();
 
+    void testIndexForKeyboardSearch();
+
 private:
     bool isModelConsistent() const;
 
@@ -123,6 +128,19 @@ void KFileItemModelTest::testNewItems()
     QVERIFY(isModelConsistent());
 }
 
+void KFileItemModelTest::testRemoveItems()
+{
+    m_testDir->createFile("a.txt");
+    m_dirLister->openUrl(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(m_model->count(), 1);
+
+    m_testDir->removeFile("a.txt");
+    m_dirLister->updateDirectory(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsRemoved(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(m_model->count(), 0);
+}
+
 void KFileItemModelTest::testModelConsistencyWhenInsertingItems()
 {
     QSKIP("Temporary disabled", SkipSingle);
@@ -182,10 +200,7 @@ void KFileItemModelTest::testItemRangeConsistencyWhenInsertingItems()
     QCOMPARE(spy1.count(), 1);
     QList<QVariant> arguments = spy1.takeFirst();
     KItemRangeList itemRangeList = arguments.at(0).value<KItemRangeList>();
-    QCOMPARE(itemRangeList.count(), 1);
-    KItemRange itemRange = itemRangeList.first();
-    QCOMPARE(itemRange.index, 0);
-    QCOMPARE(itemRange.count, 3);
+    QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 3));
 
     // The indexes of the item-ranges must always be related to the model before
     // the items have been inserted. Having:
@@ -210,13 +225,83 @@ void KFileItemModelTest::testItemRangeConsistencyWhenInsertingItems()
     QCOMPARE(spy2.count(), 1);
     arguments = spy2.takeFirst();
     itemRangeList = arguments.at(0).value<KItemRangeList>();
-    QCOMPARE(itemRangeList.count(), 3);
-    QCOMPARE(itemRangeList.at(0).index, 0);
-    QCOMPARE(itemRangeList.at(0).count, 1);
-    QCOMPARE(itemRangeList.at(1).index, 1);
-    QCOMPARE(itemRangeList.at(1).count, 2);
-    QCOMPARE(itemRangeList.at(2).index, 2);
-    QCOMPARE(itemRangeList.at(2).count, 1);
+    QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(0, 1) << KItemRange(1, 2) << KItemRange(2, 1));
+}
+
+void KFileItemModelTest::testExpandItems()
+{
+    // Test expanding subfolders in a folder with the items "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1".
+    // Besides testing the basic item expansion functionality, the test makes sure that
+    // KFileItemModel::expansionLevelsCompare(const KFileItem& a, const KFileItem& b)
+    // yields the correct result for "a/a/1" and "a/a-1/", whis is non-trivial because they share the
+    // first three characters.
+    QSet<QByteArray> modelRoles = m_model->roles();
+    modelRoles << "isExpanded" << "expansionLevel";
+    m_model->setRoles(modelRoles);
+
+    QStringList files;
+    files << "a/a/1" << "a/a-1/1"; // missing folders are created automatically
+    m_testDir->createFiles(files);
+
+    m_dirLister->openUrl(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+
+    // So far, the model contains only "a/"
+    QCOMPARE(m_model->count(), 1);
+    QVERIFY(m_model->isExpandable(0));
+    QVERIFY(!m_model->isExpanded(0));
+
+    QSignalSpy spyInserted(m_model, SIGNAL(itemsInserted(KItemRangeList)));
+
+    // Expand the folder "a/" -> "a/a/" and "a/a-1/" become visible
+    m_model->setExpanded(0, true);
+    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(spyInserted.count(), 1);
+    KItemRangeList itemRangeList = spyInserted.takeFirst().at(0).value<KItemRangeList>();
+    QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(1, 2)); // 2 new items "a/a/" and "a/a-1/" with indices 1 and 2
+
+    QVERIFY(m_model->isExpandable(1));
+    QVERIFY(!m_model->isExpanded(1));
+    QVERIFY(m_model->isExpandable(2));
+    QVERIFY(!m_model->isExpanded(2));
+
+    // Expand the folder "a/a/" -> "a/a/1" becomes visible
+    m_model->setExpanded(1, true);
+    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(spyInserted.count(), 1);
+    itemRangeList = spyInserted.takeFirst().at(0).value<KItemRangeList>();
+    QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(2, 1)); // 1 new item "a/a/1" with index 2
+
+    QVERIFY(!m_model->isExpandable(2));
+    QVERIFY(!m_model->isExpanded(2));
+
+    // Expand the folder "a/a-1/" -> "a/a-1/1" becomes visible
+    m_model->setExpanded(3, true);
+    QVERIFY(m_model->isExpanded(3));
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+    QCOMPARE(m_model->count(), 5);  // 4 items: "a/", "a/a/", "a/a/1", "a/a-1/", "a/a-1/1"
+
+    QCOMPARE(spyInserted.count(), 1);
+    itemRangeList = spyInserted.takeFirst().at(0).value<KItemRangeList>();
+    QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(4, 1)); // 1 new item "a/a-1/1" with index 4
+
+    QVERIFY(!m_model->isExpandable(4));
+    QVERIFY(!m_model->isExpanded(4));
+
+    QSignalSpy spyRemoved(m_model, SIGNAL(itemsRemoved(KItemRangeList)));
+
+    // Collapse the top-level folder -> all other items should disappear
+    m_model->setExpanded(0, false);
+    QVERIFY(!m_model->isExpanded(0));
+    QCOMPARE(spyRemoved.count(), 1);
+    itemRangeList = spyRemoved.takeFirst().at(0).value<KItemRangeList>();
+    QCOMPARE(itemRangeList, KItemRangeList() << KItemRange(1, 4)); // 4 items removed
 }
 
 void KFileItemModelTest::testExpansionLevelsCompare_data()
@@ -229,6 +314,9 @@ void KFileItemModelTest::testExpansionLevelsCompare_data()
     QTest::newRow("Sub path: A < B") << "/a/b" << "/a/b/c" << -1;
     QTest::newRow("Sub path: A > B") << "/a/b/c" << "/a/b" << +1;
     QTest::newRow("Same level: /a/1 < /a-1/1") << "/a/1" << "/a-1/1" << -1;
+    QTest::newRow("Same level: /a-/1 > /a/1") << "/a-1/1" << "/a/1" << +1;
+    QTest::newRow("Different levels: /a/a/1 < /a/a-1") << "/a/a/1" << "/a/a-1" << -1;
+    QTest::newRow("Different levels: /a/a-1 > /a/a/1") << "/a/a-1" << "/a/a/1" << +1;
 }
 
 void KFileItemModelTest::testExpansionLevelsCompare()
@@ -242,6 +330,56 @@ void KFileItemModelTest::testExpansionLevelsCompare()
     QCOMPARE(m_model->expansionLevelsCompare(a, b), result);
 }
 
+void KFileItemModelTest::testIndexForKeyboardSearch()
+{
+    QStringList files;
+    files << "a" << "aa" << "Image.jpg" << "Image.png" << "Text" << "Text1" << "Text2" << "Text11";
+    m_testDir->createFiles(files);
+
+    m_dirLister->openUrl(m_testDir->url());
+    QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout));
+
+    // Search from index 0
+    QCOMPARE(m_model->indexForKeyboardSearch("a", 0), 0);
+    QCOMPARE(m_model->indexForKeyboardSearch("aa", 0), 1);
+    QCOMPARE(m_model->indexForKeyboardSearch("i", 0), 2);
+    QCOMPARE(m_model->indexForKeyboardSearch("image", 0), 2);
+    QCOMPARE(m_model->indexForKeyboardSearch("image.jpg", 0), 2);
+    QCOMPARE(m_model->indexForKeyboardSearch("image.png", 0), 3);
+    QCOMPARE(m_model->indexForKeyboardSearch("t", 0), 4);
+    QCOMPARE(m_model->indexForKeyboardSearch("text", 0), 4);
+    QCOMPARE(m_model->indexForKeyboardSearch("text1", 0), 5);
+    QCOMPARE(m_model->indexForKeyboardSearch("text2", 0), 6);
+    QCOMPARE(m_model->indexForKeyboardSearch("text11", 0), 7);
+
+    // Start a search somewhere in the middle
+    QCOMPARE(m_model->indexForKeyboardSearch("a", 1), 1);
+    QCOMPARE(m_model->indexForKeyboardSearch("i", 3), 3);
+    QCOMPARE(m_model->indexForKeyboardSearch("t", 5), 5);
+    QCOMPARE(m_model->indexForKeyboardSearch("text1", 6), 7);
+
+    // Test searches that go past the last item back to index 0
+    QCOMPARE(m_model->indexForKeyboardSearch("a", 2), 0);
+    QCOMPARE(m_model->indexForKeyboardSearch("i", 7), 2);
+    QCOMPARE(m_model->indexForKeyboardSearch("image.jpg", 3), 2);
+    QCOMPARE(m_model->indexForKeyboardSearch("text2", 7), 6);
+
+    // Test searches that yield no result
+    QCOMPARE(m_model->indexForKeyboardSearch("aaa", 0), -1);
+    QCOMPARE(m_model->indexForKeyboardSearch("b", 0), -1);
+    QCOMPARE(m_model->indexForKeyboardSearch("image.svg", 0), -1);
+    QCOMPARE(m_model->indexForKeyboardSearch("text3", 0), -1);
+    QCOMPARE(m_model->indexForKeyboardSearch("text3", 5), -1);
+
+    // Test upper case searches (note that search is case insensitive)
+    QCOMPARE(m_model->indexForKeyboardSearch("A", 0), 0);
+    QCOMPARE(m_model->indexForKeyboardSearch("aA", 0), 1);
+    QCOMPARE(m_model->indexForKeyboardSearch("TexT", 5), 5);
+    QCOMPARE(m_model->indexForKeyboardSearch("IMAGE", 4), 2);
+
+    // TODO: Maybe we should also test keyboard searches in directories which are not sorted by Name?
+}
+
 bool KFileItemModelTest::isModelConsistent() const
 {
     for (int i = 0; i < m_model->count(); ++i) {