File indexing completed on 2024-05-12 05:01:49

0001 /*
0002    SPDX-FileCopyrightText: 2020 David Faure <faure@kde.org>
0003    SPDX-FileCopyrightText: 2020 Milian Wolff <mail@milianw.de>
0004 
0005    SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "lrucachetest.h"
0009 
0010 #include <QStandardPaths>
0011 #include <QTest>
0012 #include <QVector>
0013 
0014 #include "lrucache.h"
0015 #include <algorithm>
0016 
0017 QTEST_GUILESS_MAIN(LRUCacheTest)
0018 
0019 LRUCacheTest::LRUCacheTest(QObject *parent)
0020     : QObject(parent)
0021 {
0022     QStandardPaths::setTestModeEnabled(true);
0023 }
0024 
0025 void LRUCacheTest::shouldCacheLastFiveEntries()
0026 {
0027     auto makeString = [](const char *prefix, int i) -> QString {
0028         return QLatin1String(prefix) + QString::number(i);
0029     };
0030 
0031     using Cache = LRUCache<QString, QString>;
0032     Cache cache;
0033     cache.setMaxEntries(5);
0034     auto contents = [&cache]() -> QVector<QString> {
0035         QVector<QString> ret(cache.size());
0036         std::transform(cache.begin(), cache.end(), ret.begin(), [](const Cache::Entry &entry) {
0037             return entry.value;
0038         });
0039         return ret;
0040     };
0041 
0042     QCOMPARE(cache.size(), 0);
0043     QCOMPARE(cache.begin(), cache.end());
0044     QCOMPARE(cache.find(QString()), cache.end());
0045 
0046     QVector<QString> expected;
0047     for (int i = 1; i < 7; ++i) {
0048         const auto expectedSizeBefore = std::min(i - 1, 5);
0049         const auto expectedSizeAfter = std::min(i, 5);
0050         QCOMPARE(cache.size(), expectedSizeBefore);
0051         const auto key = makeString("key", i);
0052         const auto value = makeString("value", i);
0053         QCOMPARE(cache.find(key), cache.end());
0054         cache.insert(key, value);
0055         QCOMPARE(cache.size(), expectedSizeAfter);
0056         QCOMPARE(std::distance(cache.begin(), cache.find(key)), 0);
0057         QCOMPARE(cache.find(key)->value, value);
0058         expected.prepend(value);
0059         if (expected.size() == 6) {
0060             expected.removeLast();
0061         }
0062         QCOMPARE(contents(), expected);
0063     }
0064 
0065     for (int i = 0; i < 10; ++i) {
0066         const auto key = makeString("key", i);
0067         const auto value = makeString("value", i);
0068         if (i <= 1 || i >= 7) {
0069             QCOMPARE(cache.find(key), cache.end());
0070         } else {
0071             QCOMPARE(std::distance(cache.begin(), cache.find(key)), 0);
0072             QCOMPARE(cache.find(key)->value, value);
0073             QCOMPARE(value, expected.last());
0074             expected.removeLast();
0075             expected.prepend(value);
0076         }
0077         QCOMPARE(contents(), expected);
0078     }
0079 
0080     // Looking up an entry moves it the front
0081     auto value = makeString("value", 4);
0082     QCOMPARE(cache.find(makeString("key", 4))->value, value);
0083     QVERIFY(expected.removeOne(value));
0084     expected.prepend(value);
0085     QCOMPARE(contents(), expected);
0086 
0087     // Remove an entry
0088     auto value3 = makeString("value", 3);
0089     QVERIFY(cache.remove(makeString("key", 3)));
0090     QVERIFY(expected.removeOne(value3));
0091     QCOMPARE(contents(), expected);
0092 
0093     cache.clear();
0094 }
0095 
0096 void LRUCacheTest::shouldWorkWithUniquePtr()
0097 {
0098     static int deletions = 0;
0099     struct MyDocument {
0100         ~MyDocument()
0101         {
0102             ++deletions;
0103         }
0104     };
0105     LRUCache<int, std::unique_ptr<MyDocument>> documentCache;
0106     documentCache.setMaxEntries(32);
0107     documentCache.insert(42, std::make_unique<MyDocument>());
0108     QCOMPARE(documentCache.size(), 1);
0109     documentCache.clear();
0110     QCOMPARE(documentCache.size(), 0);
0111     QCOMPARE(deletions, 1);
0112 }
0113 
0114 #include "moc_lrucachetest.cpp"