File indexing completed on 2024-05-12 11:58:44

0001 /*
0002  *   SPDX-FileCopyrightText: 2009 Petri Damstén <damu@iki.fi>
0003  *
0004  *   SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #include "convertertest.h"
0008 #include <QStandardPaths>
0009 #include <QThread>
0010 #include <QVector>
0011 #include <currency_p.h>
0012 #include <kunitconversion/unitcategory.h>
0013 
0014 using namespace KUnitConversion;
0015 using namespace std::chrono_literals;
0016 
0017 void ConverterTest::initTestCase()
0018 {
0019     QStandardPaths::setTestModeEnabled(true);
0020 
0021     // Remove currency cache to force a download
0022     const QString cache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/libkunitconversion/currency.xml");
0023     QFile::remove(cache);
0024 }
0025 
0026 void ConverterTest::testCategory()
0027 {
0028     Converter c;
0029     QCOMPARE(c.categoryForUnit(QStringLiteral("km")).id(), LengthCategory);
0030     QCOMPARE(c.category(QStringLiteral("Length")).id(), LengthCategory);
0031     QCOMPARE(c.category(LengthCategory).name(), QStringLiteral("Length"));
0032     QVERIFY(c.categories().size() > 0);
0033 }
0034 
0035 void ConverterTest::testUnits()
0036 {
0037     Converter c;
0038     QCOMPARE(c.unit(QStringLiteral("km")).symbol(), QStringLiteral("km"));
0039     QCOMPARE(c.unit(Kilogram).symbol(), QStringLiteral("kg"));
0040 }
0041 
0042 void ConverterTest::testConvert()
0043 {
0044     Converter c;
0045     Value v = c.convert(Value(3.14, Kilometer), QStringLiteral("m"));
0046     QCOMPARE(v.number(), 3140.0);
0047     v = c.convert(v, QStringLiteral("cm"));
0048     QCOMPARE(v.number(), 314000.0);
0049     v = c.convert(v, c.category(LengthCategory).defaultUnit());
0050     QCOMPARE(v.number(), 3140.0);
0051 
0052     v = Value(8.0, LitersPer100Kilometers);
0053     v = c.convert(v, QStringLiteral("mpg"));
0054     QCOMPARE(v.number(), 29.401875);
0055     v = c.convert(v, QStringLiteral("mpg (imperial)"));
0056     QCOMPARE(v.number(), 35.310125);
0057     v = c.convert(v, QStringLiteral("kmpl"));
0058     QCOMPARE(v.number(), 12.5);
0059     v = c.convert(v, QStringLiteral("l/100 km"));
0060     QCOMPARE(v.number(), 8.0);
0061 
0062     v = Value(33.0, MilePerUsGallon);
0063     v = c.convert(v, QStringLiteral("mpg (imperial)"));
0064     QCOMPARE(v.number(), 39.63128627);
0065     v = c.convert(v, QStringLiteral("kmpl"));
0066     QCOMPARE(v.number(), 14.0297174925);
0067     v = c.convert(v, QStringLiteral("l/100 km"));
0068     QCOMPARE(v.number(), 7.12772727273);
0069     v = c.convert(v, QStringLiteral("mpg"));
0070     QCOMPARE(v.number(), 33.0);
0071 }
0072 
0073 void ConverterTest::testInvalid()
0074 {
0075     Converter c;
0076     QCOMPARE(c.categoryForUnit(QStringLiteral("does not exist")).id(), InvalidCategory);
0077     QCOMPARE(c.unit(QStringLiteral("does not exist")).symbol(), QString());
0078     QCOMPARE(c.category(QStringLiteral("does not exist")).name(), QString());
0079 }
0080 
0081 class CurrencyTestThread : public QThread
0082 {
0083 public:
0084     CurrencyTestThread(Converter &c)
0085         : m_c(c)
0086     {
0087     }
0088     void run() override
0089     {
0090         Value input = Value(1000, Eur);
0091         Value v = m_c.convert(input, QStringLiteral("$"));
0092         number = v.number();
0093     }
0094     int number;
0095     Converter &m_c;
0096 };
0097 
0098 void ConverterTest::testCurrency()
0099 {
0100     Converter c;
0101     // 2 threads is enough for tsan to notice races, let's not hammer the website with more concurrent requests
0102     const int numThreads = 2;
0103     QVector<CurrencyTestThread *> threads;
0104     threads.resize(numThreads);
0105     for (int i = 0; i < numThreads; ++i) {
0106         threads[i] = new CurrencyTestThread(c);
0107     }
0108     for (int i = 0; i < numThreads; ++i) {
0109         threads[i]->start();
0110     }
0111     for (int i = 0; i < numThreads; ++i) {
0112         threads[i]->wait();
0113         QVERIFY(threads.at(i)->number > 100);
0114     }
0115     qDeleteAll(threads);
0116 }
0117 
0118 void ConverterTest::testCurrencyConversionTableUpdate()
0119 {
0120     const QString cache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/libkunitconversion/currency.xml");
0121 
0122     // Missing conversion table must lead to update of table
0123     // note that this is the same code path as for last modified updates
0124     QFile::remove(cache);
0125     QVERIFY(Currency::lastConversionTableUpdate().isNull());
0126     Converter c;
0127     Value input = Value(1000, Eur);
0128     Value v = c.convert(input, QStringLiteral("$"));
0129     QVERIFY(!Currency::lastConversionTableUpdate().isNull());
0130 }
0131 
0132 QTEST_MAIN(ConverterTest)
0133 
0134 #include "moc_convertertest.cpp"