File indexing completed on 2024-05-19 05:05:52

0001 /***************************************************************************
0002  *   SPDX-License-Identifier: GPL-2.0-or-later
0003  *                                                                         *
0004  *   SPDX-FileCopyrightText: 2004-2023 Thomas Fischer <fischer@unix-ag.uni-kl.de>
0005  *                                                                         *
0006  *   This program is free software; you can redistribute it and/or modify  *
0007  *   it under the terms of the GNU General Public License as published by  *
0008  *   the Free Software Foundation; either version 2 of the License, or     *
0009  *   (at your option) any later version.                                   *
0010  *                                                                         *
0011  *   This program is distributed in the hope that it will be useful,       *
0012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
0013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
0014  *   GNU General Public License for more details.                          *
0015  *                                                                         *
0016  *   You should have received a copy of the GNU General Public License     *
0017  *   along with this program; if not, see <https://www.gnu.org/licenses/>. *
0018  ***************************************************************************/
0019 
0020 #include <QtTest>
0021 
0022 #include <FileExporterBibTeX>
0023 #include <FileImporterBibTeX>
0024 #include <Value>
0025 #include <Entry>
0026 #include <Macro>
0027 
0028 class KBibTeXDataTest : public QObject
0029 {
0030     Q_OBJECT
0031 
0032 private Q_SLOTS:
0033     void initTestCase();
0034 
0035     /**
0036      * This test is not designed to fail under regular circumstances.
0037      * Instead, this test should be run with 'valgrind' to observe any
0038      * irregularities in memory management or access.
0039      */
0040     void createAndRemoveValueFromEntries();
0041 
0042     void sortFileByIdentifier_data();
0043     void sortFileByIdentifier();
0044 
0045     void rearrangingCrossRefEntries_data();
0046     void rearrangingCrossRefEntries();
0047 
0048     void beautifyingMonths_data();
0049     void beautifyingMonths();
0050 
0051 private:
0052 };
0053 
0054 
0055 void KBibTeXDataTest::createAndRemoveValueFromEntries()
0056 {
0057     static const QString keyData[] = {Entry::ftAuthor, Entry::ftISBN};
0058 
0059     Entry entry;
0060     for (const QString &key : keyData) {
0061         for (int i = 0; i < 2; ++i) {
0062             entry.remove(key);
0063             Value v;
0064             entry.insert(key, v);
0065         }
0066     }
0067 }
0068 
0069 void KBibTeXDataTest::sortFileByIdentifier_data()
0070 {
0071     QTest::addColumn<File *>("unsortedBibTeXfile");
0072     QTest::addColumn<File *>("sortedBibTeXfile");
0073 
0074     QSharedPointer<Macro> mA{new Macro(QStringLiteral("mA"), Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Macro A"))))};
0075     QSharedPointer<Macro> mB{new Macro(QStringLiteral("mB"), Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Macro B"))))};
0076     QSharedPointer<Macro> mC{new Macro(QStringLiteral("mC"), Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Macro C"))))};
0077     QSharedPointer<Macro> mD{new Macro(QStringLiteral("mD"), Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Macro D"))))};
0078 
0079     QSharedPointer<Entry> aaabbb{new Entry(Entry::etBook, QStringLiteral("aaabbb"))};
0080     aaabbb->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Companion of the Duality of Polymorphism}"))));
0081     aaabbb->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Winston"), QStringLiteral("Smith"))));
0082     aaabbb->insert(Entry::ftPublisher, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Black Books"))));
0083     aaabbb->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2005"))));
0084     QSharedPointer<Entry> bbbccc{new Entry(Entry::etArticle, QStringLiteral("bbbccc"))};
0085     bbbccc->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Glibberish}"))));
0086     bbbccc->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Bernard"), QStringLiteral("Marx"))));
0087     bbbccc->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2022"))));
0088     bbbccc->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("New Swabia Journal of Incomplete Algorithms"))));
0089     QSharedPointer<Entry> cccddd{new Entry(Entry::etArticle, QStringLiteral("cccddd"))};
0090     cccddd->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Nonsense}"))));
0091     cccddd->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Lenina"), QStringLiteral("Crowne"))));
0092     cccddd->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2019"))));
0093     cccddd->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("International Journal for the Advancement of Reversal"))));
0094     QSharedPointer<Entry> dddeee{new Entry(Entry::etArticle, QStringLiteral("dddeee"))};
0095     dddeee->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Bulls**t}"))));
0096     dddeee->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Thomas"), QStringLiteral("Grahambell"))));
0097     dddeee->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2021"))));
0098     dddeee->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Kot und K{\\\"o}ter"))));
0099     QSharedPointer<Entry> eeefff{new Entry(Entry::etArticle, QStringLiteral("eeefff"))};
0100     eeefff->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Bla Bla}"))));
0101     eeefff->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Helmholtz"), QStringLiteral("Watson"))));
0102     eeefff->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("1998"))));
0103     eeefff->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("New Journal of Old Things"))));
0104     QSharedPointer<Entry> fffggg{new Entry(Entry::etInBook, QStringLiteral("fffggg"))};
0105     fffggg->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Subsurface String Theory}"))));
0106     fffggg->insert(Entry::ftCrossRef, Value() << QSharedPointer<VerbatimText>(new VerbatimText(QStringLiteral("aaabbb"))));
0107     fffggg->insert(Entry::ftPages, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("42--56"))));
0108 
0109     File *unsortedFile = new File();
0110     unsortedFile->append(mD);
0111     unsortedFile->append(mA);
0112     unsortedFile->append(mB);
0113     unsortedFile->append(mC);
0114     File *sortedFile = new File();
0115     sortedFile->append(mA);
0116     sortedFile->append(mB);
0117     sortedFile->append(mC);
0118     sortedFile->append(mD);
0119     QTest::newRow("Only macros") << unsortedFile << sortedFile;
0120 
0121     unsortedFile = new File();
0122     unsortedFile->append(eeefff);
0123     unsortedFile->append(dddeee);
0124     unsortedFile->append(fffggg);
0125     unsortedFile->append(aaabbb);
0126     unsortedFile->append(bbbccc);
0127     unsortedFile->append(cccddd);
0128     sortedFile = new File();
0129     sortedFile->append(aaabbb);
0130     sortedFile->append(bbbccc);
0131     sortedFile->append(cccddd);
0132     sortedFile->append(dddeee);
0133     sortedFile->append(eeefff);
0134     sortedFile->append(fffggg);
0135     QTest::newRow("Only entries") << unsortedFile << sortedFile;
0136 
0137     unsortedFile = new File();
0138     unsortedFile->append(mD);
0139     unsortedFile->append(mA);
0140     unsortedFile->append(eeefff);
0141     unsortedFile->append(dddeee);
0142     unsortedFile->append(mB);
0143     unsortedFile->append(fffggg);
0144     unsortedFile->append(aaabbb);
0145     unsortedFile->append(bbbccc);
0146     unsortedFile->append(cccddd);
0147     unsortedFile->append(mC);
0148     sortedFile = new File();
0149     sortedFile->append(aaabbb);
0150     sortedFile->append(bbbccc);
0151     sortedFile->append(cccddd);
0152     sortedFile->append(dddeee);
0153     sortedFile->append(eeefff);
0154     sortedFile->append(fffggg);
0155     sortedFile->append(mA);
0156     sortedFile->append(mB);
0157     sortedFile->append(mC);
0158     sortedFile->append(mD);
0159     QTest::newRow("unsorted-entries.bib -> sorted-entries.bib") << unsortedFile << sortedFile;
0160 }
0161 
0162 void KBibTeXDataTest::sortFileByIdentifier()
0163 {
0164     QFETCH(File *, unsortedBibTeXfile);
0165     QFETCH(File *, sortedBibTeXfile);
0166 
0167     const File *newlySortedBibTeXfile = File::sortByIdentifier(unsortedBibTeXfile);
0168     QCOMPARE(*sortedBibTeXfile, *newlySortedBibTeXfile);
0169 }
0170 
0171 void KBibTeXDataTest::rearrangingCrossRefEntries_data()
0172 {
0173     QTest::addColumn<File *>("originalBibTeXfile");
0174     QTest::addColumn<File *>("rearrangedBibTeXfile");
0175 
0176     QSharedPointer<Entry> aaabbb{new Entry(Entry::etBook, QStringLiteral("aaabbb"))};
0177     aaabbb->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Companion of the Duality of Polymorphism}"))));
0178     aaabbb->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Winston"), QStringLiteral("Smith"))));
0179     aaabbb->insert(Entry::ftPublisher, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("Black Books"))));
0180     aaabbb->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2005"))));
0181     QSharedPointer<Entry> bbbccc{new Entry(Entry::etArticle, QStringLiteral("bbbccc"))};
0182     bbbccc->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Glibberish}"))));
0183     bbbccc->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Bernard"), QStringLiteral("Marx"))));
0184     bbbccc->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2022"))));
0185     bbbccc->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("New Swabia Journal of Incomplete Algorithms"))));
0186     QSharedPointer<Entry> cccddd{new Entry(Entry::etArticle, QStringLiteral("cccddd"))};
0187     cccddd->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Nonsense}"))));
0188     cccddd->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Lenina"), QStringLiteral("Crowne"))));
0189     cccddd->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2019"))));
0190     cccddd->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("International Journal for the Advancement of Reversal"))));
0191     QSharedPointer<Entry> dddeee{new Entry(Entry::etArticle, QStringLiteral("dddeee"))};
0192     dddeee->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Bulls**t}"))));
0193     dddeee->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Thomas"), QStringLiteral("Grahambell"))));
0194     dddeee->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("2021"))));
0195     dddeee->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QString::fromUtf8("Kot und K\xc3\xb6ter"))));
0196     QSharedPointer<Entry> eeefff{new Entry(Entry::etArticle, QStringLiteral("eeefff"))};
0197     eeefff->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Bla Bla}"))));
0198     eeefff->insert(Entry::ftAuthor, Value() << QSharedPointer<Person>(new Person(QStringLiteral("Helmholtz"), QStringLiteral("Watson"))));
0199     eeefff->insert(Entry::ftYear, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("1998"))));
0200     eeefff->insert(Entry::ftJournal, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("New Journal of Old Things"))));
0201     QSharedPointer<Entry> fffggg{new Entry(Entry::etInBook, QStringLiteral("fffggg"))};
0202     fffggg->insert(Entry::ftTitle, Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("{Subsurface String Theory}"))));
0203     fffggg->insert(Entry::ftCrossRef, Value() << QSharedPointer<VerbatimText>(new VerbatimText(QStringLiteral("aaabbb"))));
0204     fffggg->insert(Entry::ftPages, Value() << QSharedPointer<PlainText>(new PlainText(QString::fromUtf8("42\xe2\x80\x93""56"))));
0205 
0206     File *originalBibTeXfile = new File();
0207     originalBibTeXfile->append(aaabbb);
0208     originalBibTeXfile->append(eeefff);
0209     originalBibTeXfile->append(dddeee);
0210     originalBibTeXfile->append(fffggg);
0211     originalBibTeXfile->append(bbbccc);
0212     originalBibTeXfile->append(cccddd);
0213     File *rearrangedBibTeXfile = new File();
0214     rearrangedBibTeXfile->append(eeefff);
0215     rearrangedBibTeXfile->append(dddeee);
0216     rearrangedBibTeXfile->append(fffggg);
0217     rearrangedBibTeXfile->append(bbbccc);
0218     rearrangedBibTeXfile->append(cccddd);
0219     rearrangedBibTeXfile->append(aaabbb);
0220     QTest::newRow("Crossref'ed to end") << originalBibTeXfile << rearrangedBibTeXfile;
0221 
0222     originalBibTeXfile = new File();
0223     originalBibTeXfile->append(eeefff);
0224     originalBibTeXfile->append(dddeee);
0225     originalBibTeXfile->append(fffggg);
0226     originalBibTeXfile->append(aaabbb);
0227     originalBibTeXfile->append(bbbccc);
0228     originalBibTeXfile->append(cccddd);
0229     rearrangedBibTeXfile = new File();
0230     rearrangedBibTeXfile->append(eeefff);
0231     rearrangedBibTeXfile->append(dddeee);
0232     rearrangedBibTeXfile->append(fffggg);
0233     rearrangedBibTeXfile->append(aaabbb);
0234     rearrangedBibTeXfile->append(bbbccc);
0235     rearrangedBibTeXfile->append(cccddd);
0236     QTest::newRow("Crossref'ed after reference") << originalBibTeXfile << rearrangedBibTeXfile;
0237 }
0238 
0239 void KBibTeXDataTest::rearrangingCrossRefEntries()
0240 {
0241     QFETCH(File *, originalBibTeXfile);
0242     QFETCH(File *, rearrangedBibTeXfile);
0243 
0244     FileExporterBibTeX exporter(this);
0245     FileImporterBibTeX importer(this);
0246 
0247     File *savedBibTeXfile = importer.fromString(exporter.toString(originalBibTeXfile));
0248 
0249     QCOMPARE(*rearrangedBibTeXfile, *savedBibTeXfile);
0250 }
0251 
0252 void KBibTeXDataTest::beautifyingMonths_data()
0253 {
0254     QTest::addColumn<Value>("monthsInput");
0255     QTest::addColumn<QString>("expectedBeautification");
0256     QTest::addColumn<QString>("expectedWithoutBeautification");
0257 
0258     QTest::newRow("Empty value") << Value() << QString() << QString();
0259     QTest::newRow("Single month as macro key") << (Value() << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("apr")))) << QLocale::system().monthName(4) << QStringLiteral("apr");
0260     QTest::newRow("Single month as number") << (Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("6")))) << QLocale::system().monthName(6) << QStringLiteral("6");
0261     QTest::newRow("Two months as macro keys") << (Value() << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("apr"))) << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("may")))) << QLocale::system().monthName(4) + QChar(0x2013) + QLocale::system().monthName(5) << QStringLiteral("apr may");
0262     QTest::newRow("Two months as numbers") << (Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("4"))) << QSharedPointer<PlainText>(new PlainText(QStringLiteral("5")))) << QLocale::system().monthName(4) + QChar(0x2013) + QLocale::system().monthName(5) << QStringLiteral("4 5");
0263     QTest::newRow("Two months as macro keys, with # in between") << (Value() << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("apr"))) << QSharedPointer<PlainText>(new PlainText(QStringLiteral("#"))) << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("may")))) << QLocale::system().monthName(4) + QChar(0x2013) + QLocale::system().monthName(5) << QStringLiteral("apr # may");
0264     QTest::newRow("Two months as numbers, with # in between") << (Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("4")))  << QSharedPointer<PlainText>(new PlainText(QStringLiteral("#"))) << QSharedPointer<PlainText>(new PlainText(QStringLiteral("5")))) << QLocale::system().monthName(4) + QChar(0x2013) + QLocale::system().monthName(5) << QStringLiteral("4 # 5");
0265     QTest::newRow("Two months as macro keys, with -- in between") << (Value() << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("apr"))) << QSharedPointer<PlainText>(new PlainText(QStringLiteral("--"))) << QSharedPointer<MacroKey>(new MacroKey(QStringLiteral("may")))) << QLocale::system().monthName(4) + QChar(0x2013) + QLocale::system().monthName(5) << QStringLiteral("apr -- may");
0266     QTest::newRow("Two months as numbers, with -- in between") << (Value() << QSharedPointer<PlainText>(new PlainText(QStringLiteral("4")))  << QSharedPointer<PlainText>(new PlainText(QStringLiteral("--"))) << QSharedPointer<PlainText>(new PlainText(QStringLiteral("5")))) << QLocale::system().monthName(4) + QChar(0x2013) + QLocale::system().monthName(5) << QStringLiteral("4 -- 5");
0267 }
0268 
0269 void KBibTeXDataTest::beautifyingMonths()
0270 {
0271     QFETCH(Value, monthsInput);
0272     QFETCH(QString, expectedBeautification);
0273     QFETCH(QString, expectedWithoutBeautification);
0274 
0275     QCOMPARE(PlainTextValue::text(monthsInput, PlainTextValue::BeautifyMonth), expectedBeautification);
0276     QCOMPARE(PlainTextValue::text(monthsInput), expectedWithoutBeautification);
0277 }
0278 
0279 void KBibTeXDataTest::initTestCase()
0280 {
0281     // TODO
0282 }
0283 
0284 QTEST_MAIN(KBibTeXDataTest)
0285 
0286 #include "kbibtexdatatest.moc"