Commit c681a2f6 authored by Laurent Montel's avatar Laurent Montel 😁

Add unit tests for Folder View

Summary: Add some tests for FolderModel and Positioner classes.

Reviewers: #plasma, ervin, hein, mlaurent, aacid, dvratil, franckarrecot, renatoo, olivierjg

Reviewed By: #plasma, hein, mlaurent

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D8447
parent c6702fac
include(GenerateExportHeader)
if(BUILD_TESTING)
add_definitions(-DBUILD_TESTING)
endif(BUILD_TESTING)
set(folderplugin_SRCS
directorypicker.cpp
foldermodel.cpp
......@@ -32,3 +38,9 @@ target_link_libraries(folderplugin
KF5::ConfigGui)
install(TARGETS folderplugin DESTINATION ${QML_INSTALL_DIR}/org/kde/private/desktopcontainment/folder)
generate_export_header(folderplugin BASE_NAME folderplugin)
if(BUILD_TESTING)
add_subdirectory(tests)
endif(BUILD_TESTING)
......@@ -37,6 +37,8 @@
#include <KNewFileMenu>
#include "folderplugin_private_export.h"
class QDrag;
class QItemSelectionModel;
class QQuickItem;
......@@ -69,7 +71,7 @@ class DirLister : public KDirLister
void handleError(KIO::Job *job) Q_DECL_OVERRIDE;
};
class FolderModel : public QSortFilterProxyModel
class FOLDERPLUGIN_TESTS_EXPORT FolderModel : public QSortFilterProxyModel
{
Q_OBJECT
......
/***************************************************************************
* Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company *
* <info@kdab.com> *
* Author: Andras Mantia <andras.mantia@kdab.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 *
* 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 . *
***************************************************************************/
#ifndef FOLDERPLUGIN_PRIVATE_EXPORT_H
#define FOLDERPLUGIN_PRIVATE_EXPORT_H
#include "folderplugin_export.h"
/* Classes which are exported only for unit tests */
#ifdef BUILD_TESTING
#ifndef FOLDERPLUGIN_TESTS_EXPORT
#define FOLDERPLUGIN_TESTS_EXPORT FOLDERPLUGIN_EXPORT
#endif
#else /* not compiling tests */
#endif
#endif // FOLDERPLUGIN_PRIVATE_EXPORT_H
......@@ -22,11 +22,13 @@
#include <QAbstractItemModel>
#include "folderplugin_private_export.h"
class FolderModel;
class QTimer;
class Positioner : public QAbstractItemModel
class FOLDERPLUGIN_TESTS_EXPORT Positioner : public QAbstractItemModel
{
Q_OBJECT
......
find_package(Qt5 ${REQUIRED_QT_VERSION} CONFIG REQUIRED Test)
include(ECMAddTests)
include_directories("..";${include_directories})
ecm_add_tests(
foldermodeltest.cpp
positionertest.cpp
LINK_LIBRARIES Qt5::Test folderplugin
)
/***************************************************************************
* Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company *
* <info@kdab.com> *
* Author: Andras Mantia <andras.mantia@kdab.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 *
* 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 "foldermodeltest.h"
#include "foldermodel.h"
#include <QTest>
#include <QTemporaryDir>
#include <QSignalSpy>
QTEST_MAIN(FolderModelTest)
static const QLatin1String desktop(QLatin1String("Desktop"));
void FolderModelTest::initTestCase()
{
m_folderDir = new QTemporaryDir();
QDir dir(m_folderDir->path());
dir.mkdir(desktop);
dir.cd(desktop);
dir.mkdir("firstDir");
QFile f;
for (int i = 1; i < 10; i++) {
f.setFileName(QStringLiteral("%1/file%2.txt").arg(dir.path(), QString::number(i)));
f.open(QFile::WriteOnly);
f.close();
}
}
void FolderModelTest::cleanupTestCase()
{
delete m_folderDir;
}
void FolderModelTest::init()
{
m_folderModel = new FolderModel(this);
m_folderModel->setUrl(m_folderDir->path() + QDir::separator() + desktop );
QSignalSpy s(m_folderModel, &FolderModel::listingCompleted);
s.wait(1000);
}
void FolderModelTest::cleanup()
{
delete m_folderModel;
m_folderModel = nullptr;
}
void FolderModelTest::tst_listing()
{
QCOMPARE(m_folderModel->url(), m_folderDir->path() + QDir::separator() + desktop);
const auto count = m_folderModel->rowCount();
QCOMPARE(count, 10);
QCOMPARE(m_folderModel->index(0, 0).data(FolderModel::FileNameRole).toString(),
QLatin1String("firstDir"));
for (int i = 1; i < count; i++) {
const auto index = m_folderModel->index(i, 0);
QCOMPARE(index.data(FolderModel::FileNameRole).toString(),
QStringLiteral("file%1.txt").arg(i));
}
}
void FolderModelTest::tst_listingDescending()
{
m_folderModel->setSortDesc(true);
QCOMPARE(m_folderModel->index(0, 0).data(FolderModel::FileNameRole).toString(),
QLatin1String("firstDir"));
const auto count = m_folderModel->rowCount();
for (int i = 1; i < count; i++) {
const auto index = m_folderModel->index(i, 0);
QCOMPARE(index.data(FolderModel::FileNameRole).toString(),
QStringLiteral("file%1.txt").arg(count - i));
}
}
void FolderModelTest::tst_listingFolderNotFirst()
{
const auto count = m_folderModel->rowCount();
m_folderModel->setSortDirsFirst(false);
QCOMPARE(count, 10);
QCOMPARE(m_folderModel->index(9, 0).data(FolderModel::FileNameRole).toString(),
QLatin1String("firstDir"));
for (int i = 0; i < count - 1; i++) {
const auto index = m_folderModel->index(i, 0);
QCOMPARE(index.data(FolderModel::FileNameRole).toString(),
QStringLiteral("file%1.txt").arg(i + 1));
}
}
void FolderModelTest::tst_filterListing()
{
// a little bit weird API, as both pattern and mimetype needs to be set
m_folderModel->setFilterPattern("*.txt");
m_folderModel->setFilterMimeTypes({"all/all"});
m_folderModel->setFilterMode(FolderModel::FilterShowMatches);
const auto count = m_folderModel->rowCount();
QCOMPARE(count, 9);
for (int i = 0; i < count; i++) {
const auto index = m_folderModel->index(i, 0);
QCOMPARE(index.data(FolderModel::FileNameRole).toString(),
QStringLiteral("file%1.txt").arg(i + 1));
}
}
void FolderModelTest::tst_cd()
{
QSignalSpy s(m_folderModel, &FolderModel::listingCompleted);
//go into firstDir subfolder
const auto url = m_folderModel->resolvedUrl();
m_folderModel->cd(0);
QVERIFY(s.wait(500));
const auto url2 = m_folderModel->resolvedUrl();
QVERIFY(url.isParentOf(url2));
//go back to Desktop
m_folderModel->up();
QVERIFY(s.wait(500));
QCOMPARE(m_folderModel->resolvedUrl(), url);
//try to cd to an invalid entry (a file)
m_folderModel->cd(1);
//Signal is not emitted here as it's invalided
QVERIFY(!s.wait(500));
QCOMPARE(m_folderModel->resolvedUrl(), url);
}
void FolderModelTest::tst_rename_data()
{
QTest::addColumn<int>("row");
QTest::addColumn<QString>("name");
QTest::newRow("Folder rename") << 0 << "firstDirRenamed";
QTest::newRow("File rename") << 1 << "file1.pdf";
QTest::newRow("Invalid rename") << 11 << "foo";
}
void FolderModelTest::tst_rename()
{
QFETCH(int, row);
QFETCH(QString, name);
m_folderModel->rename(row, name);
QSignalSpy s(m_folderModel, &FolderModel::listingCompleted);
const auto index = m_folderModel->index(row, 0);
s.wait(500);
QEXPECT_FAIL("Invalid rename", "This is expected to fail", Continue);
QCOMPARE(index.data(FolderModel::FileNameRole).toString(), name);
}
void FolderModelTest::tst_selection()
{
m_folderModel->setSelected(1);
QVERIFY(m_folderModel->hasSelection());
QVERIFY(m_folderModel->isSelected(1));
m_folderModel->clearSelection();
QVERIFY(!m_folderModel->hasSelection());
m_folderModel->toggleSelected(1);
QVERIFY(m_folderModel->isSelected(1));
m_folderModel->toggleSelected(1);
QVERIFY(!m_folderModel->isSelected(1));
m_folderModel->setRangeSelected(1, 4);
QVERIFY(m_folderModel->hasSelection());
for (int i = 1; i <= 4; i++) {
QVERIFY(m_folderModel->isSelected(i));
}
m_folderModel->updateSelection({5, 6}, false);
for (int i = 1; i <= 4; i++) {
QVERIFY(!m_folderModel->isSelected(i));
}
QVERIFY(m_folderModel->isSelected(5));
QVERIFY(m_folderModel->isSelected(6));
m_folderModel->setRangeSelected(1, 4);
m_folderModel->pinSelection();
m_folderModel->updateSelection({5, 6}, true);
for (int i = 1; i <= 6; i++) {
QVERIFY(m_folderModel->isSelected(i));
}
m_folderModel->unpinSelection();
m_folderModel->updateSelection({5, 6}, true);
for (int i = 1; i <= 6; i++) {
if (i < 5) {
QVERIFY(!m_folderModel->isSelected(i));
} else {
QVERIFY(m_folderModel->isSelected(i));
}
}
}
void FolderModelTest::tst_defaultValues()
{
FolderModel folderModel;
QCOMPARE(folderModel.status(), FolderModel::Status::None);
QVERIFY(folderModel.locked());
QVERIFY(!folderModel.sortDesc());
QVERIFY(folderModel.sortDirsFirst());
QVERIFY(!folderModel.parseDesktopFiles());
QVERIFY(!folderModel.previews());
QVERIFY(!folderModel.usedByContainment());
QCOMPARE(folderModel.sortMode(), 0);
QCOMPARE(folderModel.filterMode(), (int)FolderModel::NoFilter);
QVERIFY(folderModel.newMenu());
}
void FolderModelTest::tst_actionMenu()
{
const QStringList lst {
QStringLiteral("open"),
QStringLiteral("cut"),
QStringLiteral("open"),
QStringLiteral("cut"),
QStringLiteral("undo"),
QStringLiteral("copy"),
QStringLiteral("paste"),
QStringLiteral("pasteto"),
QStringLiteral("reload"),
QStringLiteral("refresh"),
QStringLiteral("rename"),
QStringLiteral("trash"),
QStringLiteral("del"),
QStringLiteral("restoreFromTrash"),
QStringLiteral("emptyTrash")
};
for (const QString &str : lst) {
QVERIFY(m_folderModel->action(str));
}
}
void FolderModelTest::tst_lockedChanged()
{
QSignalSpy s(m_folderModel, &FolderModel::lockedChanged);
m_folderModel->setLocked(false);
QCOMPARE(s.count(), 1);
m_folderModel->setLocked(false);
QCOMPARE(s.count(), 1);
m_folderModel->setLocked(true);
QCOMPARE(s.count(), 2);
}
/***************************************************************************
* Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company *
* <info@kdab.com> *
* Author: Andras Mantia <andras.mantia@kdab.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 *
* 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 . *
***************************************************************************/
#ifndef FOLDERMODELTEST_H
#define FOLDERMODELTEST_H
#include <QObject>
class QTemporaryDir;
class FolderModel;
class FolderModelTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
void tst_listing();
void tst_listingDescending();
void tst_listingFolderNotFirst();
void tst_filterListing();
void tst_cd();
void tst_rename_data();
void tst_rename();
void tst_selection();
void tst_defaultValues();
void tst_actionMenu();
void tst_lockedChanged();
private:
FolderModel *m_folderModel;
QTemporaryDir *m_folderDir;
};
#endif // FOLDERMODELTEST_H
/***************************************************************************
* Copyright (C) 2017 Klarälvdalens Datakonsult AB, a KDAB Group company *
* <info@kdab.com> *
* Author: Andras Mantia <andras.mantia@kdab.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 *
* 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 "positionertest.h"
#include <QTest>
#include <QTest>
#include <QTemporaryDir>
#include <QSignalSpy>
#include "foldermodel.h"
#include "positioner.h"
QTEST_MAIN(PositionerTest)
static const QLatin1String desktop(QLatin1String("Desktop"));
void PositionerTest::initTestCase()
{
m_folderDir = new QTemporaryDir();
QDir dir(m_folderDir->path());
dir.mkdir(desktop);
dir.cd(desktop);
dir.mkdir("firstDir");
QFile f;
for (int i = 1; i < 10; i++) {
f.setFileName(QStringLiteral("%1/file%2.txt").arg(dir.path(), QString::number(i)));
f.open(QFile::WriteOnly);
f.close();
}
}
void PositionerTest::cleanupTestCase()
{
delete m_folderDir;
}
void PositionerTest::init()
{
m_folderModel = new FolderModel(this);
m_positioner = new Positioner(this);
m_positioner->setEnabled(true);
m_positioner->setFolderModel(m_folderModel);
m_positioner->setPerStripe(3);
m_folderModel->setUrl(m_folderDir->path() + QDir::separator() + desktop );
QSignalSpy s(m_folderModel, &FolderModel::listingCompleted);
s.wait(1000);
}
void PositionerTest::cleanup()
{
delete m_folderModel;
m_folderModel = nullptr;
delete m_positioner;
m_positioner = nullptr;
}
void PositionerTest::tst_positions_data()
{
QTest::addColumn<int>("perStripe");
QTest::newRow("3 per column") << 3;
QTest::newRow("5 per column") << 5;
}
void PositionerTest::tst_positions()
{
QFETCH(int, perStripe);
m_positioner->setPerStripe(perStripe);
checkPositions(perStripe);
}
void PositionerTest::tst_map()
{
//by default the mapping is 1-1
for (int i = 0; i < m_positioner->rowCount(); i++) {
QCOMPARE(m_positioner->map(i), i);
}
}
void PositionerTest::tst_move_data()
{
QTest::addColumn<QVariantList>("moves");
QTest::addColumn<QVector<int> >("result");
QTest::newRow("First to last") << QVariantList({0, 10})
<< QVector<int>({-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0});
QTest::newRow("First to after last") << QVariantList({0, 11})
<< QVector<int>({-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, 0});
QTest::newRow("Switch 2nd with 3rd ") << QVariantList({1, 2, 2, 1})
<< QVector<int>({0, 2, 1, 3, 4, 5, 6, 7, 8, 9});
QTest::newRow("Switch 2nd with 2nd ") << QVariantList({1, 1, 1, 1})
<< QVector<int>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9});
QTest::newRow("2nd to last") << QVariantList({2, 10})
<< QVector<int>({0, 1, -1, 3, 4, 5, 6, 7, 8, 9, 2});
}
void PositionerTest::tst_move()
{
QFETCH(QVariantList, moves);
QFETCH(QVector<int>, result);
m_positioner->move(moves);
for (int i = 0; i < m_positioner->rowCount(); i++) {
QCOMPARE(m_positioner->map(i), result[i]);
}
}
void PositionerTest::tst_nearestitem_data()
{
QTest::addColumn<int>("index");
QTest::addColumn<QVector<int> >("result");
QTest::newRow("Around first") << 0 << QVector<int>{-1, -1, 3, -1, 1};
QTest::newRow("Around second") << 1 << QVector<int>{-1, -1, 4, 0, 2};
QTest::newRow("Around 5th") << 4 << QVector<int>{-1, 1, 7, 3, 5};
QTest::newRow("Around last") << 9 << QVector<int>{-1, 6, -1, -1, 7};
QTest::newRow("Around invalid") << 11 << QVector<int>{-1, -1, -1, -1, -1};
}
void PositionerTest::tst_nearestitem()
{
QFETCH(int, index);
QFETCH(QVector<int>, result);
for (int i = Qt::NoArrow; i <= Qt::RightArrow; i++) {
QCOMPARE(m_positioner->nearestItem(index, (Qt::ArrowType)i), result[i]);
}
}
void PositionerTest::tst_isBlank()
{
QCOMPARE(m_positioner->isBlank(0), false);
QCOMPARE(m_positioner->isBlank(11), true);
m_positioner->move({0, 10});
QCOMPARE(m_positioner->isBlank(0), true);
}
void PositionerTest::tst_reset()
{
m_positioner->move({0, 10});
m_positioner->reset();