File indexing completed on 2024-06-16 05:11:11
0001 /* 0002 SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include <QSignalSpy> 0008 #include <QStandardPaths> 0009 #include <QTest> 0010 0011 #include "../slidefiltermodel.h" 0012 #include "../slidemodel.h" 0013 #include "commontestdata.h" 0014 0015 #include <array> 0016 0017 class SlideFilterModelTest : public QObject 0018 { 0019 Q_OBJECT 0020 0021 private Q_SLOTS: 0022 void initTestCase(); 0023 void init(); 0024 void cleanup(); 0025 void cleanupTestCase(); 0026 0027 void testSlideFilterModelSortingOrder_data(); 0028 void testSlideFilterModelSortingOrder(); 0029 void testSlideFilterModelSortingRandomOrder(); 0030 /** 0031 * When a wallpaper file is added/removed, the random order list (m_randomOrder) should be 0032 * able to provide a correct updated list. 0033 * @see https://bugs.kde.org/show_bug.cgi?id=473088 0034 */ 0035 void testSlideFilterModelSortingRandomOrderWithFileAddedRemoved_data(); 0036 void testSlideFilterModelSortingRandomOrderWithFileAddedRemoved(); 0037 void testSlideFilterModelUncheckedSlides(); 0038 0039 private: 0040 QPointer<SlideModel> m_model = nullptr; 0041 QPointer<SlideFilterModel> m_filterModel = nullptr; 0042 0043 QDir m_dataDir; 0044 QString m_wallpaperPath; 0045 QString m_standardPath; 0046 QString m_pathA, m_pathB, m_pathC; 0047 QProperty<QSize> m_targetSize; 0048 QProperty<bool> m_usedInConfig{false}; 0049 QProperty<SortingMode::Mode> m_sortingMode{SortingMode::Random}; 0050 QProperty<bool> m_sortingFoldersFirst{false}; 0051 }; 0052 0053 void SlideFilterModelTest::initTestCase() 0054 { 0055 m_dataDir = QDir(QFINDTESTDATA("testdata/default")); 0056 QVERIFY(!m_dataDir.isEmpty()); 0057 0058 m_wallpaperPath = m_dataDir.absoluteFilePath(ImageBackendTestData::defaultImageFileName1); 0059 0060 m_targetSize = QSize(1920, 1080); 0061 0062 QStandardPaths::setTestModeEnabled(true); 0063 0064 m_standardPath = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/wallpapers/"); 0065 QDir imageDir(m_standardPath); 0066 0067 QVERIFY(imageDir.mkpath(m_standardPath + QStringLiteral("a/"))); 0068 QVERIFY(imageDir.mkpath(m_standardPath + QStringLiteral("d/"))); 0069 0070 QFile imageFile(m_wallpaperPath); 0071 0072 m_pathB = imageDir.absoluteFilePath(QStringLiteral("d/b.jpg")); 0073 QVERIFY(imageFile.copy(m_pathB)); 0074 0075 // Explicitly wait 1s 0076 QThread::sleep(1); 0077 0078 m_pathA = imageDir.absoluteFilePath(QStringLiteral("d/a.jpg")); 0079 QVERIFY(imageFile.copy(m_pathA)); 0080 0081 QThread::sleep(1); 0082 0083 m_pathC = imageDir.absoluteFilePath(QStringLiteral("a/c.jpg")); 0084 QVERIFY(imageFile.copy(m_pathC)); 0085 } 0086 0087 void SlideFilterModelTest::init() 0088 { 0089 m_model = new SlideModel(QBindable<QSize>(&m_targetSize), QBindable<bool>(&m_usedInConfig), this); 0090 m_filterModel = new SlideFilterModel(QBindable<bool>(&m_usedInConfig), // 0091 QBindable<SortingMode::Mode>(&m_sortingMode), // 0092 QBindable<bool>(&m_sortingFoldersFirst), // 0093 this); 0094 0095 // Test loading data 0096 m_model->setSlidePaths({m_standardPath}); 0097 QSignalSpy doneSpy(m_model, &SlideModel::done); 0098 0099 QVERIFY(doneSpy.wait(10 * 1000)); 0100 QCOMPARE(doneSpy.size(), 1); 0101 m_filterModel->setSourceModel(m_model); 0102 } 0103 0104 void SlideFilterModelTest::cleanup() 0105 { 0106 m_model->deleteLater(); 0107 m_filterModel->deleteLater(); 0108 } 0109 0110 void SlideFilterModelTest::cleanupTestCase() 0111 { 0112 QDir(m_standardPath).removeRecursively(); 0113 } 0114 0115 void SlideFilterModelTest::testSlideFilterModelSortingOrder_data() 0116 { 0117 QTest::addColumn<SortingMode::Mode>("order"); 0118 QTest::addColumn<bool>("folderFirst"); 0119 QTest::addColumn<QStringList>("expected"); 0120 0121 QTest::newRow("Alphabetical 0") << SortingMode::Alphabetical << false << QStringList{m_pathA, m_pathB, m_pathC}; 0122 QTest::newRow("Alphabetical 1") << SortingMode::Alphabetical << true << QStringList{m_pathC, m_pathA, m_pathB}; 0123 0124 QTest::newRow("AlphabeticalReversed 0") << SortingMode::AlphabeticalReversed << false << QStringList{m_pathC, m_pathB, m_pathA}; 0125 QTest::newRow("AlphabeticalReversed 1") << SortingMode::AlphabeticalReversed << true << QStringList{m_pathB, m_pathA, m_pathC}; 0126 0127 // Oldest first 0128 QTest::newRow("Modified 0") << SortingMode::Modified << false << QStringList{m_pathB, m_pathA, m_pathC}; 0129 QTest::newRow("Modified 1") << SortingMode::Modified << true << QStringList{m_pathB, m_pathA, m_pathC}; 0130 0131 // Newest first 0132 QTest::newRow("ModifiedReversed 0") << SortingMode::ModifiedReversed << false << QStringList{m_pathC, m_pathA, m_pathB}; 0133 QTest::newRow("ModifiedReversed 1") << SortingMode::ModifiedReversed << true << QStringList{m_pathC, m_pathA, m_pathB}; 0134 } 0135 0136 void SlideFilterModelTest::testSlideFilterModelSortingOrder() 0137 { 0138 QFETCH(SortingMode::Mode, order); 0139 QFETCH(bool, folderFirst); 0140 QFETCH(QStringList, expected); 0141 0142 m_sortingMode = order; 0143 m_sortingFoldersFirst = folderFirst; 0144 QCOMPARE(m_filterModel->rowCount(), 3); 0145 0146 for (int i = 0; i < expected.size(); i++) { 0147 QCOMPARE(m_filterModel->index(i, 0).data(ImageRoles::PackageNameRole).toString(), expected.at(i)); 0148 } 0149 } 0150 0151 void SlideFilterModelTest::testSlideFilterModelSortingRandomOrder() 0152 { 0153 std::array<int, 3> counts{0, 0, 0}; 0154 QCOMPARE(m_filterModel->rowCount(), counts.size()); 0155 0156 // Monte Carlo 0157 m_sortingMode = SortingMode::Random; 0158 m_sortingFoldersFirst = false; 0159 for (int i = 0; i < 1000; i++) { 0160 m_filterModel->invalidate(); 0161 const QString firstElement = m_filterModel->index(0, 0).data(ImageRoles::PackageNameRole).toString(); 0162 0163 if (firstElement == m_pathA) { 0164 counts[0]++; 0165 } else if (firstElement == m_pathB) { 0166 counts[1]++; 0167 } else if (firstElement == m_pathC) { 0168 counts[2]++; 0169 } 0170 } 0171 0172 qDebug() << counts[0] << counts[1] << counts[2]; 0173 for (int c : std::as_const(counts)) { 0174 QVERIFY(std::clamp(c, 200, 400) == c); 0175 } 0176 } 0177 0178 void SlideFilterModelTest::testSlideFilterModelSortingRandomOrderWithFileAddedRemoved_data() 0179 { 0180 QTest::addColumn<bool>("usedInConfig"); 0181 0182 QTest::newRow("usedInConfig: false") << false; 0183 QTest::newRow("usedInConfig: true") << true; 0184 } 0185 0186 void SlideFilterModelTest::testSlideFilterModelSortingRandomOrderWithFileAddedRemoved() 0187 { 0188 QFETCH(bool, usedInConfig); 0189 m_usedInConfig = usedInConfig; 0190 0191 m_sortingMode = SortingMode::Random; 0192 m_sortingFoldersFirst = false; 0193 int oldRowCount = m_filterModel->rowCount(); 0194 0195 qDebug() << "Before adding a new wallpaper"; 0196 QStringList oldPaths; 0197 for (int i = 0, count = m_filterModel->rowCount(); i < count; ++i) { 0198 qDebug() << i << oldPaths.emplace_back(m_filterModel->index(i, 0).data(ImageRoles::PackageNameRole).toString()); 0199 } 0200 qDebug() << "Before adding a new wallpaper"; 0201 0202 QSignalSpy rowsInsertedSpy(m_filterModel, &QAbstractItemModel::rowsInserted); 0203 QDir imageDir(m_standardPath); 0204 const QString newImagePath = imageDir.absoluteFilePath(QStringLiteral("THIS_IS_THE_LAST_WALLPAPER_BUG473088.jpg")); 0205 QVERIFY(QFile(m_wallpaperPath).copy(newImagePath)); 0206 0207 if (m_filterModel->rowCount() == oldRowCount) { 0208 QVERIFY(rowsInsertedSpy.wait()); 0209 } else { 0210 QVERIFY(!rowsInsertedSpy.empty()); // Otherwise the random order is not updated 0211 } 0212 QCOMPARE(m_filterModel->rowCount(), oldRowCount + 1); 0213 0214 qDebug() << "After adding a new wallpaper"; 0215 for (int i = 0, count = oldPaths.size(); i < count; ++i) { 0216 // Make sure the old order is not changed 0217 qDebug() << i << m_filterModel->index(i, 0).data(ImageRoles::PackageNameRole).toString(); 0218 QCOMPARE(oldPaths[i], m_filterModel->index(i + (usedInConfig ? 1 : 0), 0).data(ImageRoles::PackageNameRole).toString()); 0219 } 0220 qDebug() << "After adding a new wallpaper"; 0221 0222 if (usedInConfig) { 0223 QCOMPARE(m_filterModel->index(0, 0).data(ImageRoles::PackageNameRole).toString(), newImagePath); 0224 } else { 0225 QCOMPARE(m_filterModel->index(m_filterModel->rowCount() - 1, 0).data(ImageRoles::PackageNameRole).toString(), newImagePath); 0226 } 0227 0228 // Now remove the wallpaper 0229 oldRowCount = m_filterModel->rowCount(); 0230 QSignalSpy rowsRemovedSpy(m_filterModel, &QAbstractItemModel::rowsRemoved); 0231 QVERIFY(QFile::remove(newImagePath)); 0232 if (m_filterModel->rowCount() == oldRowCount) { 0233 QVERIFY(rowsRemovedSpy.wait()); 0234 } else { 0235 QVERIFY(!rowsRemovedSpy.empty()); // Otherwise the random order is not updated 0236 } 0237 QCOMPARE(m_filterModel->rowCount(), oldRowCount - 1); 0238 qDebug() << "After deleting a wallpaper"; 0239 for (int i = 0, count = oldPaths.size(); i < count; ++i) { 0240 // Make sure the old order is not changed 0241 qDebug() << i << m_filterModel->index(i, 0).data(ImageRoles::PackageNameRole).toString(); 0242 QCOMPARE(oldPaths[i], m_filterModel->index(i, 0).data(ImageRoles::PackageNameRole).toString()); 0243 } 0244 qDebug() << "After deleting a wallpaper"; 0245 } 0246 0247 void SlideFilterModelTest::testSlideFilterModelUncheckedSlides() 0248 { 0249 m_model->setUncheckedSlides({m_pathA}); 0250 0251 m_usedInConfig = true; 0252 QCOMPARE(m_filterModel->rowCount(), 3); 0253 0254 m_usedInConfig = false; 0255 QCOMPARE(m_filterModel->rowCount(), 2); 0256 } 0257 0258 QTEST_MAIN(SlideFilterModelTest) 0259 0260 #include "test_slidefiltermodel.moc"