File indexing completed on 2024-04-21 14:54:24
0001 /* 0002 SPDX-FileCopyrightText: 2022 Volker Krause <vkrause@kde.org> 0003 SPDX-License-Identifier: LGPL-2.0-or-later 0004 */ 0005 0006 #include "addressformat.h" 0007 #include "addressformatparser.cpp" 0008 #include "addressformatscript.cpp" 0009 #include "addressformatter.cpp" 0010 0011 #include <KConfig> 0012 #include <KConfigGroup> 0013 #include <KCountry> 0014 0015 #include <QObject> 0016 #include <QRegularExpression> 0017 #include <QTest> 0018 0019 using namespace KContacts; 0020 0021 void initLocale() 0022 { 0023 qputenv("LANGUAGE", "en_US"); 0024 QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedStates)); 0025 } 0026 0027 Q_CONSTRUCTOR_FUNCTION(initLocale) 0028 0029 class AddressFormatTest : public QObject 0030 { 0031 Q_OBJECT 0032 private: 0033 AddressFormat parseFormat(QStringView f, QStringView u, QStringView country) 0034 { 0035 AddressFormat format; 0036 auto fmt = AddressFormatPrivate::get(format); 0037 fmt->upper = AddressFormatParser::parseFields(u); 0038 fmt->elements = AddressFormatParser::parseElements(f); 0039 fmt->country = country.toString(); 0040 return format; 0041 } 0042 0043 private Q_SLOTS: 0044 void testRepostory() 0045 { 0046 auto fmt = AddressFormatRepository::formatForCountry(QStringLiteral("CA"), AddressFormatScriptPreference::Local); 0047 QCOMPARE(fmt.requiredFields(), 0048 AddressFormatField::StreetAddress | AddressFormatField::Locality | AddressFormatField::PostalCode | AddressFormatField::Region); 0049 QCOMPARE(fmt.upperCaseFields(), 0050 AddressFormatField::StreetAddress | AddressFormatField::Locality | AddressFormatField::PostalCode | AddressFormatField::Region 0051 | AddressFormatField::Name | AddressFormatField::Organization | AddressFormatField::Country); 0052 QCOMPARE(fmt.usedFields(), 0053 AddressFormatField::StreetAddress | AddressFormatField::Locality | AddressFormatField::PostalCode | AddressFormatField::Region 0054 | AddressFormatField::Name | AddressFormatField::Organization | AddressFormatField::PostOfficeBox); 0055 const auto &elems = fmt.elements(); 0056 QCOMPARE(elems.size(), 14); 0057 0058 QCOMPARE(elems[0].isField(), true); 0059 QCOMPARE(elems[0].field(), AddressFormatField::Name); 0060 QCOMPARE(elems[1].isSeparator(), true); 0061 QCOMPARE(elems[2].isField(), true); 0062 QCOMPARE(elems[2].field(), AddressFormatField::Organization); 0063 QCOMPARE(elems[3].isSeparator(), true); 0064 QCOMPARE(elems[6].isLiteral(), true); 0065 QCOMPARE(elems[6].literal(), QLatin1String("PO BOX ")); 0066 QCOMPARE(elems[9].isField(), true); 0067 QCOMPARE(elems[9].field(), AddressFormatField::Locality); 0068 QCOMPARE(elems[10].isLiteral(), true); 0069 QCOMPARE(elems[10].literal(), QLatin1String(" ")); 0070 QCOMPARE(elems[11].isField(), true); 0071 QCOMPARE(elems[11].field(), AddressFormatField::Region); 0072 QCOMPARE(elems[12].isLiteral(), true); 0073 QCOMPARE(elems[12].literal(), QLatin1String(" ")); 0074 QCOMPARE(elems[13].isField(), true); 0075 QCOMPARE(elems[13].field(), AddressFormatField::PostalCode); 0076 0077 QVERIFY(!fmt.postalCodeRegularExpression().isEmpty()); 0078 QCOMPARE(fmt.country(), QLatin1String("CA")); 0079 } 0080 0081 void testFormatStyles() 0082 { 0083 Address addr; 0084 addr.setCountry(QStringLiteral("DE")); 0085 addr.setRegion(QStringLiteral("BE")); 0086 addr.setLocality(QStringLiteral("Berlin")); 0087 addr.setPostalCode(QStringLiteral("10969")); 0088 addr.setStreet(QStringLiteral("Prinzenstraße 85 F")); 0089 addr.setExtended(QStringLiteral("East wing")); 0090 0091 auto fmt = parseFormat(u"%O%n%N%nPostfach %P%n%A%n%Z %C", u"R", u"DE"); 0092 auto s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::Postal); 0093 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nEast wing\nPrinzenstraße 85 F\n10969 Berlin\n\nGERMANY")); 0094 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::MultiLineInternational); 0095 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nEast wing\nPrinzenstraße 85 F\n10969 Berlin\nGermany")); 0096 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::MultiLineDomestic); 0097 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nEast wing\nPrinzenstraße 85 F\n10969 Berlin")); 0098 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::SingleLineInternational); 0099 QCOMPARE(s, QStringLiteral("KDE e.V., Dr. Konqi, East wing, Prinzenstraße 85 F, 10969 Berlin, Germany")); 0100 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::SingleLineDomestic); 0101 QCOMPARE(s, QStringLiteral("KDE e.V., Dr. Konqi, East wing, Prinzenstraße 85 F, 10969 Berlin")); 0102 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::GeoUriQuery); 0103 QCOMPARE(s, QStringLiteral("Prinzenstraße 85 F,10969 Berlin,DE")); 0104 0105 addr.setExtended(QString()); 0106 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::Postal); 0107 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nPrinzenstraße 85 F\n10969 Berlin\n\nGERMANY")); 0108 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::MultiLineInternational); 0109 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nPrinzenstraße 85 F\n10969 Berlin\nGermany")); 0110 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::MultiLineDomestic); 0111 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nPrinzenstraße 85 F\n10969 Berlin")); 0112 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::SingleLineInternational); 0113 QCOMPARE(s, QStringLiteral("KDE e.V., Dr. Konqi, Prinzenstraße 85 F, 10969 Berlin, Germany")); 0114 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::SingleLineDomestic); 0115 QCOMPARE(s, QStringLiteral("KDE e.V., Dr. Konqi, Prinzenstraße 85 F, 10969 Berlin")); 0116 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::GeoUriQuery); 0117 QCOMPARE(s, QStringLiteral("Prinzenstraße 85 F,10969 Berlin,DE")); 0118 0119 addr.setPostOfficeBox(QStringLiteral("42")); 0120 addr.setStreet(QString()); 0121 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::Postal); 0122 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nPostfach 42\n10969 Berlin\n\nGERMANY")); 0123 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::MultiLineInternational); 0124 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nPostfach 42\n10969 Berlin\nGermany")); 0125 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::MultiLineDomestic); 0126 QCOMPARE(s, QStringLiteral("KDE e.V.\nDr. Konqi\nPostfach 42\n10969 Berlin")); 0127 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::SingleLineInternational); 0128 QCOMPARE(s, QStringLiteral("KDE e.V., Dr. Konqi, Postfach 42, 10969 Berlin, Germany")); 0129 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::SingleLineDomestic); 0130 QCOMPARE(s, QStringLiteral("KDE e.V., Dr. Konqi, Postfach 42, 10969 Berlin")); 0131 s = AddressFormatter::format(addr, QStringLiteral("Dr. Konqi"), QStringLiteral("KDE e.V."), fmt, AddressFormatStyle::GeoUriQuery); 0132 QCOMPARE(s, QStringLiteral("10969 Berlin,DE")); 0133 } 0134 0135 void testFormatScript() 0136 { 0137 KContacts::Address address; 0138 address.setCountry(QStringLiteral("JP")); 0139 address.setRegion(QStringLiteral("東京")); 0140 address.setLocality(QStringLiteral("都港区")); 0141 address.setPostalCode(QStringLiteral("106-0047")); 0142 address.setStreet(QStringLiteral("南麻布 4-6-28")); 0143 auto fmt = parseFormat(u"〒%Z%n%S%C%A%n%O%n%N", u"SR", u"JP"); 0144 auto s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::SingleLineDomestic); 0145 QCOMPARE(s, QStringLiteral("〒106-0047東京都港区南麻布 4-6-28")); 0146 0147 address = {}; 0148 address.setCountry(QStringLiteral("EG")); 0149 address.setLocality(QStringLiteral("القاهرة")); 0150 address.setStreet(QStringLiteral("2005ج كورنيش النيل، رملة بولاق")); 0151 fmt = parseFormat(u"%N%n%O%n%A%n%C%n%S%n%Z", u"", u"EG"); 0152 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::SingleLineDomestic); 0153 QCOMPARE(s, QStringLiteral("2005ج كورنيش النيل، رملة بولاق، القاهرة")); 0154 0155 address = {}; 0156 address.setCountry(QStringLiteral("KR")); 0157 address.setRegion(QStringLiteral("서울특별시")); 0158 address.setLocality(QStringLiteral("중구")); 0159 address.setPostalCode(QStringLiteral("04637")); 0160 address.setStreet(QStringLiteral("한강대로 416")); 0161 fmt = parseFormat(u"%R%n%S %C%D%n%A%n%O%n%N%n%Z", u"Z", u"KR"); 0162 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::SingleLineDomestic); 0163 QCOMPARE(s, QStringLiteral("서울특별시 중구 한강대로 416 04637")); 0164 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::MultiLineDomestic); 0165 QCOMPARE(s, QStringLiteral("서울특별시 중구\n한강대로 416\n04637")); 0166 // the weird language mix is because we are in the wrong locale for KR here, 0167 // the important part is that the country is in the front when using Hangul 0168 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::SingleLineInternational); 0169 QCOMPARE(s, QStringLiteral("Korea, Republic of 서울특별시 중구 한강대로 416 04637")); 0170 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::MultiLineInternational); 0171 QCOMPARE(s, QStringLiteral("Korea, Republic of\n서울특별시 중구\n한강대로 416\n04637")); 0172 0173 // reverse order address lines 0174 address.setExtended(QStringLiteral("서울스퀘어 11층")); 0175 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::SingleLineDomestic); 0176 QCOMPARE(s, QStringLiteral("서울특별시 중구 한강대로 416 서울스퀘어 11층 04637")); 0177 s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::MultiLineDomestic); 0178 QCOMPARE(s, QStringLiteral("서울특별시 중구\n한강대로 416\n서울스퀘어 11층\n04637")); 0179 } 0180 0181 void testIncompleteAddress() 0182 { 0183 KContacts::Address address; 0184 address.setLocality(QStringLiteral("City")); 0185 address.setPostalCode(QStringLiteral("XX 12345")); // region wrongly part of postal code field 0186 0187 auto fmt = parseFormat(u"%C, %S %Z", u"", u"US"); 0188 auto s = AddressFormatter::format(address, QString(), QString(), fmt, AddressFormatStyle::MultiLineDomestic); 0189 QCOMPARE(s, QLatin1String("City XX 12345")); 0190 } 0191 0192 void validateRepository() 0193 { 0194 KConfig config(QStringLiteral(":/org.kde.kcontacts/addressformatrc"), KConfig::SimpleConfig); 0195 const auto groups = config.groupList(); 0196 0197 for (const auto &countryCode : groups) { 0198 // qDebug() << countryCode; 0199 QVERIFY(KCountry::fromAlpha2(countryCode).isValid()); 0200 const auto group = config.group(countryCode); 0201 0202 QVERIFY(group.hasKey("AddressFormat")); 0203 const auto upper = AddressFormatParser::parseFields(group.readEntry("Upper")); 0204 const auto required = AddressFormatParser::parseFields(group.readEntry("Required")); 0205 0206 // TODO can we check all language variants as well? 0207 for (const auto &key : {"AddressFormat", "BusinessAddressFormat", "LatinAddressFormat", "LatinBusinessAddressFormat"}) { 0208 if (!group.hasKey(key)) { 0209 continue; 0210 } 0211 const auto elems = AddressFormatParser::parseElements(group.readEntry(key, QString())); 0212 0213 AddressFormatFields seen = AddressFormatField::NoField; 0214 for (const auto &elem : elems) { 0215 if (!elem.isField()) { 0216 continue; 0217 } 0218 QCOMPARE(seen & elem.field() & ~(int)AddressFormatField::SortingCode, 0); 0219 seen |= elem.field(); 0220 } 0221 0222 QCOMPARE(seen & required, required); 0223 QCOMPARE(seen & upper & ~(int)AddressFormatField::Country, upper & ~(int)AddressFormatField::Country); 0224 } 0225 0226 const auto zipRegEx = group.readEntry("PostalCodeFormat", QString()); 0227 if (!zipRegEx.isEmpty()) { 0228 QVERIFY(QRegularExpression(zipRegEx).isValid()); 0229 } 0230 } 0231 } 0232 }; 0233 0234 QTEST_GUILESS_MAIN(AddressFormatTest) 0235 0236 #include "addressformattest.moc"