File indexing completed on 2024-05-12 17:09:49
0001 /* 0002 SPDX-FileCopyrightText: 2014 Martin Gräßlin <mgraesslin@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "../history.h" 0008 #include "../historystringitem.h" 0009 // Qt 0010 #include <QObject> 0011 #include <QSignalSpy> 0012 #include <QtTest> 0013 0014 class HistoryTest : public QObject 0015 { 0016 Q_OBJECT 0017 private Q_SLOTS: 0018 void testSetMaxSize(); 0019 void testInsertRemove(); 0020 void testClear(); 0021 void testFind(); 0022 void testCycle(); 0023 }; 0024 0025 void HistoryTest::testSetMaxSize() 0026 { 0027 std::unique_ptr<History> history(new History(nullptr)); 0028 QSignalSpy changedSpy(history.get(), &History::changed); 0029 QSignalSpy topSpy(history.get(), &History::topChanged); 0030 QVERIFY(history->empty()); 0031 QCOMPARE(history->maxSize(), 0u); 0032 QVERIFY(changedSpy.isEmpty()); 0033 QVERIFY(topSpy.isEmpty()); 0034 0035 // insert an item - should still be empty 0036 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("foo")))); 0037 QVERIFY(history->empty()); 0038 QVERIFY(changedSpy.isEmpty()); 0039 QVERIFY(topSpy.isEmpty()); 0040 0041 // now it should insert again 0042 history->setMaxSize(1); 0043 QCOMPARE(history->maxSize(), 1u); 0044 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("foo")))); 0045 QVERIFY(!history->empty()); 0046 QCOMPARE(changedSpy.size(), 1); 0047 changedSpy.clear(); 0048 QVERIFY(changedSpy.isEmpty()); 0049 QCOMPARE(topSpy.size(), 1); 0050 topSpy.clear(); 0051 QVERIFY(topSpy.isEmpty()); 0052 0053 // insert another item, foo should get removed 0054 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("bar")))); 0055 QCOMPARE(history->first()->text(), QLatin1String("bar")); 0056 QCOMPARE(history->first()->next_uuid(), history->first()->uuid()); 0057 QCOMPARE(topSpy.size(), 1); 0058 topSpy.clear(); 0059 QVERIFY(topSpy.isEmpty()); 0060 // two changed events - once added, once removed 0061 QCOMPARE(changedSpy.size(), 2); 0062 changedSpy.clear(); 0063 QVERIFY(changedSpy.isEmpty()); 0064 0065 // setting to 0 should clear again 0066 history->setMaxSize(0); 0067 QCOMPARE(history->maxSize(), 0u); 0068 QVERIFY(history->empty()); 0069 QCOMPARE(changedSpy.size(), 1); 0070 QCOMPARE(topSpy.size(), 1); 0071 } 0072 0073 void HistoryTest::testInsertRemove() 0074 { 0075 std::unique_ptr<History> history(new History(nullptr)); 0076 QSignalSpy topSpy(history.get(), &History::topChanged); 0077 QSignalSpy topUserSelectedSpy(history.get(), &History::topIsUserSelectedSet); 0078 0079 history->setMaxSize(10); 0080 QVERIFY(history->empty()); 0081 QVERIFY(!history->topIsUserSelected()); 0082 0083 const QString fooText = QStringLiteral("foo"); 0084 const QString barText = QStringLiteral("bar"); 0085 const QString fooBarText = QStringLiteral("foobar"); 0086 const QByteArray fooUuid = QCryptographicHash::hash(fooText.toUtf8(), QCryptographicHash::Sha1); 0087 const QByteArray barUuid = QCryptographicHash::hash(barText.toUtf8(), QCryptographicHash::Sha1); 0088 const QByteArray foobarUuid = QCryptographicHash::hash(fooBarText.toUtf8(), QCryptographicHash::Sha1); 0089 0090 // let's insert a few items 0091 history->insert(HistoryItemPtr(new HistoryStringItem(fooText))); 0092 QVERIFY(!history->topIsUserSelected()); 0093 QCOMPARE(history->first()->text(), fooText); 0094 QCOMPARE(history->first()->next_uuid(), history->first()->uuid()); 0095 QCOMPARE(history->first()->previous_uuid(), history->first()->uuid()); 0096 QCOMPARE(topSpy.size(), 1); 0097 topSpy.clear(); 0098 QVERIFY(topSpy.isEmpty()); 0099 0100 history->insert(HistoryItemPtr(new HistoryStringItem(barText))); 0101 QVERIFY(!history->topIsUserSelected()); 0102 QCOMPARE(history->first()->text(), barText); 0103 QCOMPARE(history->first()->next_uuid(), fooUuid); 0104 QCOMPARE(history->first()->previous_uuid(), fooUuid); 0105 QCOMPARE(history->find(fooUuid)->next_uuid(), barUuid); 0106 QCOMPARE(history->find(fooUuid)->previous_uuid(), barUuid); 0107 QCOMPARE(topSpy.size(), 1); 0108 topSpy.clear(); 0109 QVERIFY(topSpy.isEmpty()); 0110 0111 history->insert(HistoryItemPtr(new HistoryStringItem(fooBarText))); 0112 QVERIFY(!history->topIsUserSelected()); 0113 QCOMPARE(history->first()->text(), fooBarText); 0114 QCOMPARE(history->first()->next_uuid(), barUuid); 0115 QCOMPARE(history->first()->previous_uuid(), fooUuid); 0116 QCOMPARE(history->find(fooUuid)->next_uuid(), foobarUuid); 0117 QCOMPARE(history->find(fooUuid)->previous_uuid(), barUuid); 0118 QCOMPARE(history->find(barUuid)->next_uuid(), fooUuid); 0119 QCOMPARE(history->find(barUuid)->previous_uuid(), foobarUuid); 0120 QCOMPARE(topSpy.size(), 1); 0121 topSpy.clear(); 0122 QVERIFY(topSpy.isEmpty()); 0123 0124 // insert one again - it should be moved to top 0125 history->insert(HistoryItemPtr(new HistoryStringItem(barText))); 0126 QVERIFY(!history->topIsUserSelected()); 0127 QCOMPARE(history->first()->text(), barText); 0128 QCOMPARE(history->first()->next_uuid(), foobarUuid); 0129 QCOMPARE(history->first()->previous_uuid(), fooUuid); 0130 QCOMPARE(history->find(fooUuid)->next_uuid(), barUuid); 0131 QCOMPARE(history->find(fooUuid)->previous_uuid(), foobarUuid); 0132 QCOMPARE(history->find(foobarUuid)->next_uuid(), fooUuid); 0133 QCOMPARE(history->find(foobarUuid)->previous_uuid(), barUuid); 0134 QCOMPARE(topSpy.size(), 1); 0135 topSpy.clear(); 0136 QVERIFY(topSpy.isEmpty()); 0137 0138 // move one to top using the slot 0139 // as well as the top changing, topIsUserSelected will also be signalled to show that it got re-selected 0140 history->slotMoveToTop(barUuid); 0141 QVERIFY(history->topIsUserSelected()); 0142 QCOMPARE(history->first()->text(), barText); 0143 QCOMPARE(history->first()->next_uuid(), foobarUuid); 0144 QCOMPARE(history->first()->previous_uuid(), fooUuid); 0145 QCOMPARE(history->find(fooUuid)->next_uuid(), barUuid); 0146 QCOMPARE(history->find(fooUuid)->previous_uuid(), foobarUuid); 0147 QCOMPARE(history->find(foobarUuid)->next_uuid(), fooUuid); 0148 QCOMPARE(history->find(foobarUuid)->previous_uuid(), barUuid); 0149 QCOMPARE(topSpy.size(), 1); 0150 topSpy.clear(); 0151 QVERIFY(topSpy.isEmpty()); 0152 QCOMPARE(topUserSelectedSpy.size(), 1); 0153 topUserSelectedSpy.clear(); 0154 QVERIFY(topUserSelectedSpy.isEmpty()); 0155 0156 // another one should change, though 0157 history->slotMoveToTop(foobarUuid); 0158 QVERIFY(history->topIsUserSelected()); 0159 QCOMPARE(history->first()->text(), fooBarText); 0160 QCOMPARE(history->first()->next_uuid(), barUuid); 0161 QCOMPARE(history->first()->previous_uuid(), fooUuid); 0162 QCOMPARE(history->find(fooUuid)->next_uuid(), foobarUuid); 0163 QCOMPARE(history->find(fooUuid)->previous_uuid(), barUuid); 0164 QCOMPARE(history->find(barUuid)->next_uuid(), fooUuid); 0165 QCOMPARE(history->find(barUuid)->previous_uuid(), foobarUuid); 0166 QCOMPARE(topSpy.size(), 1); 0167 topSpy.clear(); 0168 QVERIFY(topSpy.isEmpty()); 0169 0170 // remove them again 0171 history->remove(history->find(foobarUuid)); 0172 QVERIFY(!history->topIsUserSelected()); 0173 QCOMPARE(history->first()->text(), barText); 0174 QCOMPARE(history->first()->next_uuid(), fooUuid); 0175 QCOMPARE(history->first()->previous_uuid(), fooUuid); 0176 QCOMPARE(history->find(fooUuid)->next_uuid(), barUuid); 0177 QCOMPARE(history->find(fooUuid)->previous_uuid(), barUuid); 0178 QCOMPARE(topSpy.size(), 1); 0179 topSpy.clear(); 0180 QVERIFY(topSpy.isEmpty()); 0181 0182 history->remove(history->find(barUuid)); 0183 QVERIFY(!history->topIsUserSelected()); 0184 QCOMPARE(history->first()->text(), fooText); 0185 QCOMPARE(history->first()->next_uuid(), history->first()->uuid()); 0186 QCOMPARE(history->first()->previous_uuid(), history->first()->uuid()); 0187 QCOMPARE(topSpy.size(), 1); 0188 topSpy.clear(); 0189 QVERIFY(topSpy.isEmpty()); 0190 0191 history->remove(history->find(fooUuid)); 0192 QVERIFY(!history->topIsUserSelected()); 0193 QVERIFY(!history->first()); 0194 QVERIFY(history->empty()); 0195 QCOMPARE(topSpy.size(), 1); 0196 } 0197 0198 void HistoryTest::testClear() 0199 { 0200 std::unique_ptr<History> history(new History(nullptr)); 0201 history->setMaxSize(10); 0202 QVERIFY(history->empty()); 0203 QVERIFY(!history->topIsUserSelected()); 0204 0205 history->slotClear(); 0206 QVERIFY(history->empty()); 0207 0208 // insert some items 0209 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("foo")))); 0210 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("bar")))); 0211 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("foobar")))); 0212 history->slotMoveToTop(QCryptographicHash::hash(QByteArrayLiteral("bar"), QCryptographicHash::Sha1)); 0213 QVERIFY(!history->empty()); 0214 QVERIFY(history->topIsUserSelected()); 0215 QVERIFY(history->first()); 0216 0217 // and clear 0218 QSignalSpy topSpy(history.get(), &History::topChanged); 0219 QVERIFY(topSpy.isEmpty()); 0220 history->slotClear(); 0221 QVERIFY(history->empty()); 0222 QVERIFY(!history->first()); 0223 QVERIFY(!history->topIsUserSelected()); 0224 QVERIFY(!topSpy.isEmpty()); 0225 } 0226 0227 void HistoryTest::testFind() 0228 { 0229 std::unique_ptr<History> history(new History(nullptr)); 0230 history->setMaxSize(10); 0231 QVERIFY(history->empty()); 0232 QVERIFY(!history->find(QByteArrayLiteral("whatever"))); 0233 QVERIFY(!history->find(QByteArray())); 0234 0235 // insert some items 0236 history->insert(HistoryItemPtr(new HistoryStringItem(QStringLiteral("foo")))); 0237 QVERIFY(!history->find(QByteArrayLiteral("whatever"))); 0238 QVERIFY(!history->find(QByteArray())); 0239 const QByteArray fooUuid = QCryptographicHash::hash(QByteArrayLiteral("foo"), QCryptographicHash::Sha1); 0240 QCOMPARE(history->find(fooUuid)->uuid(), fooUuid); 0241 0242 history->slotClear(); 0243 QVERIFY(!history->find(fooUuid)); 0244 } 0245 0246 void HistoryTest::testCycle() 0247 { 0248 std::unique_ptr<History> history(new History(nullptr)); 0249 QSignalSpy topSpy(history.get(), &History::topChanged); 0250 history->setMaxSize(10); 0251 QVERIFY(!history->nextInCycle()); 0252 QVERIFY(!history->prevInCycle()); 0253 0254 const QString fooText = QStringLiteral("foo"); 0255 const QString barText = QStringLiteral("bar"); 0256 const QString fooBarText = QStringLiteral("foobar"); 0257 const QByteArray fooUuid = QCryptographicHash::hash(fooText.toUtf8(), QCryptographicHash::Sha1); 0258 const QByteArray barUuid = QCryptographicHash::hash(barText.toUtf8(), QCryptographicHash::Sha1); 0259 const QByteArray foobarUuid = QCryptographicHash::hash(fooBarText.toUtf8(), QCryptographicHash::Sha1); 0260 0261 history->insert(HistoryItemPtr(new HistoryStringItem(fooText))); 0262 QCOMPARE(topSpy.size(), 1); 0263 topSpy.clear(); 0264 QVERIFY(!history->nextInCycle()); 0265 QVERIFY(!history->prevInCycle()); 0266 // cycling to next shouldn't change anything 0267 history->cycleNext(); 0268 QVERIFY(topSpy.isEmpty()); 0269 QVERIFY(!history->nextInCycle()); 0270 QVERIFY(!history->prevInCycle()); 0271 // cycling to previous shouldn't change anything 0272 history->cyclePrev(); 0273 QVERIFY(topSpy.isEmpty()); 0274 QVERIFY(!history->nextInCycle()); 0275 QVERIFY(!history->prevInCycle()); 0276 0277 // insert more items 0278 history->insert(HistoryItemPtr(new HistoryStringItem(barText))); 0279 QCOMPARE(topSpy.size(), 1); 0280 topSpy.clear(); 0281 QCOMPARE(history->nextInCycle(), history->find(fooUuid)); 0282 QVERIFY(!history->prevInCycle()); 0283 // cycle to next 0284 history->cycleNext(); 0285 QCOMPARE(topSpy.size(), 1); 0286 topSpy.clear(); 0287 QCOMPARE(history->first(), history->find(fooUuid)); 0288 QVERIFY(!history->nextInCycle()); 0289 QCOMPARE(history->prevInCycle(), history->find(barUuid)); 0290 // there are no more next 0291 history->cycleNext(); 0292 QVERIFY(topSpy.isEmpty()); 0293 // cycle to prev should restore previous state 0294 history->cyclePrev(); 0295 QCOMPARE(topSpy.size(), 1); 0296 topSpy.clear(); 0297 QCOMPARE(history->first(), history->find(barUuid)); 0298 QCOMPARE(history->nextInCycle(), history->find(fooUuid)); 0299 QVERIFY(!history->prevInCycle()); 0300 // there are no more prev 0301 history->cyclePrev(); 0302 QVERIFY(topSpy.isEmpty()); 0303 0304 // insert a third item 0305 history->insert(HistoryItemPtr(new HistoryStringItem(fooBarText))); 0306 QCOMPARE(topSpy.size(), 1); 0307 topSpy.clear(); 0308 QCOMPARE(history->nextInCycle(), history->find(barUuid)); 0309 QVERIFY(!history->prevInCycle()); 0310 // cycle to next 0311 history->cycleNext(); 0312 QCOMPARE(topSpy.size(), 1); 0313 topSpy.clear(); 0314 QCOMPARE(history->first(), history->find(barUuid)); 0315 QCOMPARE(history->nextInCycle(), history->find(fooUuid)); 0316 QCOMPARE(history->prevInCycle(), history->find(foobarUuid)); 0317 // cycle to next (should be last) 0318 history->cycleNext(); 0319 QCOMPARE(topSpy.size(), 1); 0320 topSpy.clear(); 0321 QCOMPARE(history->first(), history->find(fooUuid)); 0322 QVERIFY(!history->nextInCycle()); 0323 QCOMPARE(history->prevInCycle(), history->find(barUuid)); 0324 // there are no more next 0325 history->cycleNext(); 0326 QVERIFY(topSpy.isEmpty()); 0327 // and back again 0328 history->cyclePrev(); 0329 QCOMPARE(topSpy.size(), 1); 0330 topSpy.clear(); 0331 QCOMPARE(history->first(), history->find(barUuid)); 0332 QCOMPARE(history->nextInCycle(), history->find(fooUuid)); 0333 QCOMPARE(history->prevInCycle(), history->find(foobarUuid)); 0334 // one more 0335 history->cyclePrev(); 0336 QCOMPARE(topSpy.size(), 1); 0337 topSpy.clear(); 0338 QCOMPARE(history->first(), history->find(foobarUuid)); 0339 QCOMPARE(history->nextInCycle(), history->find(barUuid)); 0340 QVERIFY(!history->prevInCycle()); 0341 // there are no more prev 0342 history->cyclePrev(); 0343 QVERIFY(topSpy.isEmpty()); 0344 } 0345 0346 QTEST_MAIN(HistoryTest) 0347 #include "historytest.moc"