From: Frank Reininghaus Date: Wed, 1 Feb 2012 20:52:50 +0000 (+0100) Subject: First version of a unit test for KItemListController X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/6db0bec32548fd6c1d742defba5dbf958e61f45c First version of a unit test for KItemListController At the moment, only key press events are tested, and the current item and selection after the event are verified. Moreover, this commit makes sure that KItemListController::keyPressEvent() really does not select anything if the selection mode is NoSelection. (cherry picked from commit 7457f4868cf0bc83e8a90ce5693292378f3d07c4) --- diff --git a/src/kitemviews/kitemlistcontroller.cpp b/src/kitemviews/kitemlistcontroller.cpp index e3210dd22..69320247a 100644 --- a/src/kitemviews/kitemlistcontroller.cpp +++ b/src/kitemviews/kitemlistcontroller.cpp @@ -203,7 +203,8 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } } - const bool selectSingleItem = itemCount == 1 && + const bool selectSingleItem = m_selectionBehavior != NoSelection && + itemCount == 1 && (key == Qt::Key_Home || key == Qt::Key_End || key == Qt::Key_Up || key == Qt::Key_Down || key == Qt::Key_Left || key == Qt::Key_Right); @@ -322,13 +323,15 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } case Qt::Key_Space: - if (controlPressed) { - m_selectionManager->endAnchoredSelection(); - m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); - m_selectionManager->beginAnchoredSelection(index); - } else { - const int current = m_selectionManager->currentItem(); - m_selectionManager->setSelected(current); + if (m_selectionBehavior == MultiSelection) { + if (controlPressed) { + m_selectionManager->endAnchoredSelection(); + m_selectionManager->setSelected(index, 1, KItemListSelectionManager::Toggle); + m_selectionManager->beginAnchoredSelection(index); + } else { + const int current = m_selectionManager->currentItem(); + m_selectionManager->setSelected(current); + } } break; @@ -361,19 +364,33 @@ bool KItemListController::keyPressEvent(QKeyEvent* event) } if (m_selectionManager->currentItem() != index) { - if (controlPressed) { - m_selectionManager->endAnchoredSelection(); - } - - m_selectionManager->setCurrentItem(index); + switch (m_selectionBehavior) { + case NoSelection: + m_selectionManager->setCurrentItem(index); + break; - if (!shiftOrControlPressed || m_selectionBehavior == SingleSelection) { + case SingleSelection: + m_selectionManager->setCurrentItem(index); m_selectionManager->clearSelection(); m_selectionManager->setSelected(index, 1); - } + break; + + case MultiSelection: + if (controlPressed) { + m_selectionManager->endAnchoredSelection(); + } + + m_selectionManager->setCurrentItem(index); + + if (!shiftOrControlPressed) { + m_selectionManager->clearSelection(); + m_selectionManager->setSelected(index, 1); + } - if (!shiftPressed) { - m_selectionManager->beginAnchoredSelection(index); + if (!shiftPressed) { + m_selectionManager->beginAnchoredSelection(index); + } + break; } m_view->scrollToItem(index); diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h index 95215fffd..9c34daba3 100644 --- a/src/kitemviews/kitemlistview.h +++ b/src/kitemviews/kitemlistview.h @@ -513,6 +513,7 @@ private: bool m_useHeaderWidths; friend class KItemListController; + friend class KItemListControllerTest; }; /** diff --git a/src/kitemviews/kitemlistviewlayouter_p.h b/src/kitemviews/kitemlistviewlayouter_p.h index dec99d054..25f8eb6cd 100644 --- a/src/kitemviews/kitemlistviewlayouter_p.h +++ b/src/kitemviews/kitemlistviewlayouter_p.h @@ -161,6 +161,8 @@ private: qreal m_groupHeaderHeight; QList m_itemRects; + + friend class KItemListControllerTest; }; #endif diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index c3360674c..43d1c9bf7 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -12,6 +12,18 @@ set(kitemlistselectionmanagertest_SRCS kde4_add_unit_test(kitemlistselectionmanagertest TEST ${kitemlistselectionmanagertest_SRCS}) target_link_libraries(kitemlistselectionmanagertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) +# KItemListControllerTest +set(kitemlistcontrollertest_SRCS + kitemlistcontrollertest.cpp + testdir.cpp + ../kitemviews/kfileitemmodel.cpp + ../kitemviews/kfileitemlistview.cpp + ../kitemviews/kitemmodelbase.cpp + ../kitemviews/kitemlistview.cpp +) +kde4_add_unit_test(kitemlistcontrollertest TEST ${kitemlistcontrollertest_SRCS}) +target_link_libraries(kitemlistcontrollertest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) + # KFileItemListViewTest set(kfileitemlistviewtest_SRCS kfileitemlistviewtest.cpp diff --git a/src/tests/kitemlistcontrollertest.cpp b/src/tests/kitemlistcontrollertest.cpp new file mode 100644 index 000000000..443faa35f --- /dev/null +++ b/src/tests/kitemlistcontrollertest.cpp @@ -0,0 +1,505 @@ +/*************************************************************************** + * Copyright (C) 2012 by Frank Reininghaus * + * * + * 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 * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include +#include +#include + +#include +#include "kitemviews/kitemlistcontainer.h" +#include "kitemviews/kfileitemlistview.h" +#include "kitemviews/kfileitemmodel.h" +#include "kitemviews/kitemlistcontroller.h" +#include "kitemviews/kitemlistselectionmanager.h" +#include "kitemviews/kitemlistviewlayouter_p.h" +#include "testdir.h" + +namespace { + const int DefaultTimeout = 2000; +}; + +Q_DECLARE_METATYPE(KFileItemListView::Layout); +Q_DECLARE_METATYPE(Qt::Orientation); +Q_DECLARE_METATYPE(KItemListController::SelectionBehavior); + +class KItemListControllerTest : public QObject +{ + Q_OBJECT + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void init(); + void cleanup(); + + void testKeyboardNavigation_data(); + void testKeyboardNavigation(); + +private: + /** + * Make sure that the number of columns in the view is equal to \a count + * by changing the geometry of the container. + */ + void adjustGeometryForColumnCount(int count); + +private: + KFileItemListView* m_view; + KItemListController* m_controller; + KItemListSelectionManager* m_selectionManager; + KFileItemModel* m_model; + KDirLister* m_dirLister; + TestDir* m_testDir; + KItemListContainer* m_container; +}; + +/** + * This function initializes the member objects, creates the temporary files, and + * shows the view on the screen on startup. This could also be done before every + * single test, but this would make the time needed to run the test much larger. + */ +void KItemListControllerTest::initTestCase() +{ + m_testDir = new TestDir(); + m_dirLister = new KDirLister(); + m_model = new KFileItemModel(m_dirLister); + m_container = new KItemListContainer(); + m_controller = m_container->controller(); + m_controller->setSelectionBehavior(KItemListController::MultiSelection); + m_selectionManager = m_controller->selectionManager(); + + m_view = new KFileItemListView(); + m_controller->setView(m_view); + m_controller->setModel(m_model); + + QStringList files; + files + << "a1" << "a2" << "a3" + << "b1" + << "c1" << "c2" << "c3" << "c4" << "c5" + << "d1" << "d2" << "d3" << "d4" + << "e1" << "e2" << "e3" << "e4" << "e5" << "e6" << "e7"; + + m_testDir->createFiles(files); + m_dirLister->openUrl(m_testDir->url()); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(loadingCompleted()), DefaultTimeout)); + + m_container->show(); + QTest::qWaitForWindowShown(m_container); +} + +void KItemListControllerTest::cleanupTestCase() +{ + delete m_view; + m_view = 0; + + delete m_container; + m_container = 0; + m_controller = 0; + + delete m_model; + m_model = 0; + + delete m_dirLister; + m_dirLister = 0; + + delete m_testDir; + m_testDir = 0; +} + +/** Before each test, the current item, selection, and item size are reset to the defaults. */ +void KItemListControllerTest::init() +{ + m_selectionManager->setCurrentItem(0); + QCOMPARE(m_selectionManager->currentItem(), 0); + + m_selectionManager->clearSelection(); + QVERIFY(!m_selectionManager->hasSelection()); + + const QSizeF itemSize(50, 50); + m_view->setItemSize(itemSize); + QCOMPARE(m_view->itemSize(), itemSize); +} + +void KItemListControllerTest::cleanup() +{ +} + +/** + * \class KeyPress is a small helper struct that represents a key press event, + * including the key and the keyboard modifiers. + */ +struct KeyPress { + + KeyPress(Qt::Key key, Qt::KeyboardModifiers modifier = Qt::NoModifier) : + m_key(key), + m_modifier(modifier) + {} + + Qt::Key m_key; + Qt::KeyboardModifiers m_modifier; +}; + +/** + * \class ViewState is a small helper struct that represents a certain state + * of the view, including the current item and the selected items. + */ +struct ViewState { + + ViewState(int current, QSet selection) : + m_current(current), + m_selection(selection) + {} + + int m_current; + QSet m_selection; +}; + +// We have to define a typedef for the pair in order to make the test compile. +typedef QPair keyPressViewStatePair; +Q_DECLARE_METATYPE(QList); + +/** + * This function provides the data for the actual test function + * KItemListControllerTest::testKeyboardNavigation(). + * It tests all possible combinations of view layouts, selection behaviors, + * and enabled/disabled groupings for different column counts, and + * provides a list of key presses and the states that the view should be in + * after the key press event. + */ +void KItemListControllerTest::testKeyboardNavigation_data() +{ + QTest::addColumn("layout"); + QTest::addColumn("scrollOrientation"); + QTest::addColumn("columnCount"); + QTest::addColumn("selectionBehavior"); + QTest::addColumn("groupingEnabled"); + QTest::addColumn > >("testList"); + + static QList layoutList; + static QHash layoutNames; + if (layoutList.isEmpty()) { + layoutList.append(KFileItemListView::IconsLayout); + layoutNames[KFileItemListView::IconsLayout] = "Icons"; + + layoutList.append(KFileItemListView::CompactLayout); + layoutNames[KFileItemListView::CompactLayout] = "Compact"; + + layoutList.append(KFileItemListView::DetailsLayout); + layoutNames[KFileItemListView::DetailsLayout] = "Details"; + } + + static QList selectionBehaviorList; + static QHash selectionBehaviorNames; + if (selectionBehaviorList.isEmpty()) { + selectionBehaviorList.append(KItemListController::NoSelection); + selectionBehaviorNames[KItemListController::NoSelection] = "NoSelection"; + + selectionBehaviorList.append(KItemListController::SingleSelection); + selectionBehaviorNames[KItemListController::SingleSelection] = "SingleSelection"; + + selectionBehaviorList.append(KItemListController::MultiSelection); + selectionBehaviorNames[KItemListController::MultiSelection] = "MultiSelection"; + } + + static QList groupingEnabledList; + static QHash groupingEnabledNames; + if (groupingEnabledList.isEmpty()) { + groupingEnabledList.append(false); + groupingEnabledNames[false] = "ungrouped"; + + groupingEnabledList.append(true); + groupingEnabledNames[true] = "grouping enabled"; + } + + foreach (KFileItemListView::Layout layout, layoutList) { + // The following settings depend on the layout. + // Note that 'columns' are actually 'rows' in + // Compact layout. + Qt::Orientation scrollOrientation; + QList columnCountList; + Qt::Key nextItemKey; + Qt::Key previousItemKey; + Qt::Key nextRowKey; + Qt::Key previousRowKey; + + switch (layout) { + case KFileItemListView::IconsLayout: + scrollOrientation = Qt::Vertical; + columnCountList << 1 << 3 << 5; + nextItemKey = Qt::Key_Right; + previousItemKey = Qt::Key_Left; + nextRowKey = Qt::Key_Down; + previousRowKey = Qt::Key_Up; + break; + case KFileItemListView::CompactLayout: + scrollOrientation = Qt::Horizontal; + columnCountList << 1 << 3 << 5; + nextItemKey = Qt::Key_Down; + previousItemKey = Qt::Key_Up; + nextRowKey = Qt::Key_Right; + previousRowKey = Qt::Key_Left; + break; + case KFileItemListView::DetailsLayout: + scrollOrientation = Qt::Vertical; + columnCountList << 1; + nextItemKey = Qt::Key_Down; + previousItemKey = Qt::Key_Up; + nextRowKey = Qt::Key_Down; + previousRowKey = Qt::Key_Up; + break; + } + + foreach (int columnCount, columnCountList) { + foreach (KItemListController::SelectionBehavior selectionBehavior, selectionBehaviorList) { + foreach (bool groupingEnabled, groupingEnabledList) { + QList > testList; + + // First, key presses which should have the same effect + // for any layout and any number of columns. + testList + << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet() << 2 << 3)) + << qMakePair(KeyPress(previousItemKey), ViewState(3, QSet() << 3)) + << qMakePair(KeyPress(Qt::Key_Home, Qt::ShiftModifier), ViewState(0, QSet() << 0 << 1 << 2 << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(1, QSet() << 0 << 1 << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet() << 0 << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_Space, Qt::ControlModifier), ViewState(1, QSet() << 0 << 1 << 2 << 3)) + << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(18, QSet() << 18 << 19)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + + // Next, we test combinations of key presses which only work for a + // particular number of columns and either enabled or disabled grouping. + + // One column. + if (columnCount == 1) { + testList + << qMakePair(KeyPress(nextRowKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(2, QSet() << 1 << 2)) + << qMakePair(KeyPress(nextRowKey, Qt::ControlModifier), ViewState(3, QSet() << 1 << 2)) + << qMakePair(KeyPress(previousRowKey), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(previousItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + // Multiple columns: we test both 3 and 5 columns with grouping + // enabled or disabled. For each case, the layout of the items + // in the view is shown (both using file names and indices) to + // make it easier to understand what the tests do. + + if (columnCount == 3 && !groupingEnabled) { + // 3 columns, no grouping: + // + // a1 a2 a3 | 0 1 2 + // b1 c1 c2 | 3 4 5 + // c3 c4 c5 | 6 7 8 + // d1 d2 d3 | 9 10 11 + // d4 e1 e2 | 12 13 14 + // e3 e4 e5 | 15 16 17 + // e6 e7 | 18 19 + testList + << qMakePair(KeyPress(nextRowKey), ViewState(3, QSet() << 3)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(4, QSet() << 3)) + << qMakePair(KeyPress(nextRowKey), ViewState(7, QSet() << 7)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(8, QSet() << 7 << 8)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(9, QSet() << 7 << 8 << 9)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(8, QSet() << 7 << 8)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(7, QSet() << 7)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(6, QSet() << 6 << 7)) + << qMakePair(KeyPress(previousItemKey, Qt::ShiftModifier), ViewState(5, QSet() << 5 << 6 << 7)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(6, QSet() << 6 << 7)) + << qMakePair(KeyPress(nextItemKey, Qt::ShiftModifier), ViewState(7, QSet() << 7)) + << qMakePair(KeyPress(nextRowKey), ViewState(10, QSet() << 10)) + << qMakePair(KeyPress(nextItemKey), ViewState(11, QSet() << 11)) + << qMakePair(KeyPress(nextRowKey), ViewState(14, QSet() << 14)) + << qMakePair(KeyPress(nextRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(Qt::Key_End), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(16, QSet() << 16)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + if (columnCount == 5 && !groupingEnabled) { + // 5 columns, no grouping: + // + // a1 a2 a3 b1 c1 | 0 1 2 3 4 + // c2 c3 c4 c5 d1 | 5 6 7 8 9 + // d2 d3 d4 e1 e2 | 10 11 12 13 14 + // e3 e4 e5 e6 e7 | 15 16 17 18 19 + testList + << qMakePair(KeyPress(nextRowKey), ViewState(5, QSet() << 5)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(6, QSet() << 5)) + << qMakePair(KeyPress(nextRowKey), ViewState(11, QSet() << 11)) + << qMakePair(KeyPress(nextItemKey), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(17, QSet() << 12 << 13 << 14 << 15 << 16 << 17)) + << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(7, QSet() << 7 << 8 << 9 << 10 << 11 << 12)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(Qt::Key_End, Qt::ControlModifier), ViewState(19, QSet() << 12)) + << qMakePair(KeyPress(previousRowKey), ViewState(14, QSet() << 14)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + if (columnCount == 3 && groupingEnabled) { + // 3 columns, with grouping: + // + // a1 a2 a3 | 0 1 2 + // b1 | 3 + // c1 c2 c3 | 4 5 6 + // c4 c5 | 7 8 + // d1 d2 d3 | 9 10 11 + // d4 | 12 + // e1 e2 e3 | 13 14 15 + // e4 e5 e6 | 16 17 18 + // e7 | 19 + testList + << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextItemKey), ViewState(2, QSet() << 2)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, QSet() << 2 << 3)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(6, QSet() << 2 << 3 << 4 << 5 << 6)) + << qMakePair(KeyPress(nextRowKey), ViewState(8, QSet() << 8)) + << qMakePair(KeyPress(nextRowKey), ViewState(11, QSet() << 11)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(12, QSet() << 11)) + << qMakePair(KeyPress(nextRowKey), ViewState(13, QSet() << 13)) + << qMakePair(KeyPress(nextRowKey), ViewState(16, QSet() << 16)) + << qMakePair(KeyPress(nextItemKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + if (columnCount == 5 && groupingEnabled) { + // 5 columns, with grouping: + // + // a1 a2 a3 | 0 1 2 + // b1 | 3 + // c1 c2 c3 c4 c5 | 4 5 6 7 8 + // d1 d2 d3 d4 | 9 10 11 12 + // e1 e2 e3 e4 e5 | 13 14 15 16 17 + // e6 e7 | 18 19 + testList + << qMakePair(KeyPress(nextItemKey), ViewState(1, QSet() << 1)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(3, QSet() << 1 << 2 << 3)) + << qMakePair(KeyPress(nextRowKey, Qt::ShiftModifier), ViewState(5, QSet() << 1 << 2 << 3 << 4 << 5)) + << qMakePair(KeyPress(nextItemKey), ViewState(6, QSet() << 6)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(7, QSet() << 6)) + << qMakePair(KeyPress(nextItemKey, Qt::ControlModifier), ViewState(8, QSet() << 6)) + << qMakePair(KeyPress(nextRowKey), ViewState(12, QSet() << 12)) + << qMakePair(KeyPress(nextRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(nextRowKey), ViewState(19, QSet() << 19)) + << qMakePair(KeyPress(previousRowKey), ViewState(17, QSet() << 17)) + << qMakePair(KeyPress(Qt::Key_End, Qt::ShiftModifier), ViewState(19, QSet() << 17 << 18 << 19)) + << qMakePair(KeyPress(previousRowKey, Qt::ShiftModifier), ViewState(14, QSet() << 14 << 15 << 16 << 17)) + << qMakePair(KeyPress(Qt::Key_Home), ViewState(0, QSet() << 0)); + } + + const QString testName = + layoutNames[layout] + ", " + + QString("%1 columns, ").arg(columnCount) + + selectionBehaviorNames[selectionBehavior] + ", " + + groupingEnabledNames[groupingEnabled]; + + const QByteArray testNameAscii = testName.toAscii(); + + QTest::newRow(testNameAscii.data()) + << layout + << scrollOrientation + << columnCount + << selectionBehavior + << groupingEnabled + << testList; + } + } + } + } +} + +/** + * This function sets the view's properties according to the data provided by + * KItemListControllerTest::testKeyboardNavigation_data(). + * + * The list \a testList contains pairs of key presses, which are sent to the + * container, and expected view states, which are verified then. + */ +void KItemListControllerTest::testKeyboardNavigation() +{ + QFETCH(KFileItemListView::Layout, layout); + QFETCH(Qt::Orientation, scrollOrientation); + QFETCH(int, columnCount); + QFETCH(KItemListController::SelectionBehavior, selectionBehavior); + QFETCH(bool, groupingEnabled); + QFETCH(QList, testList); + + m_view->setItemLayout(layout); + QCOMPARE(m_view->itemLayout(), layout); + + m_view->setScrollOrientation(scrollOrientation); + QCOMPARE(m_view->scrollOrientation(), scrollOrientation); + + adjustGeometryForColumnCount(columnCount); + QCOMPARE(m_view->m_layouter->m_columnCount, columnCount); + + m_controller->setSelectionBehavior(selectionBehavior); + QCOMPARE(m_controller->selectionBehavior(), selectionBehavior); + + m_model->setGroupedSorting(groupingEnabled); + QCOMPARE(m_model->groupedSorting(), groupingEnabled); + + while (!testList.isEmpty()) { + const QPair test = testList.takeFirst(); + const Qt::Key key = test.first.m_key; + const Qt::KeyboardModifiers modifier = test.first.m_modifier; + const int current = test.second.m_current; + const QSet selection = test.second.m_selection; + + QTest::keyClick(m_container, key, modifier); + QCOMPARE(m_selectionManager->currentItem(), current); + switch (selectionBehavior) { + case KItemListController::NoSelection: QVERIFY(m_selectionManager->selectedItems().isEmpty()); break; + case KItemListController::SingleSelection: QCOMPARE(m_selectionManager->selectedItems(), QSet() << current); break; + case KItemListController::MultiSelection: QCOMPARE(m_selectionManager->selectedItems(), selection); break; + } + } +} + +void KItemListControllerTest::adjustGeometryForColumnCount(int count) +{ + const QSize size = m_view->itemSize().toSize(); + + QRect rect = m_container->geometry(); + rect.setSize(size * count); + m_container->setGeometry(rect); + + // Increase the size of the container until the correct column count is reached. + while (m_view->m_layouter->m_columnCount < count) { + rect = m_container->geometry(); + rect.setSize(rect.size() + size); + m_container->setGeometry(rect); + } +} + +QTEST_KDEMAIN(KItemListControllerTest, GUI) + +#include "kitemlistcontrollertest.moc"