File indexing completed on 2025-01-05 05:00:00

0001 /*
0002  * SPDX-FileCopyrightText: 2014 Kevin Ottens <ervin@kde.org>
0003  SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0004 */
0005 
0006 
0007 #include <testlib/qtest_zanshin.h>
0008 
0009 #include <QStandardItemModel>
0010 
0011 #include "domain/task.h"
0012 
0013 #include "presentation/querytreemodelbase.h"
0014 #include "presentation/taskfilterproxymodel.h"
0015 #include "utils/datetime.h"
0016 
0017 Q_DECLARE_METATYPE(QList<QStandardItem*>)
0018 
0019 class TaskFilterProxyModelTest : public QObject
0020 {
0021     Q_OBJECT
0022 private:
0023     QStandardItem *createTaskItem(const QString &title, const QString &text,
0024                                   const QDate &start = QDate(),
0025                                   const QDate &due = QDate(),
0026                   bool done = false) const
0027     {
0028         auto task = Domain::Task::Ptr::create();
0029         task->setTitle(title);
0030         task->setText(text);
0031         task->setStartDate(start);
0032         task->setDueDate(due);
0033     task->setDone(done);
0034 
0035         auto item = new QStandardItem;
0036         item->setData(task->title(), Qt::DisplayRole);
0037         item->setData(QVariant::fromValue(task),
0038                       Presentation::QueryTreeModelBase::ObjectRole);
0039         return item;
0040     }
0041 
0042 private slots:
0043     void initTestCase()
0044     {
0045         qputenv("ZANSHIN_OVERRIDE_DATE", "2015-03-11");
0046     }
0047 
0048     void shouldHaveDefaultState()
0049     {
0050         Presentation::TaskFilterProxyModel proxy;
0051         QVERIFY(!proxy.sourceModel());
0052         QCOMPARE(proxy.sortColumn(), 0);
0053         QCOMPARE(proxy.sortOrder(), Qt::AscendingOrder);
0054         QCOMPARE(proxy.sortType(), Presentation::TaskFilterProxyModel::TitleSort);
0055         QCOMPARE(proxy.sortCaseSensitivity(), Qt::CaseInsensitive);
0056     QVERIFY(!proxy.showDoneTasks());
0057         QVERIFY(!proxy.showFutureTasks());
0058     }
0059 
0060     void shouldFilterByTextAndTitle()
0061     {
0062         // GIVEN
0063         QStandardItemModel input;
0064         input.appendRow(createTaskItem(QStringLiteral("1. foo"), QStringLiteral("find me")));
0065         input.appendRow(createTaskItem(QStringLiteral("2. Find Me"), QStringLiteral("bar")));
0066         input.appendRow(createTaskItem(QStringLiteral("3. baz"), QStringLiteral("baz")));
0067 
0068         Presentation::TaskFilterProxyModel output;
0069         output.setSourceModel(&input);
0070 
0071         // WHEN
0072         output.setFilterRegularExpression(QStringLiteral("find me"));
0073 
0074         // THEN
0075         QCOMPARE(output.rowCount(), 2);
0076         QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. foo"));
0077         QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. Find Me"));
0078     }
0079 
0080     void shouldFilterByDoneState()
0081     {
0082         // GIVEN
0083         QStandardItemModel input;
0084         const auto today = Utils::DateTime::currentDate();
0085         input.appendRow(createTaskItem(QStringLiteral("1. Done"), QString(), today.addDays(-1), today, true));
0086         input.appendRow(createTaskItem(QStringLiteral("2. Done"), QString(), today, QDate(), true));
0087         input.appendRow(createTaskItem(QStringLiteral("3. Not Done"), QString(), today));
0088         input.appendRow(createTaskItem(QStringLiteral("4. Not Done"), QString()));
0089 
0090         Presentation::TaskFilterProxyModel output;
0091         output.setSourceModel(&input);
0092 
0093         // WHEN
0094         output.setShowDoneTasks(true);
0095 
0096         // THEN
0097         QCOMPARE(output.rowCount(), 4);
0098         QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. Done"));
0099         QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. Done"));
0100         QCOMPARE(output.index(2, 0).data().toString(), QStringLiteral("3. Not Done"));
0101         QCOMPARE(output.index(3, 0).data().toString(), QStringLiteral("4. Not Done"));
0102 
0103         // WHEN
0104         output.setShowDoneTasks(false);
0105 
0106         // THEN
0107         QCOMPARE(output.rowCount(), 2);
0108         QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("3. Not Done"));
0109         QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("4. Not Done"));
0110     }
0111 
0112     void shouldFilterByStartDate()
0113     {
0114         // GIVEN
0115         QStandardItemModel input;
0116         const auto today = Utils::DateTime::currentDate();
0117         input.appendRow(createTaskItem(QStringLiteral("1. past"), QString(), today.addDays(-1)));
0118         input.appendRow(createTaskItem(QStringLiteral("2. present"), QString(), today));
0119         input.appendRow(createTaskItem(QStringLiteral("3. future"), QString(), today.addDays(1)));
0120         input.appendRow(createTaskItem(QStringLiteral("4. whatever"), QString()));
0121 
0122         Presentation::TaskFilterProxyModel output;
0123         output.setSourceModel(&input);
0124 
0125         // WHEN
0126         output.setShowFutureTasks(true);
0127 
0128         // THEN
0129         QCOMPARE(output.rowCount(), 4);
0130         QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. past"));
0131         QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. present"));
0132         QCOMPARE(output.index(2, 0).data().toString(), QStringLiteral("3. future"));
0133         QCOMPARE(output.index(3, 0).data().toString(), QStringLiteral("4. whatever"));
0134 
0135         // WHEN
0136         output.setShowFutureTasks(false);
0137 
0138         // THEN
0139         QCOMPARE(output.rowCount(), 3);
0140         QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. past"));
0141         QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. present"));
0142         QCOMPARE(output.index(2, 0).data().toString(), QStringLiteral("4. whatever"));
0143     }
0144 
0145     void shouldKeepRowIfItHasAcceptableChildren()
0146     {
0147         // GIVEN
0148         QStandardItemModel input;
0149         input.appendRow(createTaskItem(QStringLiteral("1. foo"), QStringLiteral("find me")));
0150         QStandardItem *item = createTaskItem(QStringLiteral("2. baz"), QStringLiteral("baz"));
0151         item->appendRow(createTaskItem(QStringLiteral("21. bar"), QStringLiteral("bar")));
0152         item->appendRow(createTaskItem(QStringLiteral("22. find me"), QStringLiteral("foo")));
0153         input.appendRow(item);
0154         input.appendRow(createTaskItem(QStringLiteral("3. baz"), QStringLiteral("baz")));
0155 
0156         Presentation::TaskFilterProxyModel output;
0157         output.setSourceModel(&input);
0158 
0159         // WHEN
0160         output.setFilterRegularExpression(QStringLiteral("find me"));
0161 
0162         // THEN
0163         QCOMPARE(output.rowCount(), 2);
0164         QCOMPARE(output.index(0, 0).data().toString(), QStringLiteral("1. foo"));
0165         QCOMPARE(output.index(1, 0).data().toString(), QStringLiteral("2. baz"));
0166 
0167         const QModelIndex parent = output.index(1, 0);
0168         QCOMPARE(output.rowCount(parent), 1);
0169         QCOMPARE(output.index(0, 0, parent).data().toString(), QStringLiteral("22. find me"));
0170     }
0171 
0172     void shouldSortFollowingType_data()
0173     {
0174         QTest::addColumn<int>("sortType");
0175         QTest::addColumn<int>("sortOrder");
0176         QTest::addColumn<QList<QStandardItem*>>("inputItems");
0177         QTest::addColumn<QStringList>("expectedOutputTitles");
0178 
0179         QList<QStandardItem*> inputItems;
0180         QStringList expectedOutputTitles;
0181 
0182         inputItems.clear();
0183         expectedOutputTitles.clear();
0184         inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo")) << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"));
0185         expectedOutputTitles << QStringLiteral("B") << QStringLiteral("C");
0186         QTest::newRow("title ascending") << int(Presentation::TaskFilterProxyModel::TitleSort)
0187                                          << int(Qt::AscendingOrder)
0188                                          << inputItems << expectedOutputTitles;
0189 
0190         inputItems.clear();
0191         expectedOutputTitles.clear();
0192         inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo")) << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"));
0193         expectedOutputTitles << QStringLiteral("C") << QStringLiteral("B");
0194         QTest::newRow("title descending") << int(Presentation::TaskFilterProxyModel::TitleSort)
0195                                          << int(Qt::DescendingOrder)
0196                                          << inputItems << expectedOutputTitles;
0197 
0198         inputItems.clear();
0199         expectedOutputTitles.clear();
0200         inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 10))
0201                    << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(2014, 03, 01))
0202                    << createTaskItem(QStringLiteral("D"), QStringLiteral("foo"));
0203         expectedOutputTitles << QStringLiteral("C") << QStringLiteral("B") << QStringLiteral("D");
0204         QTest::newRow("start date ascending") << int(Presentation::TaskFilterProxyModel::DateSort)
0205                                               << int(Qt::AscendingOrder)
0206                                               << inputItems << expectedOutputTitles;
0207 
0208         inputItems.clear();
0209         expectedOutputTitles.clear();
0210         inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 10))
0211                    << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(2014, 03, 01))
0212                    << createTaskItem(QStringLiteral("D"), QStringLiteral("foo"));
0213         expectedOutputTitles << QStringLiteral("D") << QStringLiteral("B") << QStringLiteral("C");
0214         QTest::newRow("start date descending") << int(Presentation::TaskFilterProxyModel::DateSort)
0215                                                << int(Qt::DescendingOrder)
0216                                                << inputItems << expectedOutputTitles;
0217 
0218         inputItems.clear();
0219         expectedOutputTitles.clear();
0220         inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 10))
0221                    << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 01))
0222                    << createTaskItem(QStringLiteral("D"), QStringLiteral("foo"));
0223         expectedOutputTitles << QStringLiteral("C") << QStringLiteral("B") << QStringLiteral("D");
0224         QTest::newRow("due date ascending") << int(Presentation::TaskFilterProxyModel::DateSort)
0225                                             << int(Qt::AscendingOrder)
0226                                             << inputItems << expectedOutputTitles;
0227 
0228         inputItems.clear();
0229         expectedOutputTitles.clear();
0230         inputItems << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 10))
0231                    << createTaskItem(QStringLiteral("C"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 01))
0232                    << createTaskItem(QStringLiteral("D"), QStringLiteral("foo"));
0233         expectedOutputTitles << QStringLiteral("D") << QStringLiteral("B") << QStringLiteral("C");
0234         QTest::newRow("due date descending") << int(Presentation::TaskFilterProxyModel::DateSort)
0235                                              << int(Qt::DescendingOrder)
0236                                              << inputItems << expectedOutputTitles;
0237 
0238         inputItems.clear();
0239         expectedOutputTitles.clear();
0240         inputItems << createTaskItem(QStringLiteral("A"), QStringLiteral("foo"), QDate(2014, 03, 01), QDate(2014, 03, 10))
0241                    << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 10), QDate(2014, 03, 01));
0242         expectedOutputTitles << QStringLiteral("B") << QStringLiteral("A");
0243         QTest::newRow("due date over start date") << int(Presentation::TaskFilterProxyModel::DateSort)
0244                                                   << int(Qt::AscendingOrder)
0245                                                   << inputItems << expectedOutputTitles;
0246 
0247         inputItems.clear();
0248         expectedOutputTitles.clear();
0249         inputItems << createTaskItem(QStringLiteral("A"), QStringLiteral("foo"), QDate(), QDate(2014, 03, 10))
0250                    << createTaskItem(QStringLiteral("B"), QStringLiteral("foo"), QDate(2014, 03, 01), QDate());
0251         expectedOutputTitles << QStringLiteral("B") << QStringLiteral("A");
0252         QTest::newRow("due date over start date") << int(Presentation::TaskFilterProxyModel::DateSort)
0253                                                   << int(Qt::AscendingOrder)
0254                                                   << inputItems << expectedOutputTitles;
0255     }
0256 
0257     void shouldSortFollowingType()
0258     {
0259         // GIVEN
0260         QFETCH(int, sortType);
0261         QFETCH(int, sortOrder);
0262         QFETCH(QList<QStandardItem*>, inputItems);
0263         QFETCH(QStringList, expectedOutputTitles);
0264 
0265         QStandardItemModel input;
0266         foreach (QStandardItem *item, inputItems) {
0267             input.appendRow(item);
0268         }
0269 
0270         // WHEN
0271         Presentation::TaskFilterProxyModel output;
0272         output.setSourceModel(&input);
0273         output.setSortType(Presentation::TaskFilterProxyModel::SortType(sortType));
0274         output.setSortOrder(Qt::SortOrder(sortOrder));
0275 
0276         QStringList outputTitles;
0277         outputTitles.reserve(output.rowCount());
0278         for (int row = 0; row < output.rowCount(); row++) {
0279             outputTitles << output.index(row, 0).data().toString();
0280         }
0281 
0282         // THEN
0283         QCOMPARE(outputTitles, expectedOutputTitles);
0284     }
0285 };
0286 
0287 ZANSHIN_TEST_MAIN(TaskFilterProxyModelTest)
0288 
0289 #include "taskfilterproxymodeltest.moc"