File indexing completed on 2024-04-21 14:59:03

0001 /*
0002     SPDX-FileCopyrightText: 2021 Volker Krause <vkrause@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include <KCountry>
0008 #include <KCountrySubdivision>
0009 
0010 #include <QObject>
0011 #include <QStandardPaths>
0012 #include <QTest>
0013 
0014 void initEnvironment()
0015 {
0016     qputenv("LANG", "fr_CH.UTF-8");
0017     QStandardPaths::setTestModeEnabled(true);
0018 }
0019 
0020 Q_CONSTRUCTOR_FUNCTION(initEnvironment)
0021 
0022 class KCountryTest : public QObject
0023 {
0024     Q_OBJECT
0025 private Q_SLOTS:
0026     void testEmpty()
0027     {
0028         KCountry c;
0029         QVERIFY(!c.isValid());
0030         QVERIFY(c.alpha2().isEmpty());
0031         QVERIFY(c.alpha3().isEmpty());
0032         QVERIFY(c.name().isEmpty());
0033         QVERIFY(c.emojiFlag().isEmpty());
0034         QVERIFY(c.subdivisions().isEmpty());
0035         QCOMPARE(c.country(), QLocale::AnyCountry);
0036         QVERIFY(c.currencyCode().isEmpty());
0037         QVERIFY(c.timeZoneIds().isEmpty());
0038     }
0039 
0040     void testLookup()
0041     {
0042         auto c = KCountry::fromAlpha2(u"NZ");
0043         QVERIFY(c.isValid());
0044         QCOMPARE(c.alpha2(), QLatin1String("NZ"));
0045         QCOMPARE(c.alpha3(), QLatin1String("NZL"));
0046         QCOMPARE(c.name(), QStringLiteral("Nouvelle-Zélande"));
0047         QCOMPARE(c.emojiFlag(), QStringLiteral("🇳🇿"));
0048         QCOMPARE(c.country(), QLocale::NewZealand);
0049         QCOMPARE(c.currencyCode(), QLatin1String("NZD"));
0050 
0051         c = KCountry::fromAlpha2("nz");
0052         QVERIFY(c.isValid());
0053         QCOMPARE(c.alpha2(), QLatin1String("NZ"));
0054 
0055         c = KCountry::fromAlpha3(u"NZL");
0056         QVERIFY(c.isValid());
0057         QCOMPARE(c.alpha2(), QLatin1String("NZ"));
0058 
0059         QVERIFY(!KCountry::fromAlpha2(QString()).isValid());
0060         QVERIFY(!KCountry::fromAlpha2(u"ZZ").isValid());
0061         QVERIFY(!KCountry::fromAlpha2(u"N").isValid());
0062         QVERIFY(!KCountry::fromAlpha2(u"NZL").isValid());
0063         QVERIFY(!KCountry::fromAlpha2(u"42").isValid());
0064         QVERIFY(!KCountry::fromAlpha2(nullptr).isValid());
0065         QVERIFY(!KCountry::fromAlpha2("N").isValid());
0066         QVERIFY(!KCountry::fromAlpha2("nzl").isValid());
0067         QVERIFY(!KCountry::fromAlpha2("\0\0").isValid());
0068 
0069         QVERIFY(!KCountry::fromAlpha3(u"ZZZ").isValid());
0070         QVERIFY(!KCountry::fromAlpha3(QString()).isValid());
0071         QVERIFY(!KCountry::fromAlpha3(u"NZ").isValid());
0072         QVERIFY(!KCountry::fromAlpha3(u"NEWZL").isValid());
0073         QVERIFY(!KCountry::fromAlpha3(u"123").isValid());
0074         QVERIFY(!KCountry::fromAlpha3(nullptr).isValid());
0075         QVERIFY(!KCountry::fromAlpha3("NZ").isValid());
0076         QVERIFY(!KCountry::fromAlpha3("nzla").isValid());
0077         QVERIFY(!KCountry::fromAlpha3("\0\0\0").isValid());
0078 
0079         QCOMPARE(KCountry::fromAlpha2(u"nz").alpha2(), QLatin1String("NZ"));
0080         QCOMPARE(KCountry::fromAlpha2(u"Nz").alpha2(), QLatin1String("NZ"));
0081         QCOMPARE(KCountry::fromAlpha3(u"nzl").alpha2(), QLatin1String("NZ"));
0082         QCOMPARE(KCountry::fromAlpha3(u"NzL").alpha2(), QLatin1String("NZ"));
0083 
0084         c = KCountry::fromQLocale(QLocale::NewZealand);
0085         QVERIFY(c.isValid());
0086         QCOMPARE(c.alpha2(), QLatin1String("NZ"));
0087 
0088         QVERIFY(!KCountry::fromQLocale(QLocale::AnyCountry).isValid());
0089         QVERIFY(!KCountry::fromQLocale(QLocale::World).isValid());
0090     }
0091 
0092     void benchmarkLookup()
0093     {
0094         QBENCHMARK {
0095             const auto c = KCountry::fromAlpha2(u"NZ");
0096             QVERIFY(c.isValid());
0097         }
0098     }
0099 
0100     void testList()
0101     {
0102         const auto l = KCountry::allCountries();
0103         QVERIFY(l.size() > 200);
0104         for (const auto &c : l) {
0105             QVERIFY(c.isValid());
0106             QVERIFY(!c.alpha2().isEmpty());
0107             QVERIFY(!c.alpha3().isEmpty());
0108             QVERIFY(!c.name().isEmpty());
0109             QVERIFY(!c.emojiFlag().isEmpty());
0110             QVERIFY(c.country() != QLocale::AnyCountry);
0111         }
0112     }
0113 
0114     void testTimezone()
0115     {
0116         auto tzs = KCountry::fromAlpha2("BE").timeZoneIds();
0117         QCOMPARE(tzs.size(), 1);
0118         QCOMPARE(tzs.at(0), "Europe/Brussels");
0119 
0120         tzs = KCountry::fromAlpha2("DE").timeZoneIds();
0121         QCOMPARE(tzs.size(), 1); // we don't want Europe/Busingen as well here
0122         QCOMPARE(tzs.at(0), "Europe/Berlin");
0123 
0124         tzs = KCountry::fromAlpha2("ES").timeZoneIds();
0125         QCOMPARE(tzs.size(), 3);
0126         QCOMPARE(tzs.at(0), "Europe/Madrid");
0127         QCOMPARE(tzs.at(1), "Africa/Ceuta");
0128         QCOMPARE(tzs.at(2), "Atlantic/Canary");
0129     }
0130 
0131     void testFromLocation_data()
0132     {
0133         QTest::addColumn<float>("lat");
0134         QTest::addColumn<float>("lon");
0135         QTest::addColumn<QString>("country");
0136         QTest::addColumn<bool>("canBeConflict"); // for test close to the border, no result is acceptable, a wrong one isn't
0137 
0138         QTest::newRow("invalid") << 400.0f << 25.0f << QString() << false;
0139         QTest::newRow("out-of-coverage") << -90.0f << 0.0f << QString() << false;
0140 
0141         // basic checks in all quadrants
0142         QTest::newRow("BR") << -8.0f << -35.0f << QStringLiteral("BR") << false;
0143         QTest::newRow("CA") << 44.0f << -79.5f << QStringLiteral("CA") << false;
0144         QTest::newRow("DE") << 52.4f << 13.1f << QStringLiteral("DE") << false;
0145         QTest::newRow("NZ") << -36.5f << 175.0f << QStringLiteral("NZ") << false;
0146 
0147         // important KDE locations
0148         QTest::newRow("Randa") << 46.0998f << 7.781469f << QStringLiteral("CH") << false;
0149 
0150         // Maastricht (NL), very close to the BE border
0151         QTest::newRow("Maastricht") << 50.8505f << 5.6881f << QStringLiteral("NL") << true;
0152         // Aachen, at the BE/DE/NL corner
0153         QTest::newRow("Aachen") << 50.7717f << 6.04235f << QStringLiteral("DE") << true;
0154         // Geneva (CH), very close to the FR border
0155         QTest::newRow("Geneva") << 46.23213f << 6.10636f << QStringLiteral("CH") << true;
0156         // Busingen (DE), enclosed by CH
0157         QTest::newRow("Busingen") << 47.69947f << 8.68833f << QStringLiteral("DE") << true;
0158         // Tijuana (MX), close to US
0159         QTest::newRow("Tijuana") << 32.54274f << -116.97505f << QStringLiteral("MX") << true;
0160 
0161         // Baarle, the ultimate special case, NL/BE differs house by house
0162         QTest::newRow("you-got-to-be-kidding-me") << 51.44344f << 4.93373f << QString() << false;
0163     }
0164 
0165     void testFromLocation()
0166     {
0167         QFETCH(float, lat);
0168         QFETCH(float, lon);
0169         QFETCH(QString, country);
0170         QFETCH(bool, canBeConflict);
0171 
0172         auto c = KCountry::fromLocation(lat, lon);
0173         if (!canBeConflict || c.isValid()) {
0174             QCOMPARE(c.alpha2(), country);
0175         }
0176     }
0177 
0178     void testFromName()
0179     {
0180         QVERIFY(!KCountry::fromName(u"").isValid());
0181         QVERIFY(!KCountry::fromName(u"Disneyland").isValid());
0182 
0183         QCOMPARE(KCountry::fromName(u"new zealand").alpha2(), QLatin1String("NZ"));
0184         QCOMPARE(KCountry::fromName(u"Nouvelle-Zélande").alpha2(), QLatin1String("NZ"));
0185         QCOMPARE(KCountry::fromName(u"NEUSEELAND").alpha2(), QLatin1String("NZ"));
0186 
0187         // diacritic normalization
0188         QCOMPARE(KCountry::fromName(u"Österreich").alpha2(), QLatin1String("AT"));
0189         QCOMPARE(KCountry::fromName(u"Østrig").alpha2(), QLatin1String("AT"));
0190         QCOMPARE(KCountry::fromName(u"osterreich").alpha2(), QLatin1String("AT"));
0191         QCOMPARE(KCountry::fromName(u"대한민국").alpha2(), QLatin1String("KR"));
0192 
0193         // unique prefix/suffix
0194         QCOMPARE(KCountry::fromName(u"United States").alpha2(), QLatin1String("US"));
0195         QCOMPARE(KCountry::fromName(u"Ünīted  States\nOf Amérìcâ").alpha2(), QLatin1String("US"));
0196         QCOMPARE(KCountry::fromName(u"Arab Emirates").alpha2(), QLatin1String("AE"));
0197         QCOMPARE(KCountry::fromName(u"United").alpha2(), QString());
0198         QCOMPARE(KCountry::fromName(u"Bundesrepuplik Deutschland").alpha2(), QLatin1String("DE"));
0199 
0200         // code fallbacks
0201         QCOMPARE(KCountry::fromName(u"USA").alpha2(), QLatin1String("US"));
0202     }
0203 
0204     void benchmarkFromName()
0205     {
0206         QBENCHMARK {
0207             QCOMPARE(KCountry::fromName(u"Nouvelle-Zélande").alpha2(), QLatin1String("NZ"));
0208         }
0209     }
0210 };
0211 
0212 QTEST_GUILESS_MAIN(KCountryTest)
0213 
0214 #include "kcountrytest.moc"