File indexing completed on 2024-05-12 05:09:58
0001 /*************************************************************************** 0002 Copyright (C) 2009-2023 Robby Stephenson <robby@periapsis.org> 0003 ***************************************************************************/ 0004 0005 /*************************************************************************** 0006 * * 0007 * This program is free software; you can redistribute it and/or * 0008 * modify it under the terms of the GNU General Public License as * 0009 * published by the Free Software Foundation; either version 2 of * 0010 * the License or (at your option) version 3 or any later version * 0011 * accepted by the membership of KDE e.V. (or its successor approved * 0012 * by the membership of KDE e.V.), which shall act as a proxy * 0013 * defined in Section 14 of version 3 of the license. * 0014 * * 0015 * This program is distributed in the hope that it will be useful, * 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0018 * GNU General Public License for more details. * 0019 * * 0020 * You should have received a copy of the GNU General Public License * 0021 * along with this program. If not, see <http://www.gnu.org/licenses/>. * 0022 * * 0023 ***************************************************************************/ 0024 0025 #include "entrycomparisontest.h" 0026 0027 #include "../collection.h" 0028 #include "../field.h" 0029 #include "../entry.h" 0030 #include "../collections/bookcollection.h" 0031 #include "../collections/bibtexcollection.h" 0032 #include "../collections/videocollection.h" 0033 #include "../collections/comicbookcollection.h" 0034 #include "../collections/musiccollection.h" 0035 #include "../collections/gamecollection.h" 0036 #include "../collections/filecatalog.h" 0037 #include "../entrycomparison.h" 0038 0039 #include <KLocalizedString> 0040 0041 #include <QTest> 0042 #include <QLoggingCategory> 0043 #include <QStandardPaths> 0044 0045 QTEST_GUILESS_MAIN( EntryComparisonTest ) 0046 0047 Q_DECLARE_METATYPE(Tellico::EntryComparison::MatchValue) 0048 0049 void EntryComparisonTest::initTestCase() { 0050 QStandardPaths::setTestModeEnabled(true); 0051 QLoggingCategory::setFilterRules(QStringLiteral("tellico.debug = true\ntellico.info = false")); 0052 qRegisterMetaType<Tellico::EntryComparison::MatchValue>(); 0053 KLocalizedString::setApplicationDomain("tellico"); 0054 // Tellico::ImageFactory::init(); 0055 0056 // create the collection and entry used for testMatchScore() 0057 m_coll = Tellico::Data::CollPtr(new Tellico::Data::BookCollection(true)); 0058 m_entry = Tellico::Data::EntryPtr(new Tellico::Data::Entry(m_coll)); 0059 m_entry->setField(QStringLiteral("title"), QStringLiteral("title1")); 0060 m_entry->setField(QStringLiteral("author"), QStringLiteral("John Doe")); 0061 m_entry->setField(QStringLiteral("isbn"), QStringLiteral("1234367890")); 0062 m_entry->setField(QStringLiteral("lccn"), QStringLiteral("89456")); 0063 Tellico::Data::FieldPtr f(new Tellico::Data::Field(QStringLiteral("arxiv"), QStringLiteral("Arxiv ID"))); 0064 m_coll->addField(f); 0065 m_entry->setField(QStringLiteral("arxiv"), QStringLiteral("hep-lat/0110180")); 0066 m_coll->addEntries(m_entry); 0067 } 0068 0069 void EntryComparisonTest::cleanupTestCase() { 0070 // Tellico::ImageFactory::clean(true); 0071 } 0072 0073 void EntryComparisonTest::testMatchScore() { 0074 QFETCH(QString, field); 0075 QFETCH(QString, value); 0076 QFETCH(Tellico::EntryComparison::MatchValue, score); 0077 0078 QVERIFY(m_coll); 0079 Tellico::Data::EntryPtr e(new Tellico::Data::Entry(m_coll)); 0080 e->setField(field, value); 0081 QCOMPARE(Tellico::EntryComparison::score(m_entry, e, field, m_coll.data()), int(score)); 0082 } 0083 0084 void EntryComparisonTest::testMatchScore_data() { 0085 QTest::addColumn<QString>("field"); 0086 QTest::addColumn<QString>("value"); 0087 QTest::addColumn<Tellico::EntryComparison::MatchValue>("score"); 0088 0089 QTest::newRow("empty title") << QStringLiteral("title") << QString() << Tellico::EntryComparison::MATCH_VALUE_NONE; 0090 QTest::newRow("title match") << QStringLiteral("title") << QStringLiteral("title1") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0091 QTest::newRow("title match case") << QStringLiteral("title") << QStringLiteral("TITLE1") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0092 // QTest::newRow("title match articles") << QStringLiteral("title") << QStringLiteral("THE TITLE1") << Tellico::EntryComparison::MATCH_VALUE_WEAK; 0093 QTest::newRow("title match non alphanum") << QStringLiteral("title") << QStringLiteral("title1.") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0094 // QTest::newRow("title match paren") << QStringLiteral("title") << QStringLiteral("title1 (old)") << Tellico::EntryComparison::MATCH_VALUE_WEAK; 0095 QTest::newRow("isbn match") << QStringLiteral("isbn") << QStringLiteral("1234367890") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0096 QTest::newRow("isbn match formatted") << QStringLiteral("isbn") << QStringLiteral("1-234-36789-0") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0097 QTest::newRow("lccn match") << QStringLiteral("lccn") << QStringLiteral("89456") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0098 QTest::newRow("lccn match formatted") << QStringLiteral("lccn") << QStringLiteral("89-456") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0099 QTest::newRow("arxiv") << QStringLiteral("arxiv") << QStringLiteral("hep-lat/0110180") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0100 QTest::newRow("arxiv format1") << QStringLiteral("arxiv") << QStringLiteral("hep-lat/0110180v1") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0101 QTest::newRow("arxiv format2") << QStringLiteral("arxiv") << QStringLiteral("arxiv:hep-lat/0110180v1") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0102 QTest::newRow("author") << QStringLiteral("author") << QStringLiteral("John Doe") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0103 QTest::newRow("author formatted") << QStringLiteral("author") << QStringLiteral("Doe, John") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0104 QTest::newRow("author formatted2") << QStringLiteral("author") << QStringLiteral("doe, john") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0105 QTest::newRow("author multiple") << QStringLiteral("author") << QStringLiteral("John Doe; Jane Doe") << Tellico::EntryComparison::MATCH_VALUE_STRONG; 0106 } 0107 0108 void EntryComparisonTest::testBookMatch() { 0109 Tellico::Data::CollPtr c(new Tellico::Data::BookCollection(true)); 0110 0111 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0112 e1->setField(QStringLiteral("title"), QStringLiteral("title1")); 0113 e1->setField(QStringLiteral("author"), QStringLiteral("author1")); 0114 e1->setField(QStringLiteral("edition"), QStringLiteral("edition1")); 0115 e1->setField(QStringLiteral("pur_price"), QStringLiteral("price1")); 0116 e1->setField(QStringLiteral("isbn"), QStringLiteral("1234567890")); 0117 c->addEntries(e1); 0118 0119 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0120 e2->setField(QStringLiteral("title"), QStringLiteral("title2")); 0121 e2->setField(QStringLiteral("author"), QStringLiteral("author2")); 0122 e2->setField(QStringLiteral("edition"), QStringLiteral("edition2")); 0123 e2->setField(QStringLiteral("pur_price"), QStringLiteral("price2")); 0124 e2->setField(QStringLiteral("isbn"), QStringLiteral("000000000")); 0125 0126 // not a good match 0127 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0128 0129 // matching the title makes a good match, even if author does not match 0130 e2->setField(QStringLiteral("title"), QStringLiteral("title1")); 0131 QVERIFY(c->sameEntry(e1, e2) > Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0132 0133 // title and author both matching are enough for high confidence 0134 e2->setField(QStringLiteral("author"), QStringLiteral("author1")); 0135 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0136 0137 // perfect match for isbn by itself 0138 e2->setField(QStringLiteral("title"), QString()); 0139 e2->setField(QStringLiteral("author"), QString()); 0140 e2->setField(QStringLiteral("isbn"), QStringLiteral("1234567890")); 0141 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0142 } 0143 0144 void EntryComparisonTest::testBibtexMatch() { 0145 Tellico::Data::CollPtr c(new Tellico::Data::BibtexCollection(true)); 0146 0147 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0148 e1->setField(QStringLiteral("title"), QStringLiteral("title1")); 0149 e1->setField(QStringLiteral("author"), QStringLiteral("author1")); 0150 e1->setField(QStringLiteral("edition"), QStringLiteral("edition1")); 0151 e1->setField(QStringLiteral("doi"), QStringLiteral("1234567890")); 0152 c->addEntries(e1); 0153 0154 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0155 e2->setField(QStringLiteral("title"), QStringLiteral("title2")); 0156 e2->setField(QStringLiteral("author"), QStringLiteral("author2")); 0157 e2->setField(QStringLiteral("edition"), QStringLiteral("edition2")); 0158 e2->setField(QStringLiteral("doi"), QStringLiteral("000000000")); 0159 0160 // not a good match 0161 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0162 0163 // matching the title makes a good match, even if author does not match 0164 e2->setField(QStringLiteral("title"), QStringLiteral("title1")); 0165 QVERIFY(c->sameEntry(e1, e2) > Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0166 0167 // title and author both matching are enough for high confidence 0168 e2->setField(QStringLiteral("author"), QStringLiteral("author1")); 0169 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0170 0171 // perfect match for doi by itself 0172 e2->setField(QStringLiteral("title"), QString()); 0173 e2->setField(QStringLiteral("author"), QString()); 0174 e2->setField(QStringLiteral("doi"), QStringLiteral("1234567890")); 0175 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0176 } 0177 0178 void EntryComparisonTest::testComicMatch() { 0179 Tellico::Data::CollPtr c(new Tellico::Data::ComicBookCollection(true)); 0180 0181 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0182 e1->setField(QStringLiteral("title"), QStringLiteral("title1")); 0183 e1->setField(QStringLiteral("series"), QStringLiteral("series1")); 0184 e1->setField(QStringLiteral("issue"), QStringLiteral("1")); 0185 c->addEntries(e1); 0186 0187 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0188 e2->setField(QStringLiteral("title"), QStringLiteral("title2")); 0189 0190 // not a good match 0191 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0192 0193 // matching the title makes a good match, even if author does not match 0194 e2->setField(QStringLiteral("title"), QStringLiteral("title1")); 0195 QVERIFY(c->sameEntry(e1, e2) > Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0196 0197 // matching series and issue makes a perfect match 0198 e2->setField(QStringLiteral("series"), QStringLiteral("series1")); 0199 e2->setField(QStringLiteral("issue"), QStringLiteral("1")); 0200 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0201 } 0202 0203 void EntryComparisonTest::testVideoMatch() { 0204 Tellico::Data::CollPtr c(new Tellico::Data::VideoCollection(true)); 0205 Tellico::Data::FieldPtr f(new Tellico::Data::Field(QStringLiteral("imdb"), 0206 QStringLiteral("IMDB"), 0207 Tellico::Data::Field::URL)); 0208 c->addField(f); 0209 0210 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0211 e1->setField(QStringLiteral("title"), QStringLiteral("the man from snowy river")); 0212 e1->setField(QStringLiteral("year"), QStringLiteral("1982")); 0213 e1->setField(QStringLiteral("director"), QStringLiteral("a director")); 0214 e1->setField(QStringLiteral("studio"), QStringLiteral("studio 7")); 0215 c->addEntries(e1); 0216 0217 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0218 e2->setField(QStringLiteral("title"), QStringLiteral("man from snowy river, the")); 0219 0220 // not a good match 0221 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0222 0223 // matching the year makes a good match 0224 e2->setField(QStringLiteral("year"), QStringLiteral("1982")); 0225 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0226 0227 // matching the title exactly and year makes a perfect match 0228 e2->setField(QStringLiteral("title"), QStringLiteral("the man from snowy river")); 0229 e2->setField(QStringLiteral("year"), QStringLiteral("1982")); 0230 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0231 0232 // imdb link should be pefect match by itself, ignoring host 0233 e1->setField(QStringLiteral("imdb"), QLatin1String("https://www.imdb.com/title/tt1856080/")); 0234 e2->setField(QStringLiteral("imdb"), QLatin1String("https://us.imdb.com/title/tt1856080/")); 0235 e2->setField(QStringLiteral("title"), QString()); 0236 e2->setField(QStringLiteral("year"), QString()); 0237 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0238 } 0239 0240 void EntryComparisonTest::testMusicMatch() { 0241 Tellico::Data::CollPtr c(new Tellico::Data::MusicCollection(true)); 0242 0243 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0244 e1->setField(QStringLiteral("title"), QStringLiteral("title1")); 0245 e1->setField(QStringLiteral("artist"), QStringLiteral("artist1")); 0246 e1->setField(QStringLiteral("label"), QStringLiteral("label")); 0247 e1->setField(QStringLiteral("year"), QStringLiteral("1994")); 0248 c->addEntries(e1); 0249 0250 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0251 e2->setField(QStringLiteral("title"), QStringLiteral("title2")); 0252 e2->setField(QStringLiteral("artist"), QStringLiteral("artist2")); 0253 0254 // not a good match 0255 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0256 0257 // matching the title and artist makes a good match 0258 e2->setField(QStringLiteral("title"), QStringLiteral("title1")); 0259 e2->setField(QStringLiteral("artist"), QStringLiteral("artist1")); 0260 QVERIFY(c->sameEntry(e1, e2) > Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0261 0262 e2->setField(QStringLiteral("label"), QStringLiteral("label")); 0263 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0264 e2->setField(QStringLiteral("label"), QString()); 0265 e2->setField(QStringLiteral("year"), QStringLiteral("1994")); 0266 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0267 } 0268 0269 void EntryComparisonTest::testGameMatch() { 0270 Tellico::Data::CollPtr c(new Tellico::Data::GameCollection(true)); 0271 0272 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0273 e1->setField(QStringLiteral("title"), QStringLiteral("title1")); 0274 e1->setField(QStringLiteral("platform"), QStringLiteral("Xbox One")); 0275 e1->setField(QStringLiteral("publisher"), QStringLiteral("publisher")); 0276 e1->setField(QStringLiteral("year"), QStringLiteral("1994")); 0277 c->addEntries(e1); 0278 0279 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0280 e2->setField(QStringLiteral("title"), QStringLiteral("title2")); 0281 e2->setField(QStringLiteral("platform"), QStringLiteral("Xbox One")); 0282 0283 // not a good match 0284 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0285 0286 e2->setField(QStringLiteral("title"), QStringLiteral("title1")); 0287 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0288 0289 e2->setField(QStringLiteral("publisher"), QStringLiteral("publisher")); 0290 e2->setField(QStringLiteral("year"), QStringLiteral("1994")); 0291 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0292 } 0293 0294 void EntryComparisonTest::testFileMatch() { 0295 QUrl url = QUrl::fromLocalFile(QFINDTESTDATA("data/test.ris")); 0296 Tellico::Data::CollPtr c(new Tellico::Data::FileCatalog(true)); 0297 0298 // first check merging with same isbn 0299 Tellico::Data::EntryPtr e1(new Tellico::Data::Entry(c)); 0300 e1->setField(QStringLiteral("url"), url.url()); 0301 e1->setField(QStringLiteral("title"), QStringLiteral("file.name")); 0302 e1->setField(QStringLiteral("description"), QStringLiteral("desc")); 0303 e1->setField(QStringLiteral("mimetype"), QStringLiteral("text/plain")); 0304 e1->setField(QStringLiteral("size"), QStringLiteral("1234")); 0305 e1->setField(QStringLiteral("volume"), QStringLiteral("vol1")); 0306 c->addEntries(e1); 0307 0308 Tellico::Data::EntryPtr e2(new Tellico::Data::Entry(c)); 0309 e2->setField(QStringLiteral("url"), url.url()); 0310 e2->setField(QStringLiteral("title"), QStringLiteral("file.name")); 0311 0312 // perfect match by file url 0313 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0314 0315 e2->setField(QStringLiteral("url"), QString()); 0316 QVERIFY(c->sameEntry(e1, e2) == Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0317 0318 e2->setField(QStringLiteral("description"), QStringLiteral("desc")); 0319 QVERIFY(c->sameEntry(e1, e2) > Tellico::EntryComparison::ENTRY_GOOD_MATCH); 0320 QVERIFY(c->sameEntry(e1, e2) < Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0321 e2->setField(QStringLiteral("mimetype"), QStringLiteral("text/plain")); 0322 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0323 0324 e2->setField(QStringLiteral("description"), QString()); 0325 e2->setField(QStringLiteral("mimetype"), QString()); 0326 e2->setField(QStringLiteral("size"), QStringLiteral("1234")); 0327 QVERIFY(c->sameEntry(e1, e2) >= Tellico::EntryComparison::ENTRY_PERFECT_MATCH); 0328 0329 // if volume is different, can't be same match 0330 e2->setField(QStringLiteral("volume"), QStringLiteral("vol2")); 0331 QVERIFY(c->sameEntry(e1, e2) <= Tellico::EntryComparison::ENTRY_BAD_MATCH); 0332 }