| 1 | /**************************************************************************** |
| 2 | ** |
| 3 | ** Copyright (C) 2020 The Qt Company Ltd. |
| 4 | ** Contact: https://www.qt.io/licensing/ |
| 5 | ** |
| 6 | ** This file is part of the test suite of the Qt Toolkit. |
| 7 | ** |
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ |
| 9 | ** Commercial License Usage |
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in |
| 11 | ** accordance with the commercial license agreement provided with the |
| 12 | ** Software or, alternatively, in accordance with the terms contained in |
| 13 | ** a written agreement between you and The Qt Company. For licensing terms |
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further |
| 15 | ** information use the contact form at https://www.qt.io/contact-us. |
| 16 | ** |
| 17 | ** GNU General Public License Usage |
| 18 | ** Alternatively, this file may be used under the terms of the GNU |
| 19 | ** General Public License version 3 as published by the Free Software |
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT |
| 21 | ** included in the packaging of this file. Please review the following |
| 22 | ** information to ensure the GNU General Public License requirements will |
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. |
| 24 | ** |
| 25 | ** $QT_END_LICENSE$ |
| 26 | ** |
| 27 | ****************************************************************************/ |
| 28 | |
| 29 | |
| 30 | #include <QtTest/QtTest> |
| 31 | #include <math.h> |
| 32 | #include <qdebug.h> |
| 33 | #include <qdir.h> |
| 34 | #include <qfileinfo.h> |
| 35 | #include <QScopedArrayPointer> |
| 36 | #include <qtextcodec.h> |
| 37 | #include <qdatetime.h> |
| 38 | #if QT_CONFIG(process) |
| 39 | # include <qprocess.h> |
| 40 | #endif |
| 41 | #include <float.h> |
| 42 | #include <locale.h> |
| 43 | |
| 44 | #include <qlocale.h> |
| 45 | #include <private/qlocale_p.h> |
| 46 | #include <private/qlocale_tools_p.h> |
| 47 | #include <qnumeric.h> |
| 48 | |
| 49 | #if defined(Q_OS_LINUX) && !defined(__UCLIBC__) |
| 50 | # define QT_USE_FENV |
| 51 | #endif |
| 52 | |
| 53 | #ifdef QT_USE_FENV |
| 54 | # include <fenv.h> |
| 55 | #endif |
| 56 | |
| 57 | #if defined(Q_OS_UNIX) && !defined(Q_OS_MAC) |
| 58 | # include <stdlib.h> |
| 59 | #endif |
| 60 | |
| 61 | Q_DECLARE_METATYPE(QLocale::FormatType) |
| 62 | |
| 63 | class tst_QLocale : public QObject |
| 64 | { |
| 65 | Q_OBJECT |
| 66 | |
| 67 | public: |
| 68 | tst_QLocale(); |
| 69 | |
| 70 | private slots: |
| 71 | void initTestCase(); |
| 72 | void cleanupTestCase(); |
| 73 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) |
| 74 | void windowsDefaultLocale(); |
| 75 | #endif |
| 76 | #ifdef Q_OS_MAC |
| 77 | void macDefaultLocale(); |
| 78 | #endif |
| 79 | |
| 80 | void ctor(); |
| 81 | void emptyCtor_data(); |
| 82 | void emptyCtor(); |
| 83 | void consistentC(); |
| 84 | void matchingLocales(); |
| 85 | void stringToDouble_data(); |
| 86 | void stringToDouble(); |
| 87 | void stringToFloat_data(); |
| 88 | void stringToFloat(); |
| 89 | void doubleToString_data(); |
| 90 | void doubleToString(); |
| 91 | void strtod_data(); |
| 92 | void strtod(); |
| 93 | void long_long_conversion_data(); |
| 94 | void long_long_conversion(); |
| 95 | void long_long_conversion_extra(); |
| 96 | void testInfAndNan(); |
| 97 | void fpExceptions(); |
| 98 | void negativeZero(); |
| 99 | void dayOfWeek(); |
| 100 | void dayOfWeek_data(); |
| 101 | void formatDate(); |
| 102 | void formatDate_data(); |
| 103 | void formatTime(); |
| 104 | void formatTime_data(); |
| 105 | void formatDateTime(); |
| 106 | void formatDateTime_data(); |
| 107 | void formatTimeZone(); |
| 108 | void toDateTime_data(); |
| 109 | void toDateTime(); |
| 110 | void negativeNumbers(); |
| 111 | void numberOptions(); |
| 112 | void dayName_data(); |
| 113 | void dayName(); |
| 114 | void standaloneDayName_data(); |
| 115 | void standaloneDayName(); |
| 116 | void underflowOverflow(); |
| 117 | |
| 118 | void dateFormat(); |
| 119 | void timeFormat(); |
| 120 | void dateTimeFormat(); |
| 121 | void monthName(); |
| 122 | void standaloneMonthName(); |
| 123 | |
| 124 | void defaultNumberingSystem_data(); |
| 125 | void defaultNumberingSystem(); |
| 126 | |
| 127 | void ampm_data(); |
| 128 | void ampm(); |
| 129 | void currency(); |
| 130 | void quoteString(); |
| 131 | void uiLanguages(); |
| 132 | void weekendDays(); |
| 133 | void listPatterns(); |
| 134 | |
| 135 | void measurementSystems_data(); |
| 136 | void measurementSystems(); |
| 137 | void QTBUG_26035_positivesign(); |
| 138 | |
| 139 | void textDirection_data(); |
| 140 | void textDirection(); |
| 141 | |
| 142 | void formattedDataSize_data(); |
| 143 | void formattedDataSize(); |
| 144 | void bcp47Name_data(); |
| 145 | void bcp47Name(); |
| 146 | |
| 147 | void systemLocale_data(); |
| 148 | void systemLocale(); |
| 149 | |
| 150 | void IndianNumberGrouping(); |
| 151 | |
| 152 | // *** ORDER-DEPENDENCY *** (This Is Bad.) |
| 153 | // Test order is determined by order of declaration here: *all* tests that |
| 154 | // QLocale::setDefault() *must* appear *after* all other tests ! |
| 155 | void defaulted_ctor(); // This one must be the first of these. |
| 156 | void legacyNames(); |
| 157 | void unixLocaleName_data(); |
| 158 | void unixLocaleName(); |
| 159 | void testNames_data(); |
| 160 | void testNames(); |
| 161 | // DO NOT add tests here unless they QLocale::setDefault(); see above. |
| 162 | private: |
| 163 | QString m_decimal, m_thousand, m_sdate, m_ldate, m_time; |
| 164 | QString m_sysapp; |
| 165 | QStringList cleanEnv; |
| 166 | bool europeanTimeZone; |
| 167 | void toReal_data(); |
| 168 | |
| 169 | class TransientLocale |
| 170 | { |
| 171 | const int m_category; |
| 172 | const char *const m_prior; |
| 173 | public: |
| 174 | TransientLocale(int category, const char *locale) |
| 175 | : m_category(category), m_prior(setlocale(category: category, locale: locale)) {} |
| 176 | ~TransientLocale() { setlocale(category: m_category, locale: m_prior); } |
| 177 | }; |
| 178 | }; |
| 179 | |
| 180 | tst_QLocale::tst_QLocale() |
| 181 | { |
| 182 | qRegisterMetaType<QLocale::FormatType>(typeName: "QLocale::FormatType" ); |
| 183 | |
| 184 | // Test if in Central European Time zone |
| 185 | uint x1 = QDateTime(QDate(1990, 1, 1), QTime()).toSecsSinceEpoch(); |
| 186 | uint x2 = QDateTime(QDate(1990, 6, 1), QTime()).toSecsSinceEpoch(); |
| 187 | europeanTimeZone = (x1 == 631148400 && x2 == 644191200); |
| 188 | } |
| 189 | |
| 190 | void tst_QLocale::initTestCase() |
| 191 | { |
| 192 | #if QT_CONFIG(process) |
| 193 | # ifdef Q_OS_ANDROID |
| 194 | m_sysapp = QCoreApplication::applicationDirPath() + "/libsyslocaleapp.so" ; |
| 195 | # else // !defined(Q_OS_ANDROID) |
| 196 | const QString syslocaleapp_dir = QFINDTESTDATA("syslocaleapp" ); |
| 197 | QVERIFY2(!syslocaleapp_dir.isEmpty(), |
| 198 | qPrintable(QStringLiteral("Cannot find 'syslocaleapp' starting from " ) |
| 199 | + QDir::toNativeSeparators(QDir::currentPath()))); |
| 200 | m_sysapp = syslocaleapp_dir + QStringLiteral("/syslocaleapp" ); |
| 201 | # ifdef Q_OS_WIN |
| 202 | m_sysapp += QStringLiteral(".exe" ); |
| 203 | # endif |
| 204 | # endif // Q_OS_ANDROID |
| 205 | const QFileInfo fi(m_sysapp); |
| 206 | QVERIFY2(fi.exists() && fi.isExecutable(), |
| 207 | qPrintable(QDir::toNativeSeparators(m_sysapp) |
| 208 | + QStringLiteral(" does not exist or is not executable." ))); |
| 209 | |
| 210 | // Get an environment free of any locale-related variables |
| 211 | cleanEnv.clear(); |
| 212 | foreach (QString const& entry, QProcess::systemEnvironment()) { |
| 213 | if (entry.startsWith(s: "LANG=" ) || entry.startsWith(s: "LC_" ) || entry.startsWith(s: "LANGUAGE=" )) |
| 214 | continue; |
| 215 | cleanEnv << entry; |
| 216 | } |
| 217 | #endif // QT_CONFIG(process) |
| 218 | } |
| 219 | |
| 220 | void tst_QLocale::cleanupTestCase() |
| 221 | {} |
| 222 | |
| 223 | void tst_QLocale::ctor() |
| 224 | { |
| 225 | QLocale default_locale = QLocale::system(); |
| 226 | QLocale::Language default_lang = default_locale.language(); |
| 227 | QLocale::Country default_country = default_locale.country(); |
| 228 | |
| 229 | qDebug(msg: "Default: %s/%s" , QLocale::languageToString(language: default_lang).toLatin1().constData(), |
| 230 | QLocale::countryToString(country: default_country).toLatin1().constData()); |
| 231 | |
| 232 | { |
| 233 | QLocale l; |
| 234 | QVERIFY(l.language() == default_lang); |
| 235 | QVERIFY(l.country() == default_country); |
| 236 | } |
| 237 | |
| 238 | #define TEST_CTOR(req_lang, req_script, req_country, exp_lang, exp_script, exp_country) \ |
| 239 | { \ |
| 240 | QLocale l(QLocale::req_lang, QLocale::req_script, QLocale::req_country); \ |
| 241 | QCOMPARE((int)l.language(), (int)exp_lang); \ |
| 242 | QCOMPARE((int)l.script(), (int)exp_script); \ |
| 243 | QCOMPARE((int)l.country(), (int)exp_country); \ |
| 244 | } |
| 245 | |
| 246 | // Exact matches |
| 247 | TEST_CTOR(Chinese, SimplifiedHanScript, China, |
| 248 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 249 | TEST_CTOR(Chinese, TraditionalHanScript, Taiwan, |
| 250 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); |
| 251 | TEST_CTOR(Chinese, TraditionalHanScript, HongKong, |
| 252 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong); |
| 253 | |
| 254 | // Best match for AnyCountry |
| 255 | TEST_CTOR(Chinese, SimplifiedHanScript, AnyCountry, |
| 256 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 257 | TEST_CTOR(Chinese, TraditionalHanScript, AnyCountry, |
| 258 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); |
| 259 | |
| 260 | // Best match for AnyScript (and change country to supported one, if necessary) |
| 261 | TEST_CTOR(Chinese, AnyScript, China, |
| 262 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 263 | TEST_CTOR(Chinese, AnyScript, Taiwan, |
| 264 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); |
| 265 | TEST_CTOR(Chinese, AnyScript, HongKong, |
| 266 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::HongKong); |
| 267 | TEST_CTOR(Chinese, AnyScript, UnitedStates, |
| 268 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 269 | |
| 270 | // Fully-specified not found; find best alternate country |
| 271 | TEST_CTOR(Chinese, SimplifiedHanScript, Taiwan, |
| 272 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 273 | TEST_CTOR(Chinese, SimplifiedHanScript, UnitedStates, |
| 274 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 275 | TEST_CTOR(Chinese, TraditionalHanScript, China, |
| 276 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); |
| 277 | TEST_CTOR(Chinese, TraditionalHanScript, UnitedStates, |
| 278 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); |
| 279 | |
| 280 | // Fully-specified not found; find best alternate script |
| 281 | TEST_CTOR(Chinese, LatinScript, China, |
| 282 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 283 | TEST_CTOR(Chinese, LatinScript, Taiwan, |
| 284 | QLocale::Chinese, QLocale::TraditionalHanScript, QLocale::Taiwan); |
| 285 | |
| 286 | // Fully-specified not found; find best alternate country and script |
| 287 | TEST_CTOR(Chinese, LatinScript, UnitedStates, |
| 288 | QLocale::Chinese, QLocale::SimplifiedHanScript, QLocale::China); |
| 289 | |
| 290 | #undef TEST_CTOR |
| 291 | } |
| 292 | |
| 293 | void tst_QLocale::defaulted_ctor() |
| 294 | { |
| 295 | QLocale default_locale = QLocale::system(); |
| 296 | QLocale::Language default_lang = default_locale.language(); |
| 297 | QLocale::Country default_country = default_locale.country(); |
| 298 | |
| 299 | qDebug(msg: "Default: %s/%s" , QLocale::languageToString(language: default_lang).toLatin1().constData(), |
| 300 | QLocale::countryToString(country: default_country).toLatin1().constData()); |
| 301 | |
| 302 | { |
| 303 | QLocale l(QLocale::C, QLocale::AnyCountry); |
| 304 | QCOMPARE(l.language(), QLocale::C); |
| 305 | QCOMPARE(l.country(), QLocale::AnyCountry); |
| 306 | } |
| 307 | |
| 308 | #define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \ |
| 309 | { \ |
| 310 | QLocale l(QLocale::req_lang, QLocale::req_country); \ |
| 311 | QCOMPARE((int)l.language(), (int)exp_lang); \ |
| 312 | QCOMPARE((int)l.country(), (int)exp_country); \ |
| 313 | } |
| 314 | |
| 315 | TEST_CTOR(AnyLanguage, AnyCountry, default_lang, default_country) |
| 316 | TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry) |
| 317 | TEST_CTOR(Aymara, AnyCountry, default_lang, default_country) |
| 318 | TEST_CTOR(Aymara, France, default_lang, default_country) |
| 319 | |
| 320 | TEST_CTOR(English, AnyCountry, QLocale::English, QLocale::UnitedStates) |
| 321 | TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates) |
| 322 | TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates) |
| 323 | TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom) |
| 324 | |
| 325 | TEST_CTOR(French, France, QLocale::French, QLocale::France) |
| 326 | TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry) |
| 327 | TEST_CTOR(Spanish, LatinAmerica, QLocale::Spanish, |
| 328 | QLocale::LatinAmerica) |
| 329 | |
| 330 | QLocale::setDefault(QLocale(QLocale::English, QLocale::France)); |
| 331 | |
| 332 | { |
| 333 | QLocale l; |
| 334 | QVERIFY(l.language() == QLocale::English); |
| 335 | QVERIFY(l.country() == QLocale::UnitedStates); |
| 336 | } |
| 337 | |
| 338 | TEST_CTOR(French, France, QLocale::French, QLocale::France) |
| 339 | TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom) |
| 340 | |
| 341 | TEST_CTOR(French, France, QLocale::French, QLocale::France) |
| 342 | TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry) |
| 343 | TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry) |
| 344 | TEST_CTOR(Aymara, AnyCountry, QLocale::English, QLocale::UnitedStates) |
| 345 | |
| 346 | QLocale::setDefault(QLocale(QLocale::English, QLocale::UnitedKingdom)); |
| 347 | |
| 348 | { |
| 349 | QLocale l; |
| 350 | QVERIFY(l.language() == QLocale::English); |
| 351 | QVERIFY(l.country() == QLocale::UnitedKingdom); |
| 352 | } |
| 353 | |
| 354 | TEST_CTOR(French, France, QLocale::French, QLocale::France) |
| 355 | TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom) |
| 356 | |
| 357 | TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry) |
| 358 | TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry) |
| 359 | |
| 360 | QLocale::setDefault(QLocale(QLocale::Aymara, QLocale::France)); |
| 361 | |
| 362 | { |
| 363 | QLocale l; |
| 364 | QVERIFY(l.language() == QLocale::English); |
| 365 | QVERIFY(l.country() == QLocale::UnitedKingdom); |
| 366 | } |
| 367 | |
| 368 | TEST_CTOR(Aymara, AnyCountry, QLocale::English, QLocale::UnitedKingdom) |
| 369 | TEST_CTOR(Aymara, France, QLocale::English, QLocale::UnitedKingdom) |
| 370 | |
| 371 | TEST_CTOR(English, AnyCountry, QLocale::English, QLocale::UnitedStates) |
| 372 | TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates) |
| 373 | TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates) |
| 374 | TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom) |
| 375 | |
| 376 | TEST_CTOR(French, France, QLocale::French, QLocale::France) |
| 377 | TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry) |
| 378 | TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry) |
| 379 | |
| 380 | QLocale::setDefault(QLocale(QLocale::Aymara, QLocale::AnyCountry)); |
| 381 | |
| 382 | { |
| 383 | QLocale l; |
| 384 | QVERIFY(l.language() == QLocale::English); |
| 385 | QVERIFY(l.country() == QLocale::UnitedKingdom); |
| 386 | } |
| 387 | |
| 388 | TEST_CTOR(Aymara, AnyCountry, QLocale::English, QLocale::UnitedKingdom) |
| 389 | TEST_CTOR(Aymara, France, QLocale::English, QLocale::UnitedKingdom) |
| 390 | |
| 391 | TEST_CTOR(English, AnyCountry, QLocale::English, QLocale::UnitedStates) |
| 392 | TEST_CTOR(English, UnitedStates, QLocale::English, QLocale::UnitedStates) |
| 393 | TEST_CTOR(English, France, QLocale::English, QLocale::UnitedStates) |
| 394 | TEST_CTOR(English, UnitedKingdom, QLocale::English, QLocale::UnitedKingdom) |
| 395 | |
| 396 | TEST_CTOR(French, France, QLocale::French, QLocale::France) |
| 397 | TEST_CTOR(C, AnyCountry, QLocale::C, QLocale::AnyCountry) |
| 398 | TEST_CTOR(C, France, QLocale::C, QLocale::AnyCountry) |
| 399 | |
| 400 | TEST_CTOR(Arabic, AnyCountry, QLocale::Arabic, QLocale::Egypt) |
| 401 | TEST_CTOR(Dutch, AnyCountry, QLocale::Dutch, QLocale::Netherlands) |
| 402 | TEST_CTOR(German, AnyCountry, QLocale::German, QLocale::Germany) |
| 403 | TEST_CTOR(Greek, AnyCountry, QLocale::Greek, QLocale::Greece) |
| 404 | TEST_CTOR(Malay, AnyCountry, QLocale::Malay, QLocale::Malaysia) |
| 405 | TEST_CTOR(Persian, AnyCountry, QLocale::Persian, QLocale::Iran) |
| 406 | TEST_CTOR(Portuguese, AnyCountry, QLocale::Portuguese, QLocale::Brazil) |
| 407 | TEST_CTOR(Serbian, AnyCountry, QLocale::Serbian, QLocale::Serbia) |
| 408 | TEST_CTOR(Somali, AnyCountry, QLocale::Somali, QLocale::Somalia) |
| 409 | TEST_CTOR(Spanish, AnyCountry, QLocale::Spanish, QLocale::Spain) |
| 410 | TEST_CTOR(Swedish, AnyCountry, QLocale::Swedish, QLocale::Sweden) |
| 411 | TEST_CTOR(Uzbek, AnyCountry, QLocale::Uzbek, QLocale::Uzbekistan) |
| 412 | |
| 413 | #undef TEST_CTOR |
| 414 | #define TEST_CTOR(req_lc, exp_lang, exp_country) \ |
| 415 | { \ |
| 416 | QLocale l(req_lc); \ |
| 417 | QVERIFY2(l.language() == QLocale::exp_lang \ |
| 418 | && l.country() == QLocale::exp_country, \ |
| 419 | QString("requested: \"" + QString(req_lc) + "\", got: " \ |
| 420 | + QLocale::languageToString(l.language()) \ |
| 421 | + QLatin1Char('/') \ |
| 422 | + QLocale::countryToString(l.country())).toLatin1().constData()); \ |
| 423 | QCOMPARE(l, QLocale(QLocale::exp_lang, QLocale::exp_country)); \ |
| 424 | QCOMPARE(qHash(l), qHash(QLocale(QLocale::exp_lang, QLocale::exp_country))); \ |
| 425 | } |
| 426 | |
| 427 | QLocale::setDefault(QLocale(QLocale::C)); |
| 428 | const QString empty; |
| 429 | |
| 430 | TEST_CTOR("C" , C, AnyCountry) |
| 431 | TEST_CTOR("bla" , C, AnyCountry) |
| 432 | TEST_CTOR("zz" , C, AnyCountry) |
| 433 | TEST_CTOR("zz_zz" , C, AnyCountry) |
| 434 | TEST_CTOR("zz..." , C, AnyCountry) |
| 435 | TEST_CTOR("" , C, AnyCountry) |
| 436 | TEST_CTOR("en/" , C, AnyCountry) |
| 437 | TEST_CTOR(empty, C, AnyCountry) |
| 438 | TEST_CTOR("en" , English, UnitedStates) |
| 439 | TEST_CTOR("en" , English, UnitedStates) |
| 440 | TEST_CTOR("en." , English, UnitedStates) |
| 441 | TEST_CTOR("en@" , English, UnitedStates) |
| 442 | TEST_CTOR("en.@" , English, UnitedStates) |
| 443 | TEST_CTOR("en_" , English, UnitedStates) |
| 444 | TEST_CTOR("en_U" , English, UnitedStates) |
| 445 | TEST_CTOR("en_." , English, UnitedStates) |
| 446 | TEST_CTOR("en_.@" , English, UnitedStates) |
| 447 | TEST_CTOR("en.bla" , English, UnitedStates) |
| 448 | TEST_CTOR("en@bla" , English, UnitedStates) |
| 449 | TEST_CTOR("en_blaaa" , English, UnitedStates) |
| 450 | TEST_CTOR("en_zz" , English, UnitedStates) |
| 451 | TEST_CTOR("en_GB" , English, UnitedKingdom) |
| 452 | TEST_CTOR("en_GB.bla" , English, UnitedKingdom) |
| 453 | TEST_CTOR("en_GB@.bla" , English, UnitedKingdom) |
| 454 | TEST_CTOR("en_GB@bla" , English, UnitedKingdom) |
| 455 | TEST_CTOR("en-GB" , English, UnitedKingdom) |
| 456 | TEST_CTOR("en-GB@bla" , English, UnitedKingdom) |
| 457 | TEST_CTOR("eo" , Esperanto, World) |
| 458 | TEST_CTOR("yi" , Yiddish, World) |
| 459 | |
| 460 | TEST_CTOR("no" , NorwegianBokmal, Norway) |
| 461 | TEST_CTOR("nb" , NorwegianBokmal, Norway) |
| 462 | TEST_CTOR("nn" , NorwegianNynorsk, Norway) |
| 463 | TEST_CTOR("no_NO" , NorwegianBokmal, Norway) |
| 464 | TEST_CTOR("nb_NO" , NorwegianBokmal, Norway) |
| 465 | TEST_CTOR("nn_NO" , NorwegianNynorsk, Norway) |
| 466 | TEST_CTOR("es_ES" , Spanish, Spain) |
| 467 | TEST_CTOR("es_419" , Spanish, LatinAmerica) |
| 468 | TEST_CTOR("es-419" , Spanish, LatinAmerica) |
| 469 | TEST_CTOR("fr_MA" , French, Morocco) |
| 470 | |
| 471 | // test default countries for languages |
| 472 | TEST_CTOR("zh" , Chinese, China) |
| 473 | TEST_CTOR("zh-Hans" , Chinese, China) |
| 474 | TEST_CTOR("ne" , Nepali, Nepal) |
| 475 | |
| 476 | #undef TEST_CTOR |
| 477 | #define TEST_CTOR(req_lc, exp_lang, exp_script, exp_country) \ |
| 478 | { \ |
| 479 | QLocale l(req_lc); \ |
| 480 | QVERIFY2(l.language() == QLocale::exp_lang \ |
| 481 | && l.script() == QLocale::exp_script \ |
| 482 | && l.country() == QLocale::exp_country, \ |
| 483 | QString("requested: \"" + QString(req_lc) + "\", got: " \ |
| 484 | + QLocale::languageToString(l.language()) \ |
| 485 | + QLatin1Char('/') + QLocale::scriptToString(l.script()) \ |
| 486 | + QLatin1Char('/') + QLocale::countryToString(l.country())).toLatin1().constData()); \ |
| 487 | } |
| 488 | |
| 489 | TEST_CTOR("zh_CN" , Chinese, SimplifiedHanScript, China) |
| 490 | TEST_CTOR("zh_Hans_CN" , Chinese, SimplifiedHanScript, China) |
| 491 | TEST_CTOR("zh_Hans" , Chinese, SimplifiedHanScript, China) |
| 492 | TEST_CTOR("zh_Hant" , Chinese, TraditionalHanScript, Taiwan) |
| 493 | TEST_CTOR("zh_Hans_MO" , Chinese, SimplifiedHanScript, Macau) |
| 494 | TEST_CTOR("zh_Hant_MO" , Chinese, TraditionalHanScript, Macau) |
| 495 | TEST_CTOR("az_Latn_AZ" , Azerbaijani, LatinScript, Azerbaijan) |
| 496 | TEST_CTOR("ha_NG" , Hausa, LatinScript, Nigeria) |
| 497 | |
| 498 | TEST_CTOR("ru" , Russian, CyrillicScript, RussianFederation) |
| 499 | TEST_CTOR("ru_Cyrl" , Russian, CyrillicScript, RussianFederation) |
| 500 | |
| 501 | #undef TEST_CTOR |
| 502 | } |
| 503 | |
| 504 | #if QT_CONFIG(process) |
| 505 | static inline bool runSysApp(const QString &binary, |
| 506 | const QStringList &env, |
| 507 | QString *output, |
| 508 | QString *errorMessage) |
| 509 | { |
| 510 | output->clear(); |
| 511 | errorMessage->clear(); |
| 512 | QProcess process; |
| 513 | process.setEnvironment(env); |
| 514 | process.start(program: binary, arguments: QStringList()); |
| 515 | process.closeWriteChannel(); |
| 516 | if (!process.waitForStarted()) { |
| 517 | *errorMessage = QLatin1String("Cannot start '" ) + binary |
| 518 | + QLatin1String("': " ) + process.errorString(); |
| 519 | return false; |
| 520 | } |
| 521 | if (!process.waitForFinished()) { |
| 522 | process.kill(); |
| 523 | *errorMessage = QStringLiteral("Timeout waiting for " ) + binary; |
| 524 | return false; |
| 525 | } |
| 526 | *output = QString::fromLocal8Bit(str: process.readAllStandardOutput()); |
| 527 | return true; |
| 528 | } |
| 529 | |
| 530 | static inline bool runSysAppTest(const QString &binary, |
| 531 | QStringList baseEnv, |
| 532 | const QString &requestedLocale, |
| 533 | const QString &expectedOutput, |
| 534 | QString *errorMessage) |
| 535 | { |
| 536 | QString output; |
| 537 | baseEnv.append(QStringLiteral("LANG=" ) + requestedLocale); |
| 538 | if (!runSysApp(binary, env: baseEnv, output: &output, errorMessage)) |
| 539 | return false; |
| 540 | |
| 541 | if (output.isEmpty()) { |
| 542 | *errorMessage = QLatin1String("Empty output received for requested '" ) + requestedLocale |
| 543 | + QLatin1String("' (expected '" ) + expectedOutput + QLatin1String("')" ); |
| 544 | return false; |
| 545 | } |
| 546 | if (output != expectedOutput) { |
| 547 | *errorMessage = QLatin1String("Output mismatch for requested '" ) + requestedLocale |
| 548 | + QLatin1String("': Expected '" ) + expectedOutput + QLatin1String("', got '" ) |
| 549 | + output + QLatin1String("'" ); |
| 550 | return false; |
| 551 | } |
| 552 | return true; |
| 553 | } |
| 554 | #endif |
| 555 | |
| 556 | void tst_QLocale::emptyCtor_data() |
| 557 | { |
| 558 | #if !QT_CONFIG(process) |
| 559 | QSKIP("No qprocess support" , SkipAll); |
| 560 | #endif |
| 561 | #ifdef Q_OS_ANDROID |
| 562 | QSKIP("This test crashes on Android" ); |
| 563 | #endif |
| 564 | |
| 565 | QTest::addColumn<QString>(name: "expected" ); |
| 566 | |
| 567 | #define ADD_CTOR_TEST(give, expect) QTest::newRow(give) << QStringLiteral(expect); |
| 568 | |
| 569 | // For format and meaning, see: |
| 570 | // http://pubs.opengroup.org/onlinepubs/7908799/xbd/envvar.html |
| 571 | // Note that the accepted values for fields are implementation-dependent; |
| 572 | // the template is language[_territory][.codeset][@modifier] |
| 573 | |
| 574 | // Vanilla: |
| 575 | ADD_CTOR_TEST("C" , "C" ); |
| 576 | |
| 577 | // Standard forms: |
| 578 | ADD_CTOR_TEST("en" , "en_US" ); |
| 579 | ADD_CTOR_TEST("en_GB" , "en_GB" ); |
| 580 | ADD_CTOR_TEST("de" , "de_DE" ); |
| 581 | // Norsk has some quirks: |
| 582 | ADD_CTOR_TEST("no" , "nb_NO" ); |
| 583 | ADD_CTOR_TEST("nb" , "nb_NO" ); |
| 584 | ADD_CTOR_TEST("nn" , "nn_NO" ); |
| 585 | ADD_CTOR_TEST("no_NO" , "nb_NO" ); |
| 586 | ADD_CTOR_TEST("nb_NO" , "nb_NO" ); |
| 587 | ADD_CTOR_TEST("nn_NO" , "nn_NO" ); |
| 588 | |
| 589 | // Not too fussy about case: |
| 590 | ADD_CTOR_TEST("DE" , "de_DE" ); |
| 591 | ADD_CTOR_TEST("EN" , "en_US" ); |
| 592 | |
| 593 | // Invalid fields |
| 594 | ADD_CTOR_TEST("bla" , "C" ); |
| 595 | ADD_CTOR_TEST("zz" , "C" ); |
| 596 | ADD_CTOR_TEST("zz_zz" , "C" ); |
| 597 | ADD_CTOR_TEST("zz..." , "C" ); |
| 598 | ADD_CTOR_TEST("en.bla" , "en_US" ); |
| 599 | ADD_CTOR_TEST("en@bla" , "en_US" ); |
| 600 | ADD_CTOR_TEST("en_blaaa" , "en_US" ); |
| 601 | ADD_CTOR_TEST("en_zz" , "en_US" ); |
| 602 | ADD_CTOR_TEST("en_GB.bla" , "en_GB" ); |
| 603 | ADD_CTOR_TEST("en_GB@.bla" , "en_GB" ); |
| 604 | ADD_CTOR_TEST("en_GB@bla" , "en_GB" ); |
| 605 | |
| 606 | // Empty optional fields, but with punctuators supplied |
| 607 | ADD_CTOR_TEST("en." , "en_US" ); |
| 608 | ADD_CTOR_TEST("en@" , "en_US" ); |
| 609 | ADD_CTOR_TEST("en.@" , "en_US" ); |
| 610 | ADD_CTOR_TEST("en_" , "en_US" ); |
| 611 | ADD_CTOR_TEST("en_." , "en_US" ); |
| 612 | ADD_CTOR_TEST("en_.@" , "en_US" ); |
| 613 | #undef ADD_CTOR_TEST |
| 614 | |
| 615 | #if QT_CONFIG(process) // for runSysApp |
| 616 | // Get default locale. |
| 617 | QString defaultLoc; |
| 618 | QString errorMessage; |
| 619 | if (runSysApp(binary: m_sysapp, env: cleanEnv, output: &defaultLoc, errorMessage: &errorMessage)) { |
| 620 | #define ADD_CTOR_TEST(give) QTest::newRow(give) << defaultLoc; |
| 621 | ADD_CTOR_TEST("en/" ); |
| 622 | ADD_CTOR_TEST("asdfghj" ); |
| 623 | ADD_CTOR_TEST("123456" ); |
| 624 | #undef ADD_CTOR_TEST |
| 625 | } else { |
| 626 | qDebug() << "Skipping tests based on default locale" << qPrintable(errorMessage); |
| 627 | } |
| 628 | #endif // process |
| 629 | } |
| 630 | |
| 631 | void tst_QLocale::emptyCtor() |
| 632 | { |
| 633 | #if QT_CONFIG(process) // for runSysAppTest |
| 634 | QLatin1String request(QTest::currentDataTag()); |
| 635 | QFETCH(QString, expected); |
| 636 | |
| 637 | // Test constructor without arguments (see syslocaleapp/syslocaleapp.cpp) |
| 638 | // Needs separate process because of caching of the system locale. |
| 639 | QString errorMessage; |
| 640 | QVERIFY2(runSysAppTest(m_sysapp, cleanEnv, request, expected, &errorMessage), |
| 641 | qPrintable(errorMessage)); |
| 642 | |
| 643 | #else |
| 644 | // This won't be called, as _data() skipped out early. |
| 645 | #endif // process |
| 646 | } |
| 647 | |
| 648 | void tst_QLocale::legacyNames() |
| 649 | { |
| 650 | QLocale::setDefault(QLocale(QLocale::C)); |
| 651 | |
| 652 | #if QT_DEPRECATED_SINCE(5, 15) |
| 653 | #define TEST_CTOR(req_lang, req_country, exp_lang, exp_country) \ |
| 654 | { \ |
| 655 | QLocale l(QLocale::req_lang, QLocale::req_country); \ |
| 656 | QCOMPARE((int)l.language(), (int)QLocale::exp_lang); \ |
| 657 | QCOMPARE((int)l.country(), (int)QLocale::exp_country); \ |
| 658 | } |
| 659 | |
| 660 | TEST_CTOR(Moldavian, Moldova, Romanian, Moldova) |
| 661 | TEST_CTOR(Norwegian, AnyCountry, Norwegian, Norway) |
| 662 | TEST_CTOR(SerboCroatian, Montenegro, Serbian, Montenegro) |
| 663 | TEST_CTOR(Tagalog, AnyCountry, Filipino, Philippines) |
| 664 | |
| 665 | #undef TEST_CTOR |
| 666 | #endif |
| 667 | |
| 668 | #define TEST_CTOR(req_lc, exp_lang, exp_country) \ |
| 669 | { \ |
| 670 | QLocale l(req_lc); \ |
| 671 | QVERIFY2(l.language() == QLocale::exp_lang \ |
| 672 | && l.country() == QLocale::exp_country, \ |
| 673 | QString("requested: \"" + QString(req_lc) + "\", got: " \ |
| 674 | + QLocale::languageToString(l.language()) \ |
| 675 | + QLatin1Char('/') \ |
| 676 | + QLocale::countryToString(l.country())).toLatin1().constData()); \ |
| 677 | } |
| 678 | |
| 679 | TEST_CTOR("mo_MD" , Romanian, Moldova) |
| 680 | TEST_CTOR("no" , NorwegianBokmal, Norway) |
| 681 | TEST_CTOR("sh_ME" , Serbian, Montenegro) |
| 682 | TEST_CTOR("tl" , Filipino, Philippines) |
| 683 | TEST_CTOR("iw" , Hebrew, Israel) |
| 684 | TEST_CTOR("in" , Indonesian, Indonesia) |
| 685 | #undef TEST_CTOR |
| 686 | } |
| 687 | |
| 688 | void tst_QLocale::consistentC() |
| 689 | { |
| 690 | const QLocale c(QLocale::C); |
| 691 | QCOMPARE(c, QLocale::c()); |
| 692 | QCOMPARE(c, QLocale(QLocale::C, QLocale::AnyScript, QLocale::AnyCountry)); |
| 693 | QVERIFY(QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript, |
| 694 | QLocale::AnyCountry).contains(c)); |
| 695 | } |
| 696 | |
| 697 | void tst_QLocale::matchingLocales() |
| 698 | { |
| 699 | const QLocale c(QLocale::C); |
| 700 | const QLocale ru_RU(QLocale::Russian, QLocale::Russia); |
| 701 | |
| 702 | QList<QLocale> locales = QLocale::matchingLocales(language: QLocale::C, script: QLocale::AnyScript, country: QLocale::AnyCountry); |
| 703 | QCOMPARE(locales.size(), 1); |
| 704 | QVERIFY(locales.contains(c)); |
| 705 | |
| 706 | locales = QLocale::matchingLocales(language: QLocale::Russian, script: QLocale::CyrillicScript, country: QLocale::Russia); |
| 707 | QCOMPARE(locales.size(), 1); |
| 708 | QVERIFY(locales.contains(ru_RU)); |
| 709 | |
| 710 | locales = QLocale::matchingLocales(language: QLocale::Russian, script: QLocale::AnyScript, country: QLocale::AnyCountry); |
| 711 | QVERIFY(!locales.isEmpty()); |
| 712 | QVERIFY(!locales.contains(c)); |
| 713 | QVERIFY(locales.contains(ru_RU)); |
| 714 | |
| 715 | locales = QLocale::matchingLocales(language: QLocale::AnyLanguage, script: QLocale::CyrillicScript, country: QLocale::AnyCountry); |
| 716 | QVERIFY(!locales.isEmpty()); |
| 717 | QVERIFY(!locales.contains(c)); |
| 718 | QVERIFY(locales.contains(ru_RU)); |
| 719 | |
| 720 | locales = QLocale::matchingLocales(language: QLocale::AnyLanguage, script: QLocale::AnyScript, country: QLocale::Russia); |
| 721 | QVERIFY(!locales.isEmpty()); |
| 722 | QVERIFY(!locales.contains(c)); |
| 723 | QVERIFY(locales.contains(ru_RU)); |
| 724 | } |
| 725 | |
| 726 | void tst_QLocale::unixLocaleName_data() |
| 727 | { |
| 728 | QTest::addColumn<QLocale::Language>(name: "lang" ); |
| 729 | QTest::addColumn<QLocale::Country>(name: "land" ); |
| 730 | QTest::addColumn<QString>(name: "expect" ); |
| 731 | |
| 732 | #define ADDROW(nom, lang, land, name) \ |
| 733 | QTest::newRow(nom) << QLocale::lang << QLocale::land << QStringLiteral(name) |
| 734 | |
| 735 | ADDROW("C_any" , C, AnyCountry, "C" ); |
| 736 | ADDROW("en_any" , English, AnyCountry, "en_US" ); |
| 737 | ADDROW("en_GB" , English, UnitedKingdom, "en_GB" ); |
| 738 | ADDROW("ay_GB" , Aymara, UnitedKingdom, "C" ); |
| 739 | #undef ADDROW |
| 740 | } |
| 741 | |
| 742 | void tst_QLocale::unixLocaleName() |
| 743 | { |
| 744 | QFETCH(QLocale::Language, lang); |
| 745 | QFETCH(QLocale::Country, land); |
| 746 | QFETCH(QString, expect); |
| 747 | |
| 748 | QLocale::setDefault(QLocale(QLocale::C)); |
| 749 | |
| 750 | QLocale locale(lang, land); |
| 751 | QCOMPARE(locale.name(), expect); |
| 752 | } |
| 753 | |
| 754 | void tst_QLocale::toReal_data() |
| 755 | { |
| 756 | QTest::addColumn<QString>(name: "locale_name" ); |
| 757 | QTest::addColumn<QString>(name: "num_str" ); |
| 758 | QTest::addColumn<bool>(name: "good" ); |
| 759 | QTest::addColumn<double>(name: "num" ); |
| 760 | |
| 761 | QTest::newRow(dataTag: "C 1" ) << QString("C" ) << QString("1" ) << true << 1.0; |
| 762 | QTest::newRow(dataTag: "C 1.0" ) << QString("C" ) << QString("1.0" ) << true << 1.0; |
| 763 | QTest::newRow(dataTag: "C 1.234" ) << QString("C" ) << QString("1.234" ) << true << 1.234; |
| 764 | QTest::newRow(dataTag: "C 1.234e-10" ) << QString("C" ) << QString("1.234e-10" ) << true << 1.234e-10; |
| 765 | QTest::newRow(dataTag: "C 1.234E10" ) << QString("C" ) << QString("1.234E10" ) << true << 1.234e10; |
| 766 | QTest::newRow(dataTag: "C 1e10" ) << QString("C" ) << QString("1e10" ) << true << 1.0e10; |
| 767 | QTest::newRow(dataTag: "C 1e310" ) << QString("C" ) << QString("1e310" ) << false << std::numeric_limits<double>::infinity(); |
| 768 | QTest::newRow(dataTag: "C 1E310" ) << QString("C" ) << QString("1E310" ) << false << std::numeric_limits<double>::infinity(); |
| 769 | QTest::newRow(dataTag: "C 1" ) << QString("C" ) << QString(" 1" ) << true << 1.0; |
| 770 | QTest::newRow(dataTag: "C 1" ) << QString("C" ) << QString(" 1" ) << true << 1.0; |
| 771 | QTest::newRow(dataTag: "C 1 " ) << QString("C" ) << QString("1 " ) << true << 1.0; |
| 772 | QTest::newRow(dataTag: "C 1 " ) << QString("C" ) << QString("1 " ) << true << 1.0; |
| 773 | |
| 774 | QTest::newRow(dataTag: "C 1," ) << QString("C" ) << QString("1," ) << false << 0.0; |
| 775 | QTest::newRow(dataTag: "C 1,2" ) << QString("C" ) << QString("1,2" ) << false << 0.0; |
| 776 | QTest::newRow(dataTag: "C 1,23" ) << QString("C" ) << QString("1,23" ) << false << 0.0; |
| 777 | QTest::newRow(dataTag: "C 1,234" ) << QString("C" ) << QString("1,234" ) << true << 1234.0; |
| 778 | QTest::newRow(dataTag: "C 1,234," ) << QString("C" ) << QString("1,234," ) << false << 0.0; |
| 779 | QTest::newRow(dataTag: "C 1,234,5" ) << QString("C" ) << QString("1,234,5" ) << false << 0.0; |
| 780 | QTest::newRow(dataTag: "C 1,234,56" ) << QString("C" ) << QString("1,234,56" ) << false << 0.0; |
| 781 | QTest::newRow(dataTag: "C 1,234,567" ) << QString("C" ) << QString("1,234,567" ) << true << 1234567.0; |
| 782 | QTest::newRow(dataTag: "C 1,234,567." ) << QString("C" ) << QString("1,234,567." ) << true << 1234567.0; |
| 783 | QTest::newRow(dataTag: "C 1,234,567.8" ) << QString("C" ) << QString("1,234,567.8" ) << true << 1234567.8; |
| 784 | QTest::newRow(dataTag: "C 1,234567.8" ) << QString("C" ) << QString("1,234567.8" ) << false << 0.0; |
| 785 | QTest::newRow(dataTag: "C 12,34567.8" ) << QString("C" ) << QString("12,34567.8" ) << false << 0.0; |
| 786 | QTest::newRow(dataTag: "C 1234,567.8" ) << QString("C" ) << QString("1234,567.8" ) << false << 0.0; |
| 787 | QTest::newRow(dataTag: "C 1234567.8" ) << QString("C" ) << QString("1234567.8" ) << true << 1234567.8; |
| 788 | QTest::newRow(dataTag: "C ," ) << QString("C" ) << QString("," ) << false << 0.0; |
| 789 | QTest::newRow(dataTag: "C ,123" ) << QString("C" ) << QString(",123" ) << false << 0.0; |
| 790 | QTest::newRow(dataTag: "C ,3" ) << QString("C" ) << QString(",3" ) << false << 0.0; |
| 791 | QTest::newRow(dataTag: "C , 3" ) << QString("C" ) << QString(", 3" ) << false << 0.0; |
| 792 | QTest::newRow(dataTag: "C , 3" ) << QString("C" ) << QString(", 3" ) << false << 0.0; |
| 793 | QTest::newRow(dataTag: "C , 3.2" ) << QString("C" ) << QString(", 3.2" ) << false << 0.0; |
| 794 | QTest::newRow(dataTag: "C , 3.2e2" ) << QString("C" ) << QString(", 3.2e2" ) << false << 0.0; |
| 795 | QTest::newRow(dataTag: "C , e2" ) << QString("C" ) << QString(", e2" ) << false << 0.0; |
| 796 | QTest::newRow(dataTag: "C 1,,234" ) << QString("C" ) << QString("1,,234" ) << false << 0.0; |
| 797 | |
| 798 | QTest::newRow(dataTag: "C empty" ) << QString("C" ) << QString("" ) << false << 0.0; |
| 799 | QTest::newRow(dataTag: "C null" ) << QString("C" ) << QString() << false << 0.0; |
| 800 | QTest::newRow(dataTag: "C ." ) << QString("C" ) << QString("." ) << false << 0.0; |
| 801 | QTest::newRow(dataTag: "C 1e" ) << QString("C" ) << QString("1e" ) << false << 0.0; |
| 802 | QTest::newRow(dataTag: "C 1,0" ) << QString("C" ) << QString("1,0" ) << false << 0.0; |
| 803 | QTest::newRow(dataTag: "C 1,000" ) << QString("C" ) << QString("1,000" ) << true << 1000.0; |
| 804 | QTest::newRow(dataTag: "C 1,000e-6" ) << QString("C" ) << QString("1,000e-6" ) << true << 1000.0e-6; |
| 805 | QTest::newRow(dataTag: "C 1e1.0" ) << QString("C" ) << QString("1e1.0" ) << false << 0.0; |
| 806 | QTest::newRow(dataTag: "C 1e+" ) << QString("C" ) << QString("1e+" ) << false << 0.0; |
| 807 | QTest::newRow(dataTag: "C 1e-" ) << QString("C" ) << QString("1e-" ) << false << 0.0; |
| 808 | |
| 809 | QTest::newRow(dataTag: "C .1" ) << QString("C" ) << QString(".1" ) << true << 0.1; |
| 810 | QTest::newRow(dataTag: "C -.1" ) << QString("C" ) << QString("-.1" ) << true << -0.1; |
| 811 | QTest::newRow(dataTag: "C 1." ) << QString("C" ) << QString("1." ) << true << 1.0; |
| 812 | QTest::newRow(dataTag: "C 1.E10" ) << QString("C" ) << QString("1.E10" ) << true << 1.0e10; |
| 813 | QTest::newRow(dataTag: "C 1e+10" ) << QString("C" ) << QString("1e+10" ) << true << 1.0e+10; |
| 814 | |
| 815 | QTest::newRow(dataTag: "de_DE 1." ) << QString("de_DE" ) << QString("1." ) << false << 0.0; |
| 816 | QTest::newRow(dataTag: "de_DE 1.2" ) << QString("de_DE" ) << QString("1.2" ) << false << 0.0; |
| 817 | QTest::newRow(dataTag: "de_DE 1.23" ) << QString("de_DE" ) << QString("1.23" ) << false << 0.0; |
| 818 | QTest::newRow(dataTag: "de_DE 1.234" ) << QString("de_DE" ) << QString("1.234" ) << true << 1234.0; |
| 819 | QTest::newRow(dataTag: "de_DE 1.234," ) << QString("de_DE" ) << QString("1.234." ) << false << 0.0; |
| 820 | QTest::newRow(dataTag: "de_DE 1.234.5" ) << QString("de_DE" ) << QString("1.234.5" ) << false << 0.0; |
| 821 | QTest::newRow(dataTag: "de_DE 1.234.56" ) << QString("de_DE" ) << QString("1.234.56" ) << false << 0.0; |
| 822 | QTest::newRow(dataTag: "de_DE 1.234.567" ) << QString("de_DE" ) << QString("1.234.567" ) << true << 1234567.0; |
| 823 | QTest::newRow(dataTag: "de_DE 1.234.567," ) << QString("de_DE" ) << QString("1.234.567," ) << true << 1234567.0; |
| 824 | QTest::newRow(dataTag: "de_DE 1.234.567,8" ) << QString("de_DE" ) << QString("1.234.567,8" ) << true << 1234567.8; |
| 825 | QTest::newRow(dataTag: "de_DE 1.234567,8" ) << QString("de_DE" ) << QString("1.234567,8" ) << false << 0.0; |
| 826 | QTest::newRow(dataTag: "de_DE 12.34567,8" ) << QString("de_DE" ) << QString("12.34567,8" ) << false << 0.0; |
| 827 | QTest::newRow(dataTag: "de_DE 1234.567,8" ) << QString("de_DE" ) << QString("1234.567,8" ) << false << 0.0; |
| 828 | QTest::newRow(dataTag: "de_DE 1234567,8" ) << QString("de_DE" ) << QString("1234567,8" ) << true << 1234567.8; |
| 829 | QTest::newRow(dataTag: "de_DE .123" ) << QString("de_DE" ) << QString(".123" ) << false << 0.0; |
| 830 | QTest::newRow(dataTag: "de_DE .3" ) << QString("de_DE" ) << QString(".3" ) << false << 0.0; |
| 831 | QTest::newRow(dataTag: "de_DE . 3" ) << QString("de_DE" ) << QString(". 3" ) << false << 0.0; |
| 832 | QTest::newRow(dataTag: "de_DE . 3" ) << QString("de_DE" ) << QString(". 3" ) << false << 0.0; |
| 833 | QTest::newRow(dataTag: "de_DE . 3,2" ) << QString("de_DE" ) << QString(". 3,2" ) << false << 0.0; |
| 834 | QTest::newRow(dataTag: "de_DE . 3,2e2" ) << QString("de_DE" ) << QString(". 3,2e2" ) << false << 0.0; |
| 835 | QTest::newRow(dataTag: "de_DE . e2" ) << QString("de_DE" ) << QString(". e2" ) << false << 0.0; |
| 836 | QTest::newRow(dataTag: "de_DE 1..234" ) << QString("de_DE" ) << QString("1..234" ) << false << 0.0; |
| 837 | |
| 838 | QTest::newRow(dataTag: "de_DE 1" ) << QString("de_DE" ) << QString("1" ) << true << 1.0; |
| 839 | QTest::newRow(dataTag: "de_DE 1.0" ) << QString("de_DE" ) << QString("1.0" ) << false << 0.0; |
| 840 | QTest::newRow(dataTag: "de_DE 1.234e-10" ) << QString("de_DE" ) << QString("1.234e-10" ) << true << 1234.0e-10; |
| 841 | QTest::newRow(dataTag: "de_DE 1.234E10" ) << QString("de_DE" ) << QString("1.234E10" ) << true << 1234.0e10; |
| 842 | QTest::newRow(dataTag: "de_DE 1e10" ) << QString("de_DE" ) << QString("1e10" ) << true << 1.0e10; |
| 843 | QTest::newRow(dataTag: "de_DE .1" ) << QString("de_DE" ) << QString(".1" ) << false << 0.0; |
| 844 | QTest::newRow(dataTag: "de_DE -.1" ) << QString("de_DE" ) << QString("-.1" ) << false << 0.0; |
| 845 | QTest::newRow(dataTag: "de_DE 1.E10" ) << QString("de_DE" ) << QString("1.E10" ) << false << 0.0; |
| 846 | QTest::newRow(dataTag: "de_DE 1e+10" ) << QString("de_DE" ) << QString("1e+10" ) << true << 1.0e+10; |
| 847 | |
| 848 | QTest::newRow(dataTag: "de_DE 1,0" ) << QString("de_DE" ) << QString("1,0" ) << true << 1.0; |
| 849 | QTest::newRow(dataTag: "de_DE 1,234" ) << QString("de_DE" ) << QString("1,234" ) << true << 1.234; |
| 850 | QTest::newRow(dataTag: "de_DE 1,234e-10" ) << QString("de_DE" ) << QString("1,234e-10" ) << true << 1.234e-10; |
| 851 | QTest::newRow(dataTag: "de_DE 1,234E10" ) << QString("de_DE" ) << QString("1,234E10" ) << true << 1.234e10; |
| 852 | QTest::newRow(dataTag: "de_DE ,1" ) << QString("de_DE" ) << QString(",1" ) << true << 0.1; |
| 853 | QTest::newRow(dataTag: "de_DE -,1" ) << QString("de_DE" ) << QString("-,1" ) << true << -0.1; |
| 854 | QTest::newRow(dataTag: "de_DE 1," ) << QString("de_DE" ) << QString("1," ) << true << 1.0; |
| 855 | QTest::newRow(dataTag: "de_DE 1,E10" ) << QString("de_DE" ) << QString("1,E10" ) << true << 1.0e10; |
| 856 | |
| 857 | QTest::newRow(dataTag: "de_DE empty" ) << QString("de_DE" ) << QString("" ) << false << 0.0; |
| 858 | QTest::newRow(dataTag: "de_DE null" ) << QString("de_DE" ) << QString() << false << 0.0; |
| 859 | QTest::newRow(dataTag: "de_DE ." ) << QString("de_DE" ) << QString("." ) << false << 0.0; |
| 860 | QTest::newRow(dataTag: "de_DE 1e" ) << QString("de_DE" ) << QString("1e" ) << false << 0.0; |
| 861 | QTest::newRow(dataTag: "de_DE 1e1.0" ) << QString("de_DE" ) << QString("1e1.0" ) << false << 0.0; |
| 862 | QTest::newRow(dataTag: "de_DE 1e+" ) << QString("de_DE" ) << QString("1e+" ) << false << 0.0; |
| 863 | QTest::newRow(dataTag: "de_DE 1e-" ) << QString("de_DE" ) << QString("1e-" ) << false << 0.0; |
| 864 | |
| 865 | QTest::newRow(dataTag: "C 9,876543" ) << QString("C" ) << QString("9,876543" ) << false << 0.0; |
| 866 | QTest::newRow(dataTag: "C 9,876543.2" ) << QString("C" ) << QString("9,876543.2" ) << false << 0.0; |
| 867 | QTest::newRow(dataTag: "C 9,876543e-2" ) << QString("C" ) << QString("9,876543e-2" ) << false << 0.0; |
| 868 | QTest::newRow(dataTag: "C 9,876543.0e-2" ) << QString("C" ) << QString("9,876543.0e-2" ) << false << 0.0; |
| 869 | |
| 870 | QTest::newRow(dataTag: "de_DE 9.876543" ) << QString("de_DE" ) << QString("9876.543" ) << false << 0.0; |
| 871 | QTest::newRow(dataTag: "de_DE 9.876543,2" ) << QString("de_DE" ) << QString("9.876543,2" ) << false << 0.0; |
| 872 | QTest::newRow(dataTag: "de_DE 9.876543e-2" ) << QString("de_DE" ) << QString("9.876543e-2" ) << false << 0.0; |
| 873 | QTest::newRow(dataTag: "de_DE 9.876543,0e-2" ) << QString("de_DE" ) << QString("9.876543,0e-2" ) << false << 0.0; |
| 874 | QTest::newRow(dataTag: "de_DE 9.876543e--2" ) << QString("de_DE" ) << QString("9.876543e" )+QChar(8722)+QString("2" ) << false << 0.0; |
| 875 | QTest::newRow(dataTag: "de_DE 9.876543,0e--2" ) << QString("de_DE" ) << QString("9.876543,0e" )+QChar(8722)+QString("2" ) << false << 0.0; |
| 876 | } |
| 877 | |
| 878 | void tst_QLocale::stringToDouble_data() |
| 879 | { |
| 880 | toReal_data(); |
| 881 | if (std::numeric_limits<double>::has_infinity) { |
| 882 | double huge = std::numeric_limits<double>::infinity(); |
| 883 | QTest::newRow(dataTag: "C inf" ) << QString("C" ) << QString("inf" ) << true << huge; |
| 884 | QTest::newRow(dataTag: "C +inf" ) << QString("C" ) << QString("+inf" ) << true << +huge; |
| 885 | QTest::newRow(dataTag: "C -inf" ) << QString("C" ) << QString("-inf" ) << true << -huge; |
| 886 | // Overflow: |
| 887 | QTest::newRow(dataTag: "C huge" ) << QString("C" ) << QString("2e308" ) << false << huge; |
| 888 | QTest::newRow(dataTag: "C -huge" ) << QString("C" ) << QString("-2e308" ) << false << -huge; |
| 889 | } |
| 890 | if (std::numeric_limits<double>::has_quiet_NaN) |
| 891 | QTest::newRow(dataTag: "C qnan" ) << QString("C" ) << QString("NaN" ) << true << std::numeric_limits<double>::quiet_NaN(); |
| 892 | |
| 893 | // In range (but outside float's range): |
| 894 | QTest::newRow(dataTag: "C big" ) << QString("C" ) << QString("3.5e38" ) << true << 3.5e38; |
| 895 | QTest::newRow(dataTag: "C -big" ) << QString("C" ) << QString("-3.5e38" ) << true << -3.5e38; |
| 896 | QTest::newRow(dataTag: "C small" ) << QString("C" ) << QString("1e-45" ) << true << 1e-45; |
| 897 | QTest::newRow(dataTag: "C -small" ) << QString("C" ) << QString("-1e-45" ) << true << -1e-45; |
| 898 | |
| 899 | // Underflow: |
| 900 | QTest::newRow(dataTag: "C tiny" ) << QString("C" ) << QString("2e-324" ) << false << 0.; |
| 901 | QTest::newRow(dataTag: "C -tiny" ) << QString("C" ) << QString("-2e-324" ) << false << 0.; |
| 902 | } |
| 903 | |
| 904 | void tst_QLocale::stringToDouble() |
| 905 | { |
| 906 | #define MY_DOUBLE_EPSILON (2.22045e-16) // 1/2^{52}; double has a 53-bit mantissa |
| 907 | |
| 908 | QFETCH(QString, locale_name); |
| 909 | QFETCH(QString, num_str); |
| 910 | QFETCH(bool, good); |
| 911 | QFETCH(double, num); |
| 912 | QStringRef num_strRef = num_str.leftRef(n: -1); |
| 913 | |
| 914 | QLocale locale(locale_name); |
| 915 | QCOMPARE(locale.name(), locale_name); |
| 916 | |
| 917 | bool ok; |
| 918 | double d = locale.toDouble(s: num_str, ok: &ok); |
| 919 | QCOMPARE(ok, good); |
| 920 | |
| 921 | { |
| 922 | // Make sure result is independent of locale: |
| 923 | TransientLocale ignoreme(LC_ALL, "ar_SA" ); |
| 924 | QCOMPARE(locale.toDouble(num_str, &ok), d); |
| 925 | QCOMPARE(ok, good); |
| 926 | } |
| 927 | |
| 928 | if (ok || std::isinf(x: num)) { |
| 929 | // First use fuzzy-compare, then a more precise check: |
| 930 | QCOMPARE(d, num); |
| 931 | if (std::isfinite(x: num)) { |
| 932 | double diff = d > num ? d - num : num - d; |
| 933 | QVERIFY(diff <= MY_DOUBLE_EPSILON); |
| 934 | } |
| 935 | } |
| 936 | |
| 937 | d = locale.toDouble(s: num_strRef, ok: &ok); |
| 938 | QCOMPARE(ok, good); |
| 939 | |
| 940 | if (ok || std::isinf(x: num)) { |
| 941 | QCOMPARE(d, num); |
| 942 | if (std::isfinite(x: num)) { |
| 943 | double diff = d > num ? d - num : num - d; |
| 944 | QVERIFY(diff <= MY_DOUBLE_EPSILON); |
| 945 | } |
| 946 | } |
| 947 | #undef MY_DOUBLE_EPSILON |
| 948 | } |
| 949 | |
| 950 | void tst_QLocale::stringToFloat_data() |
| 951 | { |
| 952 | using Bounds = std::numeric_limits<float>; |
| 953 | toReal_data(); |
| 954 | const QString C(QStringLiteral("C" )); |
| 955 | if (Bounds::has_infinity) { |
| 956 | double huge = Bounds::infinity(); |
| 957 | QTest::newRow(dataTag: "C inf" ) << C << QString("inf" ) << true << huge; |
| 958 | QTest::newRow(dataTag: "C +inf" ) << C << QString("+inf" ) << true << +huge; |
| 959 | QTest::newRow(dataTag: "C -inf" ) << C << QString("-inf" ) << true << -huge; |
| 960 | // Overflow float, but not double: |
| 961 | QTest::newRow(dataTag: "C big" ) << C << QString("3.5e38" ) << false << huge; |
| 962 | QTest::newRow(dataTag: "C -big" ) << C << QString("-3.5e38" ) << false << -huge; |
| 963 | // Overflow double, too: |
| 964 | QTest::newRow(dataTag: "C huge" ) << C << QString("2e308" ) << false << huge; |
| 965 | QTest::newRow(dataTag: "C -huge" ) << C << QString("-2e308" ) << false << -huge; |
| 966 | } |
| 967 | if (Bounds::has_quiet_NaN) |
| 968 | QTest::newRow(dataTag: "C qnan" ) << C << QString("NaN" ) << true << double(Bounds::quiet_NaN()); |
| 969 | |
| 970 | // Minimal float: shouldn't underflow |
| 971 | QTest::newRow(dataTag: "C float min" ) |
| 972 | << C << QLocale::c().toString(i: Bounds::denorm_min()) << true << double(Bounds::denorm_min()); |
| 973 | QTest::newRow(dataTag: "C float -min" ) |
| 974 | << C << QLocale::c().toString(i: -Bounds::denorm_min()) << true << -double(Bounds::denorm_min()); |
| 975 | |
| 976 | // Underflow float, but not double: |
| 977 | QTest::newRow(dataTag: "C small" ) << C << QString("7e-46" ) << false << 0.; |
| 978 | QTest::newRow(dataTag: "C -small" ) << C << QString("-7e-46" ) << false << 0.; |
| 979 | using Double = std::numeric_limits<double>; |
| 980 | QTest::newRow(dataTag: "C double min" ) |
| 981 | << C << QLocale::c().toString(i: Double::denorm_min()) << false << 0.0; |
| 982 | QTest::newRow(dataTag: "C double -min" ) |
| 983 | << C << QLocale::c().toString(i: -Double::denorm_min()) << false << 0.0; |
| 984 | |
| 985 | // Underflow double, too: |
| 986 | QTest::newRow(dataTag: "C tiny" ) << C << QString("2e-324" ) << false << 0.; |
| 987 | QTest::newRow(dataTag: "C -tiny" ) << C << QString("-2e-324" ) << false << 0.; |
| 988 | } |
| 989 | |
| 990 | void tst_QLocale::stringToFloat() |
| 991 | { |
| 992 | #define MY_FLOAT_EPSILON (2.384e-7) // 1/2^{22}; float has a 23-bit mantissa |
| 993 | |
| 994 | QFETCH(QString, locale_name); |
| 995 | QFETCH(QString, num_str); |
| 996 | QFETCH(bool, good); |
| 997 | QFETCH(double, num); |
| 998 | QStringRef num_strRef = num_str.leftRef(n: -1); |
| 999 | float fnum = num; |
| 1000 | |
| 1001 | QLocale locale(locale_name); |
| 1002 | QCOMPARE(locale.name(), locale_name); |
| 1003 | |
| 1004 | bool ok; |
| 1005 | float f = locale.toFloat(s: num_str, ok: &ok); |
| 1006 | QCOMPARE(ok, good); |
| 1007 | |
| 1008 | { |
| 1009 | // Make sure result is independent of locale: |
| 1010 | TransientLocale ignoreme(LC_ALL, "ar_SA" ); |
| 1011 | QCOMPARE(locale.toFloat(num_str, &ok), f); |
| 1012 | QCOMPARE(ok, good); |
| 1013 | } |
| 1014 | |
| 1015 | if (ok || std::isinf(x: fnum)) { |
| 1016 | // First use fuzzy-compare, then a more precise check: |
| 1017 | QCOMPARE(f, fnum); |
| 1018 | if (std::isfinite(x: fnum)) { |
| 1019 | float diff = f > fnum ? f - fnum : fnum - f; |
| 1020 | QVERIFY(diff <= MY_FLOAT_EPSILON); |
| 1021 | } |
| 1022 | } |
| 1023 | |
| 1024 | f = locale.toFloat(s: num_strRef, ok: &ok); |
| 1025 | QCOMPARE(ok, good); |
| 1026 | |
| 1027 | if (ok || std::isinf(x: fnum)) { |
| 1028 | QCOMPARE(f, fnum); |
| 1029 | if (std::isfinite(x: fnum)) { |
| 1030 | float diff = f > fnum ? f - fnum : fnum - f; |
| 1031 | QVERIFY(diff <= MY_FLOAT_EPSILON); |
| 1032 | } |
| 1033 | } |
| 1034 | #undef MY_FLOAT_EPSILON |
| 1035 | } |
| 1036 | |
| 1037 | void tst_QLocale::doubleToString_data() |
| 1038 | { |
| 1039 | QTest::addColumn<QString>(name: "locale_name" ); |
| 1040 | QTest::addColumn<QString>(name: "num_str" ); |
| 1041 | QTest::addColumn<double>(name: "num" ); |
| 1042 | QTest::addColumn<char>(name: "mode" ); |
| 1043 | QTest::addColumn<int>(name: "precision" ); |
| 1044 | |
| 1045 | int shortest = QLocale::FloatingPointShortest; |
| 1046 | |
| 1047 | QTest::newRow(dataTag: "C 3.4 f 5" ) << QString("C" ) << QString("3.40000" ) << 3.4 << 'f' << 5; |
| 1048 | QTest::newRow(dataTag: "C 3.4 f 0" ) << QString("C" ) << QString("3" ) << 3.4 << 'f' << 0; |
| 1049 | QTest::newRow(dataTag: "C 3.4 e 5" ) << QString("C" ) << QString("3.40000e+00" ) << 3.4 << 'e' << 5; |
| 1050 | QTest::newRow(dataTag: "C 3.4 e 0" ) << QString("C" ) << QString("3e+00" ) << 3.4 << 'e' << 0; |
| 1051 | QTest::newRow(dataTag: "C 3.4 g 5" ) << QString("C" ) << QString("3.4" ) << 3.4 << 'g' << 5; |
| 1052 | QTest::newRow(dataTag: "C 3.4 g 1" ) << QString("C" ) << QString("3" ) << 3.4 << 'g' << 1; |
| 1053 | |
| 1054 | QTest::newRow(dataTag: "C 3.4 f 1" ) << QString("C" ) << QString("3.4" ) << 3.4 << 'f' << 1; |
| 1055 | QTest::newRow(dataTag: "C 3.4 f -" ) << QString("C" ) << QString("3.4" ) << 3.4 << 'f' << shortest; |
| 1056 | QTest::newRow(dataTag: "C 3.4 e 1" ) << QString("C" ) << QString("3.4e+00" ) << 3.4 << 'e' << 1; |
| 1057 | QTest::newRow(dataTag: "C 3.4 e -" ) << QString("C" ) << QString("3.4e+00" ) << 3.4 << 'e' << shortest; |
| 1058 | QTest::newRow(dataTag: "C 3.4 g 2" ) << QString("C" ) << QString("3.4" ) << 3.4 << 'g' << 2; |
| 1059 | QTest::newRow(dataTag: "C 3.4 g -" ) << QString("C" ) << QString("3.4" ) << 3.4 << 'g' << shortest; |
| 1060 | |
| 1061 | QTest::newRow(dataTag: "de_DE 3,4 f 1" ) << QString("de_DE" ) << QString("3,4" ) << 3.4 << 'f' << 1; |
| 1062 | QTest::newRow(dataTag: "de_DE 3,4 f -" ) << QString("de_DE" ) << QString("3,4" ) << 3.4 << 'f' << shortest; |
| 1063 | QTest::newRow(dataTag: "de_DE 3,4 e 1" ) << QString("de_DE" ) << QString("3,4e+00" ) << 3.4 << 'e' << 1; |
| 1064 | QTest::newRow(dataTag: "de_DE 3,4 e -" ) << QString("de_DE" ) << QString("3,4e+00" ) << 3.4 << 'e' << shortest; |
| 1065 | QTest::newRow(dataTag: "de_DE 3,4 g 2" ) << QString("de_DE" ) << QString("3,4" ) << 3.4 << 'g' << 2; |
| 1066 | QTest::newRow(dataTag: "de_DE 3,4 g -" ) << QString("de_DE" ) << QString("3,4" ) << 3.4 << 'g' << shortest; |
| 1067 | |
| 1068 | QTest::newRow(dataTag: "C 0.035003945 f 12" ) << QString("C" ) << QString("0.035003945000" ) << 0.035003945 << 'f' << 12; |
| 1069 | QTest::newRow(dataTag: "C 0.035003945 f 6" ) << QString("C" ) << QString("0.035004" ) << 0.035003945 << 'f' << 6; |
| 1070 | QTest::newRow(dataTag: "C 0.035003945 e 10" ) << QString("C" ) << QString("3.5003945000e-02" ) << 0.035003945 << 'e' << 10; |
| 1071 | QTest::newRow(dataTag: "C 0.035003945 e 4" ) << QString("C" ) << QString("3.5004e-02" ) << 0.035003945 << 'e' << 4; |
| 1072 | QTest::newRow(dataTag: "C 0.035003945 g 11" ) << QString("C" ) << QString("0.035003945" ) << 0.035003945 << 'g' << 11; |
| 1073 | QTest::newRow(dataTag: "C 0.035003945 g 5" ) << QString("C" ) << QString("0.035004" ) << 0.035003945 << 'g' << 5; |
| 1074 | |
| 1075 | QTest::newRow(dataTag: "C 0.035003945 f 9" ) << QString("C" ) << QString("0.035003945" ) << 0.035003945 << 'f' << 9; |
| 1076 | QTest::newRow(dataTag: "C 0.035003945 f -" ) << QString("C" ) << QString("0.035003945" ) << 0.035003945 << 'f' << shortest; |
| 1077 | QTest::newRow(dataTag: "C 0.035003945 e 7" ) << QString("C" ) << QString("3.5003945e-02" ) << 0.035003945 << 'e' << 7; |
| 1078 | QTest::newRow(dataTag: "C 0.035003945 e -" ) << QString("C" ) << QString("3.5003945e-02" ) << 0.035003945 << 'e' << shortest; |
| 1079 | QTest::newRow(dataTag: "C 0.035003945 g 8" ) << QString("C" ) << QString("0.035003945" ) << 0.035003945 << 'g' << 8; |
| 1080 | QTest::newRow(dataTag: "C 0.035003945 g -" ) << QString("C" ) << QString("0.035003945" ) << 0.035003945 << 'g' << shortest; |
| 1081 | |
| 1082 | QTest::newRow(dataTag: "de_DE 0,035003945 f 9" ) << QString("de_DE" ) << QString("0,035003945" ) << 0.035003945 << 'f' << 9; |
| 1083 | QTest::newRow(dataTag: "de_DE 0,035003945 f -" ) << QString("de_DE" ) << QString("0,035003945" ) << 0.035003945 << 'f' << shortest; |
| 1084 | QTest::newRow(dataTag: "de_DE 0,035003945 e 7" ) << QString("de_DE" ) << QString("3,5003945e-02" ) << 0.035003945 << 'e' << 7; |
| 1085 | QTest::newRow(dataTag: "de_DE 0,035003945 e -" ) << QString("de_DE" ) << QString("3,5003945e-02" ) << 0.035003945 << 'e' << shortest; |
| 1086 | QTest::newRow(dataTag: "de_DE 0,035003945 g 8" ) << QString("de_DE" ) << QString("0,035003945" ) << 0.035003945 << 'g' << 8; |
| 1087 | QTest::newRow(dataTag: "de_DE 0,035003945 g -" ) << QString("de_DE" ) << QString("0,035003945" ) << 0.035003945 << 'g' << shortest; |
| 1088 | |
| 1089 | QTest::newRow(dataTag: "C 0.000003945 f 12" ) << QString("C" ) << QString("0.000003945000" ) << 0.000003945 << 'f' << 12; |
| 1090 | QTest::newRow(dataTag: "C 0.000003945 f 6" ) << QString("C" ) << QString("0.000004" ) << 0.000003945 << 'f' << 6; |
| 1091 | QTest::newRow(dataTag: "C 0.000003945 e 6" ) << QString("C" ) << QString("3.945000e-06" ) << 0.000003945 << 'e' << 6; |
| 1092 | QTest::newRow(dataTag: "C 0.000003945 e 0" ) << QString("C" ) << QString("4e-06" ) << 0.000003945 << 'e' << 0; |
| 1093 | QTest::newRow(dataTag: "C 0.000003945 g 7" ) << QString("C" ) << QString("3.945e-06" ) << 0.000003945 << 'g' << 7; |
| 1094 | QTest::newRow(dataTag: "C 0.000003945 g 1" ) << QString("C" ) << QString("4e-06" ) << 0.000003945 << 'g' << 1; |
| 1095 | |
| 1096 | QTest::newRow(dataTag: "C 0.000003945 f 9" ) << QString("C" ) << QString("0.000003945" ) << 0.000003945 << 'f' << 9; |
| 1097 | QTest::newRow(dataTag: "C 0.000003945 f -" ) << QString("C" ) << QString("0.000003945" ) << 0.000003945 << 'f' << shortest; |
| 1098 | QTest::newRow(dataTag: "C 0.000003945 e 3" ) << QString("C" ) << QString("3.945e-06" ) << 0.000003945 << 'e' << 3; |
| 1099 | QTest::newRow(dataTag: "C 0.000003945 e -" ) << QString("C" ) << QString("3.945e-06" ) << 0.000003945 << 'e' << shortest; |
| 1100 | QTest::newRow(dataTag: "C 0.000003945 g 4" ) << QString("C" ) << QString("3.945e-06" ) << 0.000003945 << 'g' << 4; |
| 1101 | QTest::newRow(dataTag: "C 0.000003945 g -" ) << QString("C" ) << QString("3.945e-06" ) << 0.000003945 << 'g' << shortest; |
| 1102 | |
| 1103 | QTest::newRow(dataTag: "de_DE 0,000003945 f 9" ) << QString("de_DE" ) << QString("0,000003945" ) << 0.000003945 << 'f' << 9; |
| 1104 | QTest::newRow(dataTag: "de_DE 0,000003945 f -" ) << QString("de_DE" ) << QString("0,000003945" ) << 0.000003945 << 'f' << shortest; |
| 1105 | QTest::newRow(dataTag: "de_DE 0,000003945 e 3" ) << QString("de_DE" ) << QString("3,945e-06" ) << 0.000003945 << 'e' << 3; |
| 1106 | QTest::newRow(dataTag: "de_DE 0,000003945 e -" ) << QString("de_DE" ) << QString("3,945e-06" ) << 0.000003945 << 'e' << shortest; |
| 1107 | QTest::newRow(dataTag: "de_DE 0,000003945 g 4" ) << QString("de_DE" ) << QString("3,945e-06" ) << 0.000003945 << 'g' << 4; |
| 1108 | QTest::newRow(dataTag: "de_DE 0,000003945 g -" ) << QString("de_DE" ) << QString("3,945e-06" ) << 0.000003945 << 'g' << shortest; |
| 1109 | |
| 1110 | QTest::newRow(dataTag: "C 12456789012 f 3" ) << QString("C" ) << QString("12456789012.000" ) << 12456789012.0 << 'f' << 3; |
| 1111 | QTest::newRow(dataTag: "C 12456789012 e 13" ) << QString("C" ) << QString("1.2456789012000e+10" ) << 12456789012.0 << 'e' << 13; |
| 1112 | QTest::newRow(dataTag: "C 12456789012 e 7" ) << QString("C" ) << QString("1.2456789e+10" ) << 12456789012.0 << 'e' << 7; |
| 1113 | QTest::newRow(dataTag: "C 12456789012 g 14" ) << QString("C" ) << QString("12456789012" ) << 12456789012.0 << 'g' << 14; |
| 1114 | QTest::newRow(dataTag: "C 12456789012 g 8" ) << QString("C" ) << QString("1.2456789e+10" ) << 12456789012.0 << 'g' << 8; |
| 1115 | |
| 1116 | QTest::newRow(dataTag: "C 12456789012 f 0" ) << QString("C" ) << QString("12456789012" ) << 12456789012.0 << 'f' << 0; |
| 1117 | QTest::newRow(dataTag: "C 12456789012 f -" ) << QString("C" ) << QString("12456789012" ) << 12456789012.0 << 'f' << shortest; |
| 1118 | QTest::newRow(dataTag: "C 12456789012 e 10" ) << QString("C" ) << QString("1.2456789012e+10" ) << 12456789012.0 << 'e' << 10; |
| 1119 | QTest::newRow(dataTag: "C 12456789012 e -" ) << QString("C" ) << QString("1.2456789012e+10" ) << 12456789012.0 << 'e' << shortest; |
| 1120 | QTest::newRow(dataTag: "C 12456789012 g 11" ) << QString("C" ) << QString("12456789012" ) << 12456789012.0 << 'g' << 11; |
| 1121 | QTest::newRow(dataTag: "C 12456789012 g -" ) << QString("C" ) << QString("12456789012" ) << 12456789012.0 << 'g' << shortest; |
| 1122 | |
| 1123 | QTest::newRow(dataTag: "de_DE 12456789012 f 0" ) << QString("de_DE" ) << QString("12.456.789.012" ) << 12456789012.0 << 'f' << 0; |
| 1124 | QTest::newRow(dataTag: "de_DE 12456789012 f -" ) << QString("de_DE" ) << QString("12.456.789.012" ) << 12456789012.0 << 'f' << shortest; |
| 1125 | QTest::newRow(dataTag: "de_DE 12456789012 e 10" ) << QString("de_DE" ) << QString("1,2456789012e+10" ) << 12456789012.0 << 'e' << 10; |
| 1126 | QTest::newRow(dataTag: "de_DE 12456789012 e -" ) << QString("de_DE" ) << QString("1,2456789012e+10" ) << 12456789012.0 << 'e' << shortest; |
| 1127 | QTest::newRow(dataTag: "de_DE 12456789012 g 11" ) << QString("de_DE" ) << QString("12.456.789.012" ) << 12456789012.0 << 'g' << 11; |
| 1128 | QTest::newRow(dataTag: "de_DE 12456789012 g -" ) << QString("de_DE" ) << QString("12.456.789.012" ) << 12456789012.0 << 'g' << shortest; |
| 1129 | } |
| 1130 | |
| 1131 | void tst_QLocale::doubleToString() |
| 1132 | { |
| 1133 | QFETCH(QString, locale_name); |
| 1134 | QFETCH(QString, num_str); |
| 1135 | QFETCH(double, num); |
| 1136 | QFETCH(char, mode); |
| 1137 | QFETCH(int, precision); |
| 1138 | |
| 1139 | #ifdef QT_NO_DOUBLECONVERSION |
| 1140 | if (precision == QLocale::FloatingPointShortest) |
| 1141 | QSKIP("'Shortest' double conversion is not that short without libdouble-conversion" ); |
| 1142 | #endif |
| 1143 | |
| 1144 | const QLocale locale(locale_name); |
| 1145 | QCOMPARE(locale.toString(num, mode, precision), num_str); |
| 1146 | |
| 1147 | TransientLocale ignoreme(LC_ALL, "de_DE" ); |
| 1148 | QCOMPARE(locale.toString(num, mode, precision), num_str); |
| 1149 | } |
| 1150 | |
| 1151 | void tst_QLocale::strtod_data() |
| 1152 | { |
| 1153 | QTest::addColumn<QString>(name: "num_str" ); |
| 1154 | QTest::addColumn<double>(name: "num" ); |
| 1155 | QTest::addColumn<int>(name: "processed" ); |
| 1156 | QTest::addColumn<bool>(name: "ok" ); |
| 1157 | |
| 1158 | // plain numbers, success |
| 1159 | QTest::newRow(dataTag: "0" ) << QString("0" ) << 0.0 << 1 << true; |
| 1160 | QTest::newRow(dataTag: "0." ) << QString("0." ) << 0.0 << 2 << true; |
| 1161 | QTest::newRow(dataTag: "0.0" ) << QString("0.0" ) << 0.0 << 3 << true; |
| 1162 | QTest::newRow(dataTag: "0e+0" ) << QString("0e+0" ) << 0.0 << 4 << true; |
| 1163 | QTest::newRow(dataTag: "0e-0" ) << QString("0e-0" ) << 0.0 << 4 << true; |
| 1164 | QTest::newRow(dataTag: "0e+1" ) << QString("0e+1" ) << 0.0 << 4 << true; |
| 1165 | QTest::newRow(dataTag: "0e-1" ) << QString("0e-1" ) << 0.0 << 4 << true; |
| 1166 | QTest::newRow(dataTag: "0E+0" ) << QString("0E+0" ) << 0.0 << 4 << true; |
| 1167 | QTest::newRow(dataTag: "0E-0" ) << QString("0E-0" ) << 0.0 << 4 << true; |
| 1168 | QTest::newRow(dataTag: "0E+1" ) << QString("0E+1" ) << 0.0 << 4 << true; |
| 1169 | QTest::newRow(dataTag: "0E-1" ) << QString("0E-1" ) << 0.0 << 4 << true; |
| 1170 | QTest::newRow(dataTag: "3.4" ) << QString("3.4" ) << 3.4 << 3 << true; |
| 1171 | QTest::newRow(dataTag: "0.035003945" ) << QString("0.035003945" ) << 0.035003945 << 11 << true; |
| 1172 | QTest::newRow(dataTag: "3.5003945e-2" ) << QString("3.5003945e-2" ) << 0.035003945 << 12 << true; |
| 1173 | QTest::newRow(dataTag: "0.000003945" ) << QString("0.000003945" ) << 0.000003945 << 11 << true; |
| 1174 | QTest::newRow(dataTag: "3.945e-6" ) << QString("3.945e-6" ) << 0.000003945 << 8 << true; |
| 1175 | QTest::newRow(dataTag: "12456789012" ) << QString("12456789012" ) << 12456789012.0 << 11 << true; |
| 1176 | QTest::newRow(dataTag: "1.2456789012e10" ) << QString("1.2456789012e10" ) << 12456789012.0 << 15 << true; |
| 1177 | |
| 1178 | // starts with junk, fails |
| 1179 | QTest::newRow(dataTag: "a0" ) << QString("a0" ) << 0.0 << 0 << false; |
| 1180 | QTest::newRow(dataTag: "a0." ) << QString("a0." ) << 0.0 << 0 << false; |
| 1181 | QTest::newRow(dataTag: "a0.0" ) << QString("a0.0" ) << 0.0 << 0 << false; |
| 1182 | QTest::newRow(dataTag: "a3.4" ) << QString("a3.4" ) << 0.0 << 0 << false; |
| 1183 | QTest::newRow(dataTag: "b0.035003945" ) << QString("b0.035003945" ) << 0.0 << 0 << false; |
| 1184 | QTest::newRow(dataTag: "c3.5003945e-2" ) << QString("c3.5003945e-2" ) << 0.0 << 0 << false; |
| 1185 | QTest::newRow(dataTag: "d0.000003945" ) << QString("d0.000003945" ) << 0.0 << 0 << false; |
| 1186 | QTest::newRow(dataTag: "e3.945e-6" ) << QString("e3.945e-6" ) << 0.0 << 0 << false; |
| 1187 | QTest::newRow(dataTag: "f12456789012" ) << QString("f12456789012" ) << 0.0 << 0 << false; |
| 1188 | QTest::newRow(dataTag: "g1.2456789012e10" ) << QString("g1.2456789012e10" ) << 0.0 << 0 << false; |
| 1189 | |
| 1190 | // ends with junk, success |
| 1191 | QTest::newRow(dataTag: "0a" ) << QString("0a" ) << 0.0 << 1 << true; |
| 1192 | QTest::newRow(dataTag: "0.a" ) << QString("0.a" ) << 0.0 << 2 << true; |
| 1193 | QTest::newRow(dataTag: "0.0a" ) << QString("0.0a" ) << 0.0 << 3 << true; |
| 1194 | QTest::newRow(dataTag: "0e+0a" ) << QString("0e+0a" ) << 0.0 << 4 << true; |
| 1195 | QTest::newRow(dataTag: "0e-0a" ) << QString("0e-0a" ) << 0.0 << 4 << true; |
| 1196 | QTest::newRow(dataTag: "0e+1a" ) << QString("0e+1a" ) << 0.0 << 4 << true; |
| 1197 | QTest::newRow(dataTag: "0e-1a" ) << QString("0e-1a" ) << 0.0 << 4 << true; |
| 1198 | QTest::newRow(dataTag: "0E+0a" ) << QString("0E+0a" ) << 0.0 << 4 << true; |
| 1199 | QTest::newRow(dataTag: "0E-0a" ) << QString("0E-0a" ) << 0.0 << 4 << true; |
| 1200 | QTest::newRow(dataTag: "0E+1a" ) << QString("0E+1a" ) << 0.0 << 4 << true; |
| 1201 | QTest::newRow(dataTag: "0E-1a" ) << QString("0E-1a" ) << 0.0 << 4 << true; |
| 1202 | QTest::newRow(dataTag: "0.035003945b" ) << QString("0.035003945b" ) << 0.035003945 << 11 << true; |
| 1203 | QTest::newRow(dataTag: "3.5003945e-2c" ) << QString("3.5003945e-2c" ) << 0.035003945 << 12 << true; |
| 1204 | QTest::newRow(dataTag: "0.000003945d" ) << QString("0.000003945d" ) << 0.000003945 << 11 << true; |
| 1205 | QTest::newRow(dataTag: "3.945e-6e" ) << QString("3.945e-6e" ) << 0.000003945 << 8 << true; |
| 1206 | QTest::newRow(dataTag: "12456789012f" ) << QString("12456789012f" ) << 12456789012.0 << 11 << true; |
| 1207 | QTest::newRow(dataTag: "1.2456789012e10g" ) << QString("1.2456789012e10g" ) << 12456789012.0 << 15 << true; |
| 1208 | |
| 1209 | // "0x" prefix, success but only for the "0" before "x" |
| 1210 | QTest::newRow(dataTag: "0x0" ) << QString("0x0" ) << 0.0 << 1 << true; |
| 1211 | QTest::newRow(dataTag: "0x0." ) << QString("0x0." ) << 0.0 << 1 << true; |
| 1212 | QTest::newRow(dataTag: "0x0.0" ) << QString("0x0.0" ) << 0.0 << 1 << true; |
| 1213 | QTest::newRow(dataTag: "0x3.4" ) << QString("0x3.4" ) << 0.0 << 1 << true; |
| 1214 | QTest::newRow(dataTag: "0x0.035003945" ) << QString("0x0.035003945" ) << 0.0 << 1 << true; |
| 1215 | QTest::newRow(dataTag: "0x3.5003945e-2" ) << QString("0x3.5003945e-2" ) << 0.0 << 1 << true; |
| 1216 | QTest::newRow(dataTag: "0x0.000003945" ) << QString("0x0.000003945" ) << 0.0 << 1 << true; |
| 1217 | QTest::newRow(dataTag: "0x3.945e-6" ) << QString("0x3.945e-6" ) << 0.0 << 1 << true; |
| 1218 | QTest::newRow(dataTag: "0x12456789012" ) << QString("0x12456789012" ) << 0.0 << 1 << true; |
| 1219 | QTest::newRow(dataTag: "0x1.2456789012e10" ) << QString("0x1.2456789012e10" ) << 0.0 << 1 << true; |
| 1220 | |
| 1221 | // hexfloat is not supported (yet) |
| 1222 | QTest::newRow(dataTag: "0x1.921fb5p+1" ) << QString("0x1.921fb5p+1" ) << 0.0 << 1 << true; |
| 1223 | } |
| 1224 | |
| 1225 | void tst_QLocale::strtod() |
| 1226 | { |
| 1227 | QFETCH(QString, num_str); |
| 1228 | QFETCH(double, num); |
| 1229 | QFETCH(int, processed); |
| 1230 | QFETCH(bool, ok); |
| 1231 | |
| 1232 | QByteArray numData = num_str.toLatin1(); |
| 1233 | const char *end = 0; |
| 1234 | bool actualOk = false; |
| 1235 | double result = qstrtod(s00: numData.constData(), se: &end, ok: &actualOk); |
| 1236 | |
| 1237 | QCOMPARE(result, num); |
| 1238 | QCOMPARE(actualOk, ok); |
| 1239 | QCOMPARE(static_cast<int>(end - numData.constData()), processed); |
| 1240 | |
| 1241 | // make sure neither QByteArray, QString or QLocale also work |
| 1242 | // (but they don't support incomplete parsing) |
| 1243 | if (processed == num_str.size() || processed == 0) { |
| 1244 | actualOk = false; |
| 1245 | QCOMPARE(num_str.toDouble(&actualOk), num); |
| 1246 | QCOMPARE(actualOk, ok); |
| 1247 | |
| 1248 | actualOk = false; |
| 1249 | QCOMPARE(numData.toDouble(&actualOk), num); |
| 1250 | QCOMPARE(actualOk, ok); |
| 1251 | |
| 1252 | actualOk = false; |
| 1253 | QCOMPARE(QLocale::c().toDouble(num_str, &actualOk), num); |
| 1254 | QCOMPARE(actualOk, ok); |
| 1255 | } |
| 1256 | |
| 1257 | // and QStringRef, but we can limit the length without allocating memory |
| 1258 | QStringRef num_strref(&num_str, 0, processed); |
| 1259 | actualOk = false; |
| 1260 | QCOMPARE(QLocale::c().toDouble(num_strref, &actualOk), num); |
| 1261 | QCOMPARE(actualOk, ok); |
| 1262 | } |
| 1263 | |
| 1264 | void tst_QLocale::long_long_conversion_data() |
| 1265 | { |
| 1266 | QTest::addColumn<QString>(name: "locale_name" ); |
| 1267 | QTest::addColumn<QString>(name: "num_str" ); |
| 1268 | QTest::addColumn<bool>(name: "good" ); |
| 1269 | QTest::addColumn<qlonglong>(name: "num" ); |
| 1270 | |
| 1271 | QTest::newRow(dataTag: "C null" ) << QString("C" ) << QString() << false << (qlonglong) 0; |
| 1272 | QTest::newRow(dataTag: "C empty" ) << QString("C" ) << QString("" ) << false << (qlonglong) 0; |
| 1273 | QTest::newRow(dataTag: "C 1" ) << QString("C" ) << "1" << true << (qlonglong) 1; |
| 1274 | QTest::newRow(dataTag: "C 1," ) << QString("C" ) << "1," << false << (qlonglong) 0; |
| 1275 | QTest::newRow(dataTag: "C 1,2" ) << QString("C" ) << "1,2" << false << (qlonglong) 0; |
| 1276 | QTest::newRow(dataTag: "C 1,23" ) << QString("C" ) << "1,23" << false << (qlonglong) 0; |
| 1277 | QTest::newRow(dataTag: "C 1,234" ) << QString("C" ) << "1,234" << true << (qlonglong) 1234; |
| 1278 | QTest::newRow(dataTag: "C 1234567" ) << QString("C" ) << "1234567" << true << (qlonglong) 1234567; |
| 1279 | QTest::newRow(dataTag: "C 1,234567" ) << QString("C" ) << "1,234567" << false << (qlonglong) 0; |
| 1280 | QTest::newRow(dataTag: "C 12,34567" ) << QString("C" ) << "12,34567" << false << (qlonglong) 0; |
| 1281 | QTest::newRow(dataTag: "C 123,4567" ) << QString("C" ) << "123,4567" << false << (qlonglong) 0; |
| 1282 | QTest::newRow(dataTag: "C 1234,567" ) << QString("C" ) << "1234,567" << false << (qlonglong) 0; |
| 1283 | QTest::newRow(dataTag: "C 12345,67" ) << QString("C" ) << "12345,67" << false << (qlonglong) 0; |
| 1284 | QTest::newRow(dataTag: "C 123456,7" ) << QString("C" ) << "123456,7" << false << (qlonglong) 0; |
| 1285 | QTest::newRow(dataTag: "C 1,234,567" ) << QString("C" ) << "1,234,567" << true << (qlonglong) 1234567; |
| 1286 | |
| 1287 | QTest::newRow(dataTag: "de_DE 1" ) << QString("de_DE" ) << "1" << true << (qlonglong) 1; |
| 1288 | QTest::newRow(dataTag: "de_DE 1." ) << QString("de_DE" ) << "1." << false << (qlonglong) 0; |
| 1289 | QTest::newRow(dataTag: "de_DE 1.2" ) << QString("de_DE" ) << "1.2" << false << (qlonglong) 0; |
| 1290 | QTest::newRow(dataTag: "de_DE 1.23" ) << QString("de_DE" ) << "1.23" << false << (qlonglong) 0; |
| 1291 | QTest::newRow(dataTag: "de_DE 1.234" ) << QString("de_DE" ) << "1.234" << true << (qlonglong) 1234; |
| 1292 | QTest::newRow(dataTag: "de_DE 1234567" ) << QString("de_DE" ) << "1234567" << true << (qlonglong) 1234567; |
| 1293 | QTest::newRow(dataTag: "de_DE 1.234567" ) << QString("de_DE" ) << "1.234567" << false << (qlonglong) 0; |
| 1294 | QTest::newRow(dataTag: "de_DE 12.34567" ) << QString("de_DE" ) << "12.34567" << false << (qlonglong) 0; |
| 1295 | QTest::newRow(dataTag: "de_DE 123.4567" ) << QString("de_DE" ) << "123.4567" << false << (qlonglong) 0; |
| 1296 | QTest::newRow(dataTag: "de_DE 1234.567" ) << QString("de_DE" ) << "1234.567" << false << (qlonglong) 0; |
| 1297 | QTest::newRow(dataTag: "de_DE 12345.67" ) << QString("de_DE" ) << "12345.67" << false << (qlonglong) 0; |
| 1298 | QTest::newRow(dataTag: "de_DE 123456.7" ) << QString("de_DE" ) << "123456.7" << false << (qlonglong) 0; |
| 1299 | QTest::newRow(dataTag: "de_DE 1.234.567" ) << QString("de_DE" ) << "1.234.567" << true << (qlonglong) 1234567; |
| 1300 | QTest::newRow(dataTag: "de_DE 1.234.567 ldspcs" ) << QString("de_DE" ) << " 1.234.567" << true << (qlonglong) 1234567; |
| 1301 | QTest::newRow(dataTag: "de_DE 1.234.567 trspcs" ) << QString("de_DE" ) << "1.234.567 " << true << (qlonglong) 1234567; |
| 1302 | QTest::newRow(dataTag: "de_DE 1.234.567 ldtrspcs" ) << QString("de_DE" ) << " 1.234.567 " << true << (qlonglong) 1234567; |
| 1303 | |
| 1304 | // test that space is also accepted whenever QLocale::groupSeparator() == 0xa0 (which looks like space). |
| 1305 | QTest::newRow(dataTag: "nb_NO 123 groupsep" ) << QString("nb_NO" ) << QString("1" )+QChar(0xa0)+QString("234" ) << true << (qlonglong) 1234; |
| 1306 | QTest::newRow(dataTag: "nb_NO 123 groupsep_space" ) << QString("nb_NO" ) << QString("1" )+QChar(0x20)+QString("234" ) << true << (qlonglong) 1234; |
| 1307 | |
| 1308 | QTest::newRow(dataTag: "nb_NO 123 ldspcs" ) << QString("nb_NO" ) << " 123" << true << (qlonglong) 123; |
| 1309 | QTest::newRow(dataTag: "nb_NO 123 trspcs" ) << QString("nb_NO" ) << "123 " << true << (qlonglong) 123; |
| 1310 | QTest::newRow(dataTag: "nb_NO 123 ldtrspcs" ) << QString("nb_NO" ) << " 123 " << true << (qlonglong) 123; |
| 1311 | |
| 1312 | QTest::newRow(dataTag: "C 1234" ) << QString("C" ) << " 1234" << true << (qlonglong) 1234; |
| 1313 | QTest::newRow(dataTag: "C 1234 " ) << QString("C" ) << "1234 " << true << (qlonglong) 1234; |
| 1314 | QTest::newRow(dataTag: "C 1234 " ) << QString("C" ) << " 1234 " << true << (qlonglong) 1234; |
| 1315 | } |
| 1316 | |
| 1317 | void tst_QLocale::long_long_conversion() |
| 1318 | { |
| 1319 | QFETCH(QString, locale_name); |
| 1320 | QFETCH(QString, num_str); |
| 1321 | QFETCH(bool, good); |
| 1322 | QFETCH(qlonglong, num); |
| 1323 | QStringRef num_strRef = num_str.leftRef(n: -1); |
| 1324 | |
| 1325 | QLocale locale(locale_name); |
| 1326 | QCOMPARE(locale.name(), locale_name); |
| 1327 | |
| 1328 | bool ok; |
| 1329 | qlonglong l = locale.toLongLong(s: num_str, ok: &ok); |
| 1330 | QCOMPARE(ok, good); |
| 1331 | |
| 1332 | if (ok) |
| 1333 | QCOMPARE(l, num); |
| 1334 | |
| 1335 | l = locale.toLongLong(s: num_strRef, ok: &ok); |
| 1336 | QCOMPARE(ok, good); |
| 1337 | |
| 1338 | if (ok) |
| 1339 | QCOMPARE(l, num); |
| 1340 | } |
| 1341 | |
| 1342 | void tst_QLocale::() |
| 1343 | { |
| 1344 | QLocale l(QLocale::C); |
| 1345 | l.setNumberOptions({ }); |
| 1346 | QCOMPARE(l.toString((qlonglong)1), QString("1" )); |
| 1347 | QCOMPARE(l.toString((qlonglong)12), QString("12" )); |
| 1348 | QCOMPARE(l.toString((qlonglong)123), QString("123" )); |
| 1349 | QCOMPARE(l.toString((qlonglong)1234), QString("1,234" )); |
| 1350 | QCOMPARE(l.toString((qlonglong)12345), QString("12,345" )); |
| 1351 | QCOMPARE(l.toString((qlonglong)-1), QString("-1" )); |
| 1352 | QCOMPARE(l.toString((qlonglong)-12), QString("-12" )); |
| 1353 | QCOMPARE(l.toString((qlonglong)-123), QString("-123" )); |
| 1354 | QCOMPARE(l.toString((qlonglong)-1234), QString("-1,234" )); |
| 1355 | QCOMPARE(l.toString((qlonglong)-12345), QString("-12,345" )); |
| 1356 | QCOMPARE(l.toString((qulonglong)1), QString("1" )); |
| 1357 | QCOMPARE(l.toString((qulonglong)12), QString("12" )); |
| 1358 | QCOMPARE(l.toString((qulonglong)123), QString("123" )); |
| 1359 | QCOMPARE(l.toString((qulonglong)1234), QString("1,234" )); |
| 1360 | QCOMPARE(l.toString((qulonglong)12345), QString("12,345" )); |
| 1361 | } |
| 1362 | |
| 1363 | void tst_QLocale::testInfAndNan() |
| 1364 | { |
| 1365 | double neginf = log(x: 0.0); |
| 1366 | double nan = sqrt(x: -1.0); |
| 1367 | |
| 1368 | #ifdef Q_OS_WIN |
| 1369 | // these cause INVALID floating point exception so we want to clear the status. |
| 1370 | _clear87(); |
| 1371 | #endif |
| 1372 | |
| 1373 | QVERIFY(qIsInf(-neginf)); |
| 1374 | QVERIFY(!qIsNaN(-neginf)); |
| 1375 | QVERIFY(!qIsFinite(-neginf)); |
| 1376 | |
| 1377 | QVERIFY(!qIsInf(nan)); |
| 1378 | QVERIFY(qIsNaN(nan)); |
| 1379 | QVERIFY(!qIsFinite(nan)); |
| 1380 | |
| 1381 | QVERIFY(!qIsInf(1.234)); |
| 1382 | QVERIFY(!qIsNaN(1.234)); |
| 1383 | QVERIFY(qIsFinite(1.234)); |
| 1384 | } |
| 1385 | |
| 1386 | void tst_QLocale::fpExceptions() |
| 1387 | { |
| 1388 | #ifndef _MCW_EM |
| 1389 | #define _MCW_EM 0x0008001F |
| 1390 | #endif |
| 1391 | #ifndef _EM_INEXACT |
| 1392 | #define _EM_INEXACT 0x00000001 |
| 1393 | #endif |
| 1394 | |
| 1395 | // check that double-to-string conversion doesn't throw floating point exceptions when they are |
| 1396 | // enabled |
| 1397 | #ifdef Q_OS_WIN |
| 1398 | _clear87(); |
| 1399 | unsigned int oldbits = _control87(0, 0); |
| 1400 | _control87( 0 | _EM_INEXACT, _MCW_EM ); |
| 1401 | #endif |
| 1402 | |
| 1403 | #ifdef QT_USE_FENV |
| 1404 | fenv_t envp; |
| 1405 | fegetenv(envp: &envp); |
| 1406 | feclearexcept(FE_ALL_EXCEPT); |
| 1407 | feenableexcept(FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW | FE_INVALID); |
| 1408 | #endif |
| 1409 | |
| 1410 | QString::number(1000.1245); |
| 1411 | QString::number(1.1); |
| 1412 | QString::number(0.0); |
| 1413 | |
| 1414 | QVERIFY(true); |
| 1415 | |
| 1416 | #ifdef Q_OS_WIN |
| 1417 | _clear87(); |
| 1418 | _control87(oldbits, 0xFFFFF); |
| 1419 | #endif |
| 1420 | |
| 1421 | #ifdef QT_USE_FENV |
| 1422 | fesetenv(envp: &envp); |
| 1423 | #endif |
| 1424 | } |
| 1425 | |
| 1426 | void tst_QLocale::negativeZero() |
| 1427 | { |
| 1428 | double negativeZero( 0.0 ); // Initialise to zero. |
| 1429 | uchar *ptr = (uchar *)&negativeZero; |
| 1430 | ptr[QSysInfo::ByteOrder == QSysInfo::BigEndian ? 0 : 7] = 0x80; |
| 1431 | QString s = QString::number(negativeZero); |
| 1432 | QCOMPARE(s, QString("0" )); |
| 1433 | } |
| 1434 | |
| 1435 | void tst_QLocale::dayOfWeek_data() |
| 1436 | { |
| 1437 | QTest::addColumn<QDate>(name: "date" ); |
| 1438 | QTest::addColumn<QString>(name: "shortName" ); |
| 1439 | QTest::addColumn<QString>(name: "longName" ); |
| 1440 | |
| 1441 | QTest::newRow(dataTag: "Sun" ) << QDate(2006, 1, 1) << "Sun" << "Sunday" ; |
| 1442 | QTest::newRow(dataTag: "Mon" ) << QDate(2006, 1, 2) << "Mon" << "Monday" ; |
| 1443 | QTest::newRow(dataTag: "Tue" ) << QDate(2006, 1, 3) << "Tue" << "Tuesday" ; |
| 1444 | QTest::newRow(dataTag: "Wed" ) << QDate(2006, 1, 4) << "Wed" << "Wednesday" ; |
| 1445 | QTest::newRow(dataTag: "Thu" ) << QDate(2006, 1, 5) << "Thu" << "Thursday" ; |
| 1446 | QTest::newRow(dataTag: "Fri" ) << QDate(2006, 1, 6) << "Fri" << "Friday" ; |
| 1447 | QTest::newRow(dataTag: "Sat" ) << QDate(2006, 1, 7) << "Sat" << "Saturday" ; |
| 1448 | } |
| 1449 | |
| 1450 | void tst_QLocale::dayOfWeek() |
| 1451 | { |
| 1452 | QFETCH(QDate, date); |
| 1453 | QFETCH(QString, shortName); |
| 1454 | QFETCH(QString, longName); |
| 1455 | |
| 1456 | QCOMPARE(QLocale::c().toString(date, "ddd" ), shortName); |
| 1457 | QCOMPARE(QLocale::c().toString(date, "dddd" ), longName); |
| 1458 | |
| 1459 | QCOMPARE(QLocale::c().toString(date, u"ddd" ), shortName); |
| 1460 | QCOMPARE(QLocale::c().toString(date, u"dddd" ), longName); |
| 1461 | } |
| 1462 | |
| 1463 | void tst_QLocale::formatDate_data() |
| 1464 | { |
| 1465 | QTest::addColumn<QDate>(name: "date" ); |
| 1466 | QTest::addColumn<QString>(name: "format" ); |
| 1467 | QTest::addColumn<QString>(name: "result" ); |
| 1468 | |
| 1469 | QTest::newRow(dataTag: "1" ) << QDate(1974, 12, 1) << "d/M/yyyy" << "1/12/1974" ; |
| 1470 | QTest::newRow(dataTag: "2" ) << QDate(1974, 12, 1) << "d/M/yyyyy" << "1/12/1974y" ; |
| 1471 | QTest::newRow(dataTag: "4" ) << QDate(1974, 1, 1) << "d/M/yyyy" << "1/1/1974" ; |
| 1472 | QTest::newRow(dataTag: "5" ) << QDate(1974, 1, 1) << "dd/MM/yyy" << "01/01/74y" ; |
| 1473 | QTest::newRow(dataTag: "6" ) << QDate(1974, 12, 1) << "ddd/MMM/yy" << "Sun/Dec/74" ; |
| 1474 | QTest::newRow(dataTag: "7" ) << QDate(1974, 12, 1) << "dddd/MMMM/y" << "Sunday/December/y" ; |
| 1475 | QTest::newRow(dataTag: "8" ) << QDate(1974, 12, 1) << "ddddd/MMMMM/yy" << "Sunday1/December12/74" ; |
| 1476 | QTest::newRow(dataTag: "9" ) << QDate(1974, 12, 1) << "'dddd'/MMMM/yy" << "dddd/December/74" ; |
| 1477 | QTest::newRow(dataTag: "10" ) << QDate(1974, 12, 1) << "d'dd'd/MMMM/yyy" << "1dd1/December/74y" ; |
| 1478 | QTest::newRow(dataTag: "11" ) << QDate(1974, 12, 1) << "d'dd'd/MMM'M'/yy" << "1dd1/DecM/74" ; |
| 1479 | QTest::newRow(dataTag: "12" ) << QDate(1974, 12, 1) << "d'd'dd/M/yy" << "1d01/12/74" ; |
| 1480 | |
| 1481 | QTest::newRow(dataTag: "20" ) << QDate(1974, 12, 1) << "foo" << "foo" ; |
| 1482 | QTest::newRow(dataTag: "21" ) << QDate(1974, 12, 1) << "'" << "" ; |
| 1483 | QTest::newRow(dataTag: "22" ) << QDate(1974, 12, 1) << "''" << "'" ; |
| 1484 | QTest::newRow(dataTag: "23" ) << QDate(1974, 12, 1) << "'''" << "'" ; |
| 1485 | QTest::newRow(dataTag: "24" ) << QDate(1974, 12, 1) << "\"" << "\"" ; |
| 1486 | QTest::newRow(dataTag: "25" ) << QDate(1974, 12, 1) << "\"\"" << "\"\"" ; |
| 1487 | QTest::newRow(dataTag: "26" ) << QDate(1974, 12, 1) << "\"yy\"" << "\"74\"" ; |
| 1488 | QTest::newRow(dataTag: "27" ) << QDate(1974, 12, 1) << "'\"yy\"'" << "\"yy\"" ; |
| 1489 | QTest::newRow(dataTag: "28" ) << QDate() << "'\"yy\"'" << "" ; |
| 1490 | QTest::newRow(dataTag: "29" ) |
| 1491 | << QDate(1974, 12, 1) << "hh:mm:ss.zzz ap d'd'dd/M/yy" << "hh:mm:ss.zzz ap 1d01/12/74" ; |
| 1492 | |
| 1493 | QTest::newRow(dataTag: "dd MMMM yyyy" ) << QDate(1, 1, 1) << "dd MMMM yyyy" << "01 January 0001" ; |
| 1494 | } |
| 1495 | |
| 1496 | void tst_QLocale::formatDate() |
| 1497 | { |
| 1498 | QFETCH(QDate, date); |
| 1499 | QFETCH(QString, format); |
| 1500 | QFETCH(QString, result); |
| 1501 | |
| 1502 | QLocale l(QLocale::C); |
| 1503 | QCOMPARE(l.toString(date, format), result); |
| 1504 | QCOMPARE(l.toString(date, QStringView(format)), result); |
| 1505 | } |
| 1506 | |
| 1507 | void tst_QLocale::formatTime_data() |
| 1508 | { |
| 1509 | QTest::addColumn<QTime>(name: "time" ); |
| 1510 | QTest::addColumn<QString>(name: "format" ); |
| 1511 | QTest::addColumn<QString>(name: "result" ); |
| 1512 | |
| 1513 | QTest::newRow(dataTag: "1" ) << QTime(1, 2, 3) << "h:m:s" << "1:2:3" ; |
| 1514 | QTest::newRow(dataTag: "3" ) << QTime(1, 2, 3) << "H:m:s" << "1:2:3" ; |
| 1515 | QTest::newRow(dataTag: "4" ) << QTime(1, 2, 3) << "hh:mm:ss" << "01:02:03" ; |
| 1516 | QTest::newRow(dataTag: "5" ) << QTime(1, 2, 3) << "HH:mm:ss" << "01:02:03" ; |
| 1517 | QTest::newRow(dataTag: "6" ) << QTime(1, 2, 3) << "hhh:mmm:sss" << "011:022:033" ; |
| 1518 | |
| 1519 | QTest::newRow(dataTag: "8" ) << QTime(14, 2, 3) << "h:m:s" << "14:2:3" ; |
| 1520 | QTest::newRow(dataTag: "9" ) << QTime(14, 2, 3) << "H:m:s" << "14:2:3" ; |
| 1521 | QTest::newRow(dataTag: "10" ) << QTime(14, 2, 3) << "hh:mm:ss" << "14:02:03" ; |
| 1522 | QTest::newRow(dataTag: "11" ) << QTime(14, 2, 3) << "HH:mm:ss" << "14:02:03" ; |
| 1523 | QTest::newRow(dataTag: "12" ) << QTime(14, 2, 3) << "hhh:mmm:sss" << "1414:022:033" ; |
| 1524 | |
| 1525 | QTest::newRow(dataTag: "14" ) << QTime(14, 2, 3) << "h:m:s ap" << "2:2:3 pm" ; |
| 1526 | QTest::newRow(dataTag: "15" ) << QTime(14, 2, 3) << "H:m:s AP" << "14:2:3 PM" ; |
| 1527 | QTest::newRow(dataTag: "16" ) << QTime(14, 2, 3) << "hh:mm:ss aap" << "02:02:03 pmpm" ; |
| 1528 | QTest::newRow(dataTag: "17" ) << QTime(14, 2, 3) << "HH:mm:ss AP aa" << "14:02:03 PM pmpm" ; |
| 1529 | |
| 1530 | QTest::newRow(dataTag: "18" ) << QTime(1, 2, 3) << "h:m:s ap" << "1:2:3 am" ; |
| 1531 | QTest::newRow(dataTag: "19" ) << QTime(1, 2, 3) << "H:m:s AP" << "1:2:3 AM" ; |
| 1532 | |
| 1533 | QTest::newRow(dataTag: "20" ) << QTime(1, 2, 3) << "foo" << "foo" ; |
| 1534 | QTest::newRow(dataTag: "21" ) << QTime(1, 2, 3) << "'" << "" ; |
| 1535 | QTest::newRow(dataTag: "22" ) << QTime(1, 2, 3) << "''" << "'" ; |
| 1536 | QTest::newRow(dataTag: "23" ) << QTime(1, 2, 3) << "'''" << "'" ; |
| 1537 | QTest::newRow(dataTag: "24" ) << QTime(1, 2, 3) << "\"" << "\"" ; |
| 1538 | QTest::newRow(dataTag: "25" ) << QTime(1, 2, 3) << "\"\"" << "\"\"" ; |
| 1539 | QTest::newRow(dataTag: "26" ) << QTime(1, 2, 3) << "\"H\"" << "\"1\"" ; |
| 1540 | QTest::newRow(dataTag: "27" ) << QTime(1, 2, 3) << "'\"H\"'" << "\"H\"" ; |
| 1541 | |
| 1542 | QTest::newRow(dataTag: "28" ) << QTime(1, 2, 3, 456) << "H:m:s.z" << "1:2:3.456" ; |
| 1543 | QTest::newRow(dataTag: "29" ) << QTime(1, 2, 3, 456) << "H:m:s.zz" << "1:2:3.456456" ; |
| 1544 | QTest::newRow(dataTag: "30" ) << QTime(1, 2, 3, 456) << "H:m:s.zzz" << "1:2:3.456" ; |
| 1545 | QTest::newRow(dataTag: "31" ) << QTime(1, 2, 3, 400) << "H:m:s.z" << "1:2:3.4" ; |
| 1546 | QTest::newRow(dataTag: "32" ) << QTime(1, 2, 3, 4) << "H:m:s.z" << "1:2:3.004" ; |
| 1547 | QTest::newRow(dataTag: "33" ) << QTime(1, 2, 3, 4) << "H:m:s.zzz" << "1:2:3.004" ; |
| 1548 | QTest::newRow(dataTag: "34" ) << QTime() << "H:m:s.zzz" << "" ; |
| 1549 | QTest::newRow(dataTag: "35" ) << QTime(1, 2, 3, 4) << "dd MM yyyy H:m:s.zzz" << "dd MM yyyy 1:2:3.004" ; |
| 1550 | } |
| 1551 | |
| 1552 | void tst_QLocale::formatTime() |
| 1553 | { |
| 1554 | QFETCH(QTime, time); |
| 1555 | QFETCH(QString, format); |
| 1556 | QFETCH(QString, result); |
| 1557 | |
| 1558 | QLocale l(QLocale::C); |
| 1559 | QCOMPARE(l.toString(time, format), result); |
| 1560 | QCOMPARE(l.toString(time, QStringView(format)), result); |
| 1561 | } |
| 1562 | |
| 1563 | |
| 1564 | void tst_QLocale::formatDateTime_data() |
| 1565 | { |
| 1566 | QTest::addColumn<QString>(name: "localeName" ); |
| 1567 | QTest::addColumn<QDateTime>(name: "dateTime" ); |
| 1568 | QTest::addColumn<QString>(name: "format" ); |
| 1569 | QTest::addColumn<QString>(name: "result" ); |
| 1570 | |
| 1571 | QTest::newRow(dataTag: "1C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13)) |
| 1572 | << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14" ; |
| 1573 | QTest::newRow(dataTag: "2C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1574 | << "d/M/yyyyy h" << "1/12/1974y 15" ; |
| 1575 | QTest::newRow(dataTag: "4C" ) << "C" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13)) |
| 1576 | << "d/M/yyyy zzz" << "1/1/1974 000" ; |
| 1577 | QTest::newRow(dataTag: "5C" ) << "C" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13)) |
| 1578 | << "dd/MM/yyy z" << "01/01/74y 0" ; |
| 1579 | QTest::newRow(dataTag: "6C" ) << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13)) |
| 1580 | << "ddd/MMM/yy AP" << "Mon/Dec/74 PM" ; |
| 1581 | QTest::newRow(dataTag: "7C" ) << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13)) |
| 1582 | << "dddd/MMMM/y apa" << "Monday/December/y pmpm" ; |
| 1583 | QTest::newRow(dataTag: "8C" ) << "C" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13)) |
| 1584 | << "ddddd/MMMMM/yy ss" << "Monday2/December12/74 13" ; |
| 1585 | QTest::newRow(dataTag: "9C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1586 | << "'dddd'/MMMM/yy s" << "dddd/December/74 13" ; |
| 1587 | QTest::newRow(dataTag: "10C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 4, 13)) |
| 1588 | << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/December/74y 4m04" ; |
| 1589 | QTest::newRow(dataTag: "11C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 3)) |
| 1590 | << "d'dd'd/MMM'M'/yysss" << "1dd1/DecM/74033" ; |
| 1591 | QTest::newRow(dataTag: "12C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1592 | << "d'd'dd/M/yyh" << "1d01/12/7415" ; |
| 1593 | |
| 1594 | QTest::newRow(dataTag: "dd MMMM yyyy, hh:mm:ss" ) << "C" << QDateTime(QDate(1, 1, 1), QTime(12, 00, 00)) |
| 1595 | << "dd MMMM yyyy, hh:mm:ss" << "01 January 0001, 12:00:00" ; |
| 1596 | |
| 1597 | QTest::newRow(dataTag: "20C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1598 | << "foo" << "foo" ; |
| 1599 | QTest::newRow(dataTag: "21C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1600 | << "'" << "" ; |
| 1601 | QTest::newRow(dataTag: "22C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1602 | << "''" << "'" ; |
| 1603 | QTest::newRow(dataTag: "23C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1604 | << "'''" << "'" ; |
| 1605 | QTest::newRow(dataTag: "24C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1606 | << "\"" << "\"" ; |
| 1607 | QTest::newRow(dataTag: "25C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1608 | << "\"\"" << "\"\"" ; |
| 1609 | QTest::newRow(dataTag: "26C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1610 | << "\"yymm\"" << "\"7414\"" ; |
| 1611 | QTest::newRow(dataTag: "27C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1612 | << "'\"yymm\"'" << "\"yymm\"" ; |
| 1613 | QTest::newRow(dataTag: "28C" ) << "C" << QDateTime() |
| 1614 | << "'\"yymm\"'" << "" ; |
| 1615 | |
| 1616 | QTest::newRow(dataTag: "1no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 13)) |
| 1617 | << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14" ; |
| 1618 | QTest::newRow(dataTag: "2no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1619 | << "d/M/yyyyy h" << "1/12/1974y 15" ; |
| 1620 | QTest::newRow(dataTag: "4no_NO" ) << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13)) |
| 1621 | << "d/M/yyyy zzz" << "1/1/1974 000" ; |
| 1622 | QTest::newRow(dataTag: "5no_NO" ) << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(15, 14, 13)) |
| 1623 | << "dd/MM/yyy z" << "01/01/74y 0" ; |
| 1624 | QTest::newRow(dataTag: "6no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13)) |
| 1625 | << "ddd/MMM/yy AP" << "man./des./74 P.M." ; |
| 1626 | QTest::newRow(dataTag: "7no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13)) |
| 1627 | << "dddd/MMMM/y apa" << "mandag/desember/y p.m.p.m." ; |
| 1628 | QTest::newRow(dataTag: "8no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(15, 14, 13)) |
| 1629 | << "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13" ; |
| 1630 | QTest::newRow(dataTag: "9no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1631 | << "'dddd'/MMMM/yy s" << "dddd/desember/74 13" ; |
| 1632 | QTest::newRow(dataTag: "10no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 4, 13)) |
| 1633 | << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/desember/74y 4m04" ; |
| 1634 | QTest::newRow(dataTag: "11no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 3)) |
| 1635 | << "d'dd'd/MMM'M'/yysss" << "1dd1/des.M/74033" ; |
| 1636 | QTest::newRow(dataTag: "12no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1637 | << "d'd'dd/M/yyh" << "1d01/12/7415" ; |
| 1638 | |
| 1639 | QTest::newRow(dataTag: "20no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1640 | << "foo" << "foo" ; |
| 1641 | QTest::newRow(dataTag: "21no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1642 | << "'" << "" ; |
| 1643 | QTest::newRow(dataTag: "22no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1644 | << "''" << "'" ; |
| 1645 | QTest::newRow(dataTag: "23no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1646 | << "'''" << "'" ; |
| 1647 | QTest::newRow(dataTag: "24no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1648 | << "\"" << "\"" ; |
| 1649 | QTest::newRow(dataTag: "25no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1650 | << "\"\"" << "\"\"" ; |
| 1651 | QTest::newRow(dataTag: "26no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1652 | << "\"yymm\"" << "\"7414\"" ; |
| 1653 | QTest::newRow(dataTag: "27no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 14, 13)) |
| 1654 | << "'\"yymm\"'" << "\"yymm\"" ; |
| 1655 | QTest::newRow(dataTag: "28no_NO" ) << "no_NO" << QDateTime() |
| 1656 | << "'\"yymm\"'" << "" ; |
| 1657 | |
| 1658 | QDateTime testLongHour(QDate(1999, 12, 31), QTime(23, 59, 59, 999)); |
| 1659 | QDateTime testShortHour(QDate(1999, 12, 31), QTime(3, 59, 59, 999)); |
| 1660 | QDateTime testZeroHour(QDate(1999, 12, 31), QTime(0, 59, 59, 999)); |
| 1661 | |
| 1662 | QTest::newRow(dataTag: "datetime0" ) << "en_US" << QDateTime() |
| 1663 | << QString("dd-MM-yyyy hh:mm:ss" ) << QString(); |
| 1664 | QTest::newRow(dataTag: "datetime1" ) << "en_US" << testLongHour |
| 1665 | << QString("dd-'mmddyy'MM-yyyy hh:mm:ss.zzz" ) |
| 1666 | << QString("31-mmddyy12-1999 23:59:59.999" ); |
| 1667 | QTest::newRow(dataTag: "datetime2" ) << "en_US" << testLongHour |
| 1668 | << QString("dd-'apAP'MM-yyyy hh:mm:ss.zzz" ) |
| 1669 | << QString("31-apAP12-1999 23:59:59.999" ); |
| 1670 | QTest::newRow(dataTag: "datetime3" ) << "en_US" << testLongHour |
| 1671 | << QString("Apdd-MM-yyyy hh:mm:ss.zzz" ) |
| 1672 | << QString("PMp31-12-1999 11:59:59.999" ); |
| 1673 | QTest::newRow(dataTag: "datetime4" ) << "en_US" << testLongHour |
| 1674 | << QString("'ap'apdd-MM-yyyy 'AP'hh:mm:ss.zzz" ) |
| 1675 | << QString("appm31-12-1999 AP11:59:59.999" ); |
| 1676 | QTest::newRow(dataTag: "datetime5" ) << "en_US" << testLongHour |
| 1677 | << QString("'''" ) << QString("'" ); |
| 1678 | QTest::newRow(dataTag: "datetime6" ) << "en_US" << testLongHour |
| 1679 | << QString("'ap" ) << QString("ap" ); |
| 1680 | QTest::newRow(dataTag: "datetime7" ) << "en_US" << testLongHour |
| 1681 | << QString("' ' 'hh' hh" ) << QString(" hh 23" ); |
| 1682 | QTest::newRow(dataTag: "datetime8" ) << "en_US" << testLongHour |
| 1683 | << QString("d'foobar'" ) << QString("31foobar" ); |
| 1684 | QTest::newRow(dataTag: "datetime9" ) << "en_US" << testShortHour |
| 1685 | << QString("hhhhh" ) << QString("03033" ); |
| 1686 | QTest::newRow(dataTag: "datetime11" ) << "en_US" << testLongHour |
| 1687 | << QString("HHHhhhAaAPap" ) << QString("23231111PMpmPMpm" ); |
| 1688 | QTest::newRow(dataTag: "datetime12" ) << "en_US" << testShortHour |
| 1689 | << QString("HHHhhhAaAPap" ) << QString("033033AMamAMam" ); |
| 1690 | QTest::newRow(dataTag: "datetime13" ) << "en_US" << QDateTime(QDate(1974, 12, 1), QTime(14, 14, 20)) |
| 1691 | << QString("hh''mm''ss dd''MM''yyyy" ) |
| 1692 | << QString("14'14'20 01'12'1974" ); |
| 1693 | QTest::newRow(dataTag: "AM no p" ) << "en_US" << testZeroHour |
| 1694 | << QString("hhAX" ) << QString("12AMX" ); |
| 1695 | QTest::newRow(dataTag: "AM no p, x 2" ) << "en_US" << testShortHour |
| 1696 | << QString("hhhhhaA" ) << QString("03033amAM" ); |
| 1697 | QTest::newRow(dataTag: "am 0 hour" ) << "en_US" << testZeroHour |
| 1698 | << QString("hAP" ) << QString("12AM" ); |
| 1699 | QTest::newRow(dataTag: "AM zero hour" ) << "en_US" << testZeroHour |
| 1700 | << QString("hhAP" ) << QString("12AM" ); |
| 1701 | QTest::newRow(dataTag: "dddd" ) << "en_US" << testZeroHour |
| 1702 | << QString("dddd" ) << QString("Friday" ); |
| 1703 | QTest::newRow(dataTag: "ddd" ) << "en_US" << testZeroHour |
| 1704 | << QString("ddd" ) << QString("Fri" ); |
| 1705 | QTest::newRow(dataTag: "MMMM" ) << "en_US" << testZeroHour |
| 1706 | << QString("MMMM" ) << QString("December" ); |
| 1707 | QTest::newRow(dataTag: "MMM" ) << "en_US" << testZeroHour |
| 1708 | << QString("MMM" ) << QString("Dec" ); |
| 1709 | QTest::newRow(dataTag: "empty" ) << "en_US" << testZeroHour |
| 1710 | << QString("" ) << QString("" ); |
| 1711 | } |
| 1712 | |
| 1713 | void tst_QLocale::formatDateTime() |
| 1714 | { |
| 1715 | QFETCH(QString, localeName); |
| 1716 | QFETCH(QDateTime, dateTime); |
| 1717 | QFETCH(QString, format); |
| 1718 | QFETCH(QString, result); |
| 1719 | |
| 1720 | QLocale l(localeName); |
| 1721 | QCOMPARE(l.toString(dateTime, format), result); |
| 1722 | QCOMPARE(l.toString(dateTime, QStringView(format)), result); |
| 1723 | } |
| 1724 | |
| 1725 | void tst_QLocale::formatTimeZone() |
| 1726 | { |
| 1727 | QLocale enUS("en_US" ); |
| 1728 | |
| 1729 | QDateTime dt1(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, 60 * 60); |
| 1730 | QCOMPARE(enUS.toString(dt1, "t" ), QLatin1String("UTC+01:00" )); |
| 1731 | |
| 1732 | QDateTime dt2(QDate(2013, 1, 1), QTime(1, 0, 0), Qt::OffsetFromUTC, -60 * 60); |
| 1733 | QCOMPARE(enUS.toString(dt2, "t" ), QLatin1String("UTC-01:00" )); |
| 1734 | |
| 1735 | QDateTime dt3(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::UTC); |
| 1736 | QCOMPARE(enUS.toString(dt3, "t" ), QLatin1String("UTC" )); |
| 1737 | |
| 1738 | // LocalTime should vary |
| 1739 | if (europeanTimeZone) { |
| 1740 | // Time definitely in Standard Time |
| 1741 | QDateTime dt4(QDate(2013, 1, 1), QTime(0, 0, 0), Qt::LocalTime); |
| 1742 | #ifdef Q_OS_WIN |
| 1743 | QEXPECT_FAIL("" , "Windows only returns long name (QTBUG-32759)" , Continue); |
| 1744 | #endif // Q_OS_WIN |
| 1745 | QCOMPARE(enUS.toString(dt4, "t" ), QLatin1String("CET" )); |
| 1746 | |
| 1747 | // Time definitely in Daylight Time |
| 1748 | QDateTime dt5(QDate(2013, 6, 1), QTime(0, 0, 0), Qt::LocalTime); |
| 1749 | #ifdef Q_OS_WIN |
| 1750 | QEXPECT_FAIL("" , "Windows only returns long name (QTBUG-32759)" , Continue); |
| 1751 | #endif // Q_OS_WIN |
| 1752 | QCOMPARE(enUS.toString(dt5, "t" ), QLatin1String("CEST" )); |
| 1753 | } else { |
| 1754 | qDebug(msg: "(Skipped some CET-only tests)" ); |
| 1755 | } |
| 1756 | |
| 1757 | #if QT_CONFIG(timezone) |
| 1758 | const QTimeZone berlin("Europe/Berlin" ); |
| 1759 | const QDateTime jan(QDate(2010, 1, 1).startOfDay(zone: berlin)); |
| 1760 | const QDateTime jul(QDate(2010, 7, 1).startOfDay(zone: berlin)); |
| 1761 | |
| 1762 | QCOMPARE(enUS.toString(jan, "t" ), berlin.abbreviation(jan)); |
| 1763 | QCOMPARE(enUS.toString(jul, "t" ), berlin.abbreviation(jul)); |
| 1764 | #endif |
| 1765 | |
| 1766 | // Current datetime should return current abbreviation |
| 1767 | QCOMPARE(enUS.toString(QDateTime::currentDateTime(), "t" ), |
| 1768 | QDateTime::currentDateTime().timeZoneAbbreviation()); |
| 1769 | |
| 1770 | // Time on its own will always be current local time zone |
| 1771 | QCOMPARE(enUS.toString(QTime(1, 2, 3), "t" ), |
| 1772 | QDateTime::currentDateTime().timeZoneAbbreviation()); |
| 1773 | } |
| 1774 | |
| 1775 | void tst_QLocale::toDateTime_data() |
| 1776 | { |
| 1777 | QTest::addColumn<QString>(name: "localeName" ); |
| 1778 | QTest::addColumn<QDateTime>(name: "result" ); |
| 1779 | QTest::addColumn<QString>(name: "format" ); |
| 1780 | QTest::addColumn<QString>(name: "string" ); |
| 1781 | QTest::addColumn<bool>(name: "clean" ); // No non-format letters in format string |
| 1782 | |
| 1783 | QTest::newRow(dataTag: "1C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 0)) |
| 1784 | << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14" << true; |
| 1785 | QTest::newRow(dataTag: "2C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0)) |
| 1786 | << "d/M/yyyyy h" << "1/12/1974y 15" << false; |
| 1787 | QTest::newRow(dataTag: "4C" ) << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 1)) |
| 1788 | << "d/M/yyyy zzz" << "1/1/1974 001" << true; |
| 1789 | QTest::newRow(dataTag: "5C" ) << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 1)) |
| 1790 | << "dd/MM/yyy z" << "01/01/74y 001" << false; |
| 1791 | QTest::newRow(dataTag: "6C" ) << "C" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0, 100)) |
| 1792 | << "dd/MM/yyy z" << "01/01/74y 1" << false; |
| 1793 | QTest::newRow(dataTag: "8C" ) << "C" << QDateTime(QDate(1974, 12, 2), QTime(0, 0, 13)) |
| 1794 | << "ddddd/MMMMM/yy ss" << "Monday2/December12/74 13" << true; |
| 1795 | QTest::newRow(dataTag: "9C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 13)) |
| 1796 | << "'dddd'/MMMM/yy s" << "dddd/December/74 13" << false; |
| 1797 | QTest::newRow(dataTag: "10C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 4, 0)) |
| 1798 | << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/December/74y 4m04" << false; |
| 1799 | QTest::newRow(dataTag: "11C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 3)) |
| 1800 | << "d'dd'd/MMM'M'/yysss" << "1dd1/DecM/74033" << false; |
| 1801 | QTest::newRow(dataTag: "12C" ) << "C" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0)) |
| 1802 | << "d'd'dd/M/yyh" << "1d01/12/7415" << false; |
| 1803 | // Unpadded value for fixed-width field is wrong: |
| 1804 | QTest::newRow(dataTag: "bad-day-C" ) << "C" << QDateTime() << "dd-MMM-yy" << "4-Jun-11" << true; |
| 1805 | QTest::newRow(dataTag: "bad-month-C" ) << "C" << QDateTime() << "d-MM-yy" << "4-6-11" << true; |
| 1806 | QTest::newRow(dataTag: "bad-year-C" ) << "C" << QDateTime() << "d-MMM-yyyy" << "4-Jun-11" << true; |
| 1807 | QTest::newRow(dataTag: "bad-hour-C" ) << "C" << QDateTime() << "d-MMM-yy hh:m" << "4-Jun-11 1:2" << true; |
| 1808 | QTest::newRow(dataTag: "bad-min-C" ) << "C" << QDateTime() << "d-MMM-yy h:mm" << "4-Jun-11 1:2" << true; |
| 1809 | QTest::newRow(dataTag: "bad-sec-C" ) |
| 1810 | << "C" << QDateTime() << "d-MMM-yy h:m:ss" << "4-Jun-11 1:2:3" << true; |
| 1811 | QTest::newRow(dataTag: "bad-milli-C" ) |
| 1812 | << "C" << QDateTime() << "d-MMM-yy h:m:s.zzz" << "4-Jun-11 1:2:3.4" << true; |
| 1813 | QTest::newRow(dataTag: "ok-C" ) << "C" << QDateTime(QDate(1911, 6, 4), QTime(1, 2, 3, 400)) |
| 1814 | << "d-MMM-yy h:m:s.z" << "4-Jun-11 1:2:3.4" << true; |
| 1815 | |
| 1816 | QTest::newRow(dataTag: "1no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(5, 14, 0)) |
| 1817 | << "d/M/yyyy hh:h:mm" << "1/12/1974 05:5:14" << true; |
| 1818 | QTest::newRow(dataTag: "2no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0)) |
| 1819 | << "d/M/yyyyy h" << "1/12/1974y 15" << false; |
| 1820 | QTest::newRow(dataTag: "4no_NO" ) << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0)) |
| 1821 | << "d/M/yyyy zzz" << "1/1/1974 000" << true; |
| 1822 | QTest::newRow(dataTag: "5no_NO" ) << "no_NO" << QDateTime(QDate(1974, 1, 1), QTime(0, 0, 0)) |
| 1823 | << "dd/MM/yyy z" << "01/01/74y 0" << false; |
| 1824 | QTest::newRow(dataTag: "8no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 2), QTime(0, 0, 13)) |
| 1825 | << "ddddd/MMMMM/yy ss" << "mandag2/desember12/74 13" << true; |
| 1826 | QTest::newRow(dataTag: "9no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 13)) |
| 1827 | << "'dddd'/MMMM/yy s" << "dddd/desember/74 13" << false; |
| 1828 | QTest::newRow(dataTag: "10no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 4, 0)) |
| 1829 | << "d'dd'd/MMMM/yyy m'm'mm" << "1dd1/desember/74y 4m04" << false; |
| 1830 | QTest::newRow(dataTag: "11no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(0, 0, 3)) |
| 1831 | << "d'dd'd/MMM'M'/yysss" << "1dd1/des.M/74033" << false; |
| 1832 | QTest::newRow(dataTag: "12no_NO" ) << "no_NO" << QDateTime(QDate(1974, 12, 1), QTime(15, 0, 0)) |
| 1833 | << "d'd'dd/M/yyh" << "1d01/12/7415" << false; |
| 1834 | |
| 1835 | QTest::newRow(dataTag: "RFC-1123" ) |
| 1836 | << "C" << QDateTime(QDate(2007, 11, 1), QTime(18, 8, 30)) |
| 1837 | << "ddd, dd MMM yyyy hh:mm:ss 'GMT'" << "Thu, 01 Nov 2007 18:08:30 GMT" << false; |
| 1838 | |
| 1839 | QTest::newRow(dataTag: "longFormat" ) |
| 1840 | << "en_US" << QDateTime(QDate(2009, 1, 5), QTime(11, 48, 32)) |
| 1841 | << "dddd, MMMM d, yyyy h:mm:ss AP " << "Monday, January 5, 2009 11:48:32 AM " << true; |
| 1842 | |
| 1843 | const QDateTime dt(QDate(2017, 02, 25), QTime(17, 21, 25)); |
| 1844 | // These formats correspond to the locale formats, with the timezone removed. |
| 1845 | // We hardcode them in case an update to the locale DB changes them. |
| 1846 | |
| 1847 | QTest::newRow(dataTag: "C:long" ) << "C" << dt << "dddd, d MMMM yyyy HH:mm:ss" |
| 1848 | << "Saturday, 25 February 2017 17:21:25" << true; |
| 1849 | QTest::newRow(dataTag: "C:short" ) |
| 1850 | << "C" << dt << "d MMM yyyy HH:mm:ss" << "25 Feb 2017 17:21:25" << true; |
| 1851 | QTest::newRow(dataTag: "C:narrow" ) |
| 1852 | << "C" << dt << "d MMM yyyy HH:mm:ss" << "25 Feb 2017 17:21:25" << true; |
| 1853 | |
| 1854 | QTest::newRow(dataTag: "fr:long" ) << "fr" << dt << "dddd d MMMM yyyy HH:mm:ss" |
| 1855 | << "Samedi 25 février 2017 17:21:25" << true; |
| 1856 | QTest::newRow(dataTag: "fr:short" ) |
| 1857 | << "fr" << dt.addSecs(secs: -25) << "dd/MM/yyyy HH:mm" << "25/02/2017 17:21" << true; |
| 1858 | |
| 1859 | // In Turkish, the word for Friday ("Cuma") is a prefix for the word for |
| 1860 | // Saturday ("Cumartesi") |
| 1861 | QTest::newRow(dataTag: "tr:long" ) |
| 1862 | << "tr" << dt << "d MMMM yyyy dddd HH:mm:ss" << "25 Şubat 2017 Cumartesi 17:21:25" << true; |
| 1863 | QTest::newRow(dataTag: "tr:long2" ) << "tr" << dt.addDays(days: -1) << "d MMMM yyyy dddd HH:mm:ss" |
| 1864 | << "24 Şubat 2017 Cuma 17:21:25" << true; |
| 1865 | QTest::newRow(dataTag: "tr:mashed" ) |
| 1866 | << "tr" << dt << "d MMMMyyyy ddddHH:mm:ss" << "25 Şubat2017 Cumartesi17:21:25" << true; |
| 1867 | QTest::newRow(dataTag: "tr:mashed2" ) << "tr" << dt.addDays(days: -1) << "d MMMMyyyy ddddHH:mm:ss" |
| 1868 | << "24 Şubat2017 Cuma17:21:25" << true; |
| 1869 | QTest::newRow(dataTag: "tr:short" ) |
| 1870 | << "tr" << dt.addSecs(secs: -25) << "d.MM.yyyy HH:mm" << "25.02.2017 17:21" << true; |
| 1871 | } |
| 1872 | |
| 1873 | void tst_QLocale::toDateTime() |
| 1874 | { |
| 1875 | QFETCH(QString, localeName); |
| 1876 | QFETCH(QDateTime, result); |
| 1877 | QFETCH(QString, format); |
| 1878 | QFETCH(QString, string); |
| 1879 | QFETCH(bool, clean); |
| 1880 | |
| 1881 | QLocale l(localeName); |
| 1882 | QCOMPARE(l.toDateTime(string, format), result); |
| 1883 | if (clean) { |
| 1884 | QCOMPARE(l.toDateTime(string.toLower(), format), result); |
| 1885 | QCOMPARE(l.toDateTime(string.toUpper(), format), result); |
| 1886 | } |
| 1887 | |
| 1888 | if (l.dateTimeFormat(format: QLocale::LongFormat) == format) |
| 1889 | QCOMPARE(l.toDateTime(string, QLocale::LongFormat), result); |
| 1890 | if (l.dateTimeFormat(format: QLocale::ShortFormat) == format) |
| 1891 | QCOMPARE(l.toDateTime(string, QLocale::ShortFormat), result); |
| 1892 | } |
| 1893 | |
| 1894 | #ifdef Q_OS_MAC |
| 1895 | |
| 1896 | // Format number string according to system locale settings. |
| 1897 | // Expected in format is US "1,234.56". |
| 1898 | QString systemLocaleFormatNumber(QString &&numberString) |
| 1899 | { |
| 1900 | QLocale locale = QLocale::system(); |
| 1901 | QString numberStringMunged = |
| 1902 | numberString.replace(QChar(','), QChar('G')).replace(QChar('.'), QChar('D')); |
| 1903 | if (locale.numberOptions() & QLocale::OmitGroupSeparator) |
| 1904 | numberStringMunged.remove(QLatin1Char('G')); |
| 1905 | else |
| 1906 | numberStringMunged.replace(QChar('G'), locale.groupSeparator()); |
| 1907 | return numberStringMunged.replace(QChar('D'), locale.decimalPoint()); |
| 1908 | } |
| 1909 | |
| 1910 | void tst_QLocale::macDefaultLocale() |
| 1911 | { |
| 1912 | QLocale locale = QLocale::system(); |
| 1913 | |
| 1914 | if (locale.name() != QLatin1String("en_US" )) |
| 1915 | QSKIP("This test only tests for en_US" ); |
| 1916 | |
| 1917 | QTime invalidTime; |
| 1918 | QDate invalidDate; |
| 1919 | QCOMPARE(locale.toString(invalidTime, QLocale::ShortFormat), QString()); |
| 1920 | QCOMPARE(locale.toString(invalidDate, QLocale::ShortFormat), QString()); |
| 1921 | QCOMPARE(locale.toString(invalidTime, QLocale::NarrowFormat), QString()); |
| 1922 | QCOMPARE(locale.toString(invalidDate, QLocale::NarrowFormat), QString()); |
| 1923 | QCOMPARE(locale.toString(invalidTime, QLocale::LongFormat), QString()); |
| 1924 | QCOMPARE(locale.toString(invalidDate, QLocale::LongFormat), QString()); |
| 1925 | |
| 1926 | // On OS X the decimal point and group separator are configurable |
| 1927 | // independently of the locale. Verify that they have one of the |
| 1928 | // allowed values and are not the same. |
| 1929 | QVERIFY(locale.decimalPoint() == QChar('.') || locale.decimalPoint() == QChar(',')); |
| 1930 | if (!(locale.numberOptions() & QLocale::OmitGroupSeparator)) { |
| 1931 | QVERIFY(locale.groupSeparator() == QChar(',') |
| 1932 | || locale.groupSeparator() == QChar('.') |
| 1933 | || locale.groupSeparator() == QChar('\xA0') // no-breaking space |
| 1934 | || locale.groupSeparator() == QChar('\'') |
| 1935 | || locale.groupSeparator() == QChar()); |
| 1936 | QVERIFY(locale.decimalPoint() != locale.groupSeparator()); |
| 1937 | } |
| 1938 | |
| 1939 | // make sure we are using the system to parse them |
| 1940 | QCOMPARE(locale.toString(1234.56), systemLocaleFormatNumber(QString("1,234.56" ))); |
| 1941 | |
| 1942 | QTime testTime = QTime(1, 2, 3); |
| 1943 | QTime utcTime = QDateTime(QDate::currentDate(), testTime).toUTC().time(); |
| 1944 | int diff = testTime.hour() - utcTime.hour(); |
| 1945 | |
| 1946 | // Check if local time and utc time are on opposite sides of the 24-hour wrap-around. |
| 1947 | if (diff < -12) |
| 1948 | diff += 24; |
| 1949 | if (diff > 12) |
| 1950 | diff -= 24; |
| 1951 | |
| 1952 | const QString timeString = locale.toString(testTime, QLocale::LongFormat); |
| 1953 | QVERIFY(timeString.contains(QString("1:02:03" ))); |
| 1954 | |
| 1955 | // To run this test make sure "Curreny" is US Dollar in System Preferences->Language & Region->Advanced. |
| 1956 | if (locale.currencySymbol() == QString("$" )) { |
| 1957 | QCOMPARE(locale.toCurrencyString(qulonglong(1234)), |
| 1958 | systemLocaleFormatNumber(QString("$1,234.00" ))); |
| 1959 | QCOMPARE(locale.toCurrencyString(double(1234.56)), |
| 1960 | systemLocaleFormatNumber(QString("$1,234.56" ))); |
| 1961 | } |
| 1962 | |
| 1963 | // Depending on the configured time zone, the time string might not |
| 1964 | // contain a GMT specifier. (Sometimes it just names the zone, like "CEST") |
| 1965 | QLatin1String gmt("GMT" ); |
| 1966 | if (timeString.contains(gmt) && diff) { |
| 1967 | QLatin1Char sign(diff < 0 ? '-' : '+'); |
| 1968 | QString number(QString::number(qAbs(diff))); |
| 1969 | const QString expect = gmt + sign + number; |
| 1970 | |
| 1971 | if (diff < 10) { |
| 1972 | const QString zeroed = gmt + sign + QLatin1Char('0') + number; |
| 1973 | |
| 1974 | QVERIFY2(timeString.contains(expect) || timeString.contains(zeroed), |
| 1975 | qPrintable(QString("timeString `%1', expected GMT specifier `%2' or `%3'" ) |
| 1976 | .arg(timeString).arg(expect).arg(zeroed))); |
| 1977 | } else { |
| 1978 | QVERIFY2(timeString.contains(expect), |
| 1979 | qPrintable(QString("timeString `%1', expected GMT specifier `%2'" ) |
| 1980 | .arg(timeString).arg(expect))); |
| 1981 | } |
| 1982 | } |
| 1983 | QCOMPARE(locale.dayName(1), QString("Monday" )); |
| 1984 | QCOMPARE(locale.dayName(7), QString("Sunday" )); |
| 1985 | QCOMPARE(locale.monthName(1), QString("January" )); |
| 1986 | QCOMPARE(locale.monthName(12), QString("December" )); |
| 1987 | QCOMPARE(locale.quoteString("string" ), |
| 1988 | QString::fromUtf8("\xe2\x80\x9c" "string" "\xe2\x80\x9d" )); |
| 1989 | QCOMPARE(locale.quoteString("string" , QLocale::AlternateQuotation), |
| 1990 | QString::fromUtf8("\xe2\x80\x98" "string" "\xe2\x80\x99" )); |
| 1991 | |
| 1992 | QList<Qt::DayOfWeek> days; |
| 1993 | days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday; |
| 1994 | QCOMPARE(locale.weekdays(), days); |
| 1995 | |
| 1996 | } |
| 1997 | #endif // Q_OS_MAC |
| 1998 | |
| 1999 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) |
| 2000 | #include <qt_windows.h> |
| 2001 | |
| 2002 | static QString getWinLocaleInfo(LCTYPE type) |
| 2003 | { |
| 2004 | LCID id = GetThreadLocale(); |
| 2005 | int cnt = GetLocaleInfo(id, type, 0, 0) * 2; |
| 2006 | |
| 2007 | if (cnt == 0) { |
| 2008 | qWarning().nospace() << "QLocale: empty windows locale info (" << type << ')'; |
| 2009 | return QString(); |
| 2010 | } |
| 2011 | cnt /= sizeof(wchar_t); |
| 2012 | QScopedArrayPointer<wchar_t> buf(new wchar_t[cnt]); |
| 2013 | cnt = GetLocaleInfo(id, type, buf.data(), cnt); |
| 2014 | |
| 2015 | if (cnt == 0) { |
| 2016 | qWarning().nospace() << "QLocale: empty windows locale info (" << type << ')'; |
| 2017 | return QString(); |
| 2018 | } |
| 2019 | return QString::fromWCharArray(buf.data()); |
| 2020 | } |
| 2021 | |
| 2022 | static void setWinLocaleInfo(LCTYPE type, const QString &value) |
| 2023 | { |
| 2024 | LCID id = GetThreadLocale(); |
| 2025 | SetLocaleInfo(id, type, reinterpret_cast<const wchar_t*>(value.utf16())); |
| 2026 | } |
| 2027 | |
| 2028 | #ifndef LOCALE_SSHORTTIME |
| 2029 | # define LOCALE_SSHORTTIME 0x00000079 |
| 2030 | #endif |
| 2031 | |
| 2032 | class RestoreLocaleHelper |
| 2033 | { |
| 2034 | public: |
| 2035 | RestoreLocaleHelper() |
| 2036 | { |
| 2037 | m_decimal = getWinLocaleInfo(LOCALE_SDECIMAL); |
| 2038 | m_thousand = getWinLocaleInfo(LOCALE_STHOUSAND); |
| 2039 | m_sdate = getWinLocaleInfo(LOCALE_SSHORTDATE); |
| 2040 | m_ldate = getWinLocaleInfo(LOCALE_SLONGDATE); |
| 2041 | m_time = getWinLocaleInfo(LOCALE_SSHORTTIME); |
| 2042 | } |
| 2043 | |
| 2044 | ~RestoreLocaleHelper() |
| 2045 | { |
| 2046 | // restore these, or the user will get a surprise |
| 2047 | setWinLocaleInfo(LOCALE_SDECIMAL, m_decimal); |
| 2048 | setWinLocaleInfo(LOCALE_STHOUSAND, m_thousand); |
| 2049 | setWinLocaleInfo(LOCALE_SSHORTDATE, m_sdate); |
| 2050 | setWinLocaleInfo(LOCALE_SLONGDATE, m_ldate); |
| 2051 | setWinLocaleInfo(LOCALE_SSHORTTIME, m_time); |
| 2052 | |
| 2053 | QSystemLocale dummy; // to provoke a refresh of the system locale |
| 2054 | } |
| 2055 | |
| 2056 | QString m_decimal, m_thousand, m_sdate, m_ldate, m_time; |
| 2057 | }; |
| 2058 | |
| 2059 | void tst_QLocale::windowsDefaultLocale() |
| 2060 | { |
| 2061 | RestoreLocaleHelper systemLocale; |
| 2062 | // set weird system defaults and make sure we're using them |
| 2063 | setWinLocaleInfo(LOCALE_SDECIMAL, QLatin1String("@" )); |
| 2064 | setWinLocaleInfo(LOCALE_STHOUSAND, QLatin1String("?" )); |
| 2065 | const QString shortDateFormat = QStringLiteral("d*M*yyyy" ); |
| 2066 | setWinLocaleInfo(LOCALE_SSHORTDATE, shortDateFormat); |
| 2067 | const QString longDateFormat = QStringLiteral("d@M@yyyy" ); |
| 2068 | setWinLocaleInfo(LOCALE_SLONGDATE, longDateFormat); |
| 2069 | const QString shortTimeFormat = QStringLiteral("h^m^s" ); |
| 2070 | setWinLocaleInfo(LOCALE_SSHORTTIME, shortTimeFormat); |
| 2071 | const QString longTimeFormat = QStringLiteral("HH%mm%ss" ); |
| 2072 | setWinLocaleInfo(LOCALE_STIMEFORMAT, longTimeFormat); |
| 2073 | |
| 2074 | QSystemLocale dummy; // to provoke a refresh of the system locale |
| 2075 | QLocale locale = QLocale::system(); |
| 2076 | |
| 2077 | // make sure we are seeing the system's format strings |
| 2078 | QCOMPARE(locale.decimalPoint(), QChar('@')); |
| 2079 | QCOMPARE(locale.groupSeparator(), QChar('?')); |
| 2080 | QCOMPARE(locale.dateFormat(QLocale::ShortFormat), shortDateFormat); |
| 2081 | QCOMPARE(locale.dateFormat(QLocale::LongFormat), longDateFormat); |
| 2082 | QCOMPARE(locale.timeFormat(QLocale::ShortFormat), shortTimeFormat); |
| 2083 | QCOMPARE(locale.dateTimeFormat(QLocale::ShortFormat), |
| 2084 | shortDateFormat + QLatin1Char(' ') + shortTimeFormat); |
| 2085 | const QString expectedLongDateTimeFormat |
| 2086 | = longDateFormat + QLatin1Char(' ') + longTimeFormat; |
| 2087 | QCOMPARE(locale.dateTimeFormat(QLocale::LongFormat), expectedLongDateTimeFormat); |
| 2088 | |
| 2089 | // make sure we are using the system to parse them |
| 2090 | QCOMPARE(locale.toString(1234.56), QString("1?234@56" )); |
| 2091 | QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat), QString("1*12*1974" )); |
| 2092 | QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::NarrowFormat), |
| 2093 | locale.toString(QDate(1974, 12, 1), QLocale::ShortFormat)); |
| 2094 | QCOMPARE(locale.toString(QDate(1974, 12, 1), QLocale::LongFormat), QString("1@12@1974" )); |
| 2095 | const QString expectedFormattedShortTimeSeconds = QStringLiteral("1^2^3" ); |
| 2096 | const QString expectedFormattedShortTime = QStringLiteral("1^2" ); |
| 2097 | QCOMPARE(locale.toString(QTime(1,2,3), QLocale::ShortFormat), expectedFormattedShortTime); |
| 2098 | QCOMPARE(locale.toString(QTime(1,2,3), QLocale::NarrowFormat), |
| 2099 | locale.toString(QTime(1,2,3), QLocale::ShortFormat)); |
| 2100 | const QString expectedFormattedLongTime = QStringLiteral("01%02%03" ); |
| 2101 | QCOMPARE(locale.toString(QTime(1,2,3), QLocale::LongFormat), expectedFormattedLongTime); |
| 2102 | QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat), |
| 2103 | QStringLiteral("1*12*1974 " ) + expectedFormattedShortTime); |
| 2104 | QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::NarrowFormat), |
| 2105 | locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::ShortFormat)); |
| 2106 | QCOMPARE(locale.toString(QDateTime(QDate(1974, 12, 1), QTime(1,2,3)), QLocale::LongFormat), |
| 2107 | QStringLiteral("1@12@1974 " ) + expectedFormattedLongTime); |
| 2108 | } |
| 2109 | #endif // Q_OS_WIN but !Q_OS_WINRT |
| 2110 | |
| 2111 | void tst_QLocale::numberOptions() |
| 2112 | { |
| 2113 | bool ok; |
| 2114 | |
| 2115 | QLocale locale(QLocale::C); |
| 2116 | QCOMPARE(locale.numberOptions(), QLocale::OmitGroupSeparator); |
| 2117 | QCOMPARE(locale.toInt(QString("12345" ), &ok), 12345); |
| 2118 | QVERIFY(ok); |
| 2119 | QCOMPARE(locale.toInt(QString("12345" ), &ok), 12345); |
| 2120 | QVERIFY(ok); |
| 2121 | QCOMPARE(locale.toString(12345), QString("12345" )); |
| 2122 | |
| 2123 | locale.setNumberOptions({ }); |
| 2124 | QCOMPARE(locale.numberOptions(), 0); |
| 2125 | QCOMPARE(locale.toInt(QString("12,345" ), &ok), 12345); |
| 2126 | QVERIFY(ok); |
| 2127 | QCOMPARE(locale.toInt(QString("12345" ), &ok), 12345); |
| 2128 | QVERIFY(ok); |
| 2129 | QCOMPARE(locale.toString(12345), QString("12,345" )); |
| 2130 | |
| 2131 | locale.setNumberOptions(QLocale::RejectGroupSeparator); |
| 2132 | QCOMPARE(locale.numberOptions(), QLocale::RejectGroupSeparator); |
| 2133 | locale.toInt(s: QString("12,345" ), ok: &ok); |
| 2134 | QVERIFY(!ok); |
| 2135 | QCOMPARE(locale.toInt(QString("12345" ), &ok), 12345); |
| 2136 | QVERIFY(ok); |
| 2137 | QCOMPARE(locale.toString(12345), QString("12,345" )); |
| 2138 | |
| 2139 | QLocale locale2 = locale; |
| 2140 | QCOMPARE(locale2.numberOptions(), QLocale::RejectGroupSeparator); |
| 2141 | |
| 2142 | QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+01" )); |
| 2143 | locale.setNumberOptions(QLocale::OmitLeadingZeroInExponent); |
| 2144 | QCOMPARE(locale.numberOptions(), QLocale::OmitLeadingZeroInExponent); |
| 2145 | QCOMPARE(locale.toString(12.4, 'e', 2), QString("1.24e+1" )); |
| 2146 | |
| 2147 | locale.toDouble(s: QString("1.24e+01" ), ok: &ok); |
| 2148 | QVERIFY(ok); |
| 2149 | locale.setNumberOptions(QLocale::RejectLeadingZeroInExponent); |
| 2150 | QCOMPARE(locale.numberOptions(), QLocale::RejectLeadingZeroInExponent); |
| 2151 | locale.toDouble(s: QString("1.24e+1" ), ok: &ok); |
| 2152 | QVERIFY(ok); |
| 2153 | locale.toDouble(s: QString("1.24e+01" ), ok: &ok); |
| 2154 | QVERIFY(!ok); |
| 2155 | |
| 2156 | QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.4" )); |
| 2157 | locale.setNumberOptions(QLocale::IncludeTrailingZeroesAfterDot); |
| 2158 | QCOMPARE(locale.numberOptions(), QLocale::IncludeTrailingZeroesAfterDot); |
| 2159 | QCOMPARE(locale.toString(12.4, 'g', 5), QString("12.400" )); |
| 2160 | |
| 2161 | locale.toDouble(s: QString("1.24e+01" ), ok: &ok); |
| 2162 | QVERIFY(ok); |
| 2163 | locale.toDouble(s: QString("1.2400e+01" ), ok: &ok); |
| 2164 | QVERIFY(ok); |
| 2165 | locale.toDouble(s: QString("12.4" ), ok: &ok); |
| 2166 | QVERIFY(ok); |
| 2167 | locale.toDouble(s: QString("12.400" ), ok: &ok); |
| 2168 | QVERIFY(ok); |
| 2169 | locale.setNumberOptions(QLocale::RejectTrailingZeroesAfterDot); |
| 2170 | QCOMPARE(locale.numberOptions(), QLocale::RejectTrailingZeroesAfterDot); |
| 2171 | locale.toDouble(s: QString("1.24e+01" ), ok: &ok); |
| 2172 | QVERIFY(ok); |
| 2173 | locale.toDouble(s: QString("1.2400e+01" ), ok: &ok); |
| 2174 | QVERIFY(!ok); |
| 2175 | locale.toDouble(s: QString("12.4" ), ok: &ok); |
| 2176 | QVERIFY(ok); |
| 2177 | locale.toDouble(s: QString("12.400" ), ok: &ok); |
| 2178 | QVERIFY(!ok); |
| 2179 | } |
| 2180 | |
| 2181 | void tst_QLocale::negativeNumbers() |
| 2182 | { |
| 2183 | QLocale locale(QLocale::C); |
| 2184 | |
| 2185 | bool ok; |
| 2186 | int i; |
| 2187 | |
| 2188 | i = locale.toInt(s: QLatin1String("-100" ), ok: &ok); |
| 2189 | QVERIFY(ok); |
| 2190 | QCOMPARE(i, -100); |
| 2191 | |
| 2192 | i = locale.toInt(s: QLatin1String("-1,000" ), ok: &ok); |
| 2193 | QVERIFY(ok); |
| 2194 | QCOMPARE(i, -1000); |
| 2195 | |
| 2196 | i = locale.toInt(s: QLatin1String("-1000" ), ok: &ok); |
| 2197 | QVERIFY(ok); |
| 2198 | QCOMPARE(i, -1000); |
| 2199 | |
| 2200 | i = locale.toInt(s: QLatin1String("-10,000" ), ok: &ok); |
| 2201 | QVERIFY(ok); |
| 2202 | QCOMPARE(i, -10000); |
| 2203 | |
| 2204 | i = locale.toInt(s: QLatin1String("-10000" ), ok: &ok); |
| 2205 | QVERIFY(ok); |
| 2206 | QCOMPARE(i, -10000); |
| 2207 | |
| 2208 | i = locale.toInt(s: QLatin1String("-100,000" ), ok: &ok); |
| 2209 | QVERIFY(ok); |
| 2210 | QCOMPARE(i, -100000); |
| 2211 | |
| 2212 | i = locale.toInt(s: QLatin1String("-100000" ), ok: &ok); |
| 2213 | QVERIFY(ok); |
| 2214 | QCOMPARE(i, -100000); |
| 2215 | |
| 2216 | i = locale.toInt(s: QLatin1String("-1,000,000" ), ok: &ok); |
| 2217 | QVERIFY(ok); |
| 2218 | QCOMPARE(i, -1000000); |
| 2219 | |
| 2220 | i = locale.toInt(s: QLatin1String("-1000000" ), ok: &ok); |
| 2221 | QVERIFY(ok); |
| 2222 | QCOMPARE(i, -1000000); |
| 2223 | } |
| 2224 | |
| 2225 | #include <private/qlocale_p.h> |
| 2226 | #include <private/qlocale_data_p.h> |
| 2227 | |
| 2228 | static const int locale_data_count = sizeof(locale_data)/sizeof(locale_data[0]); |
| 2229 | |
| 2230 | void tst_QLocale::testNames_data() |
| 2231 | { |
| 2232 | QTest::addColumn<int>(name: "language" ); |
| 2233 | QTest::addColumn<int>(name: "country" ); |
| 2234 | |
| 2235 | QLocale::setDefault(QLocale(QLocale::C)); // Ensures predictable fall-backs |
| 2236 | |
| 2237 | for (int i = 0; i < locale_data_count; ++i) { |
| 2238 | const QLocaleData &item = locale_data[i]; |
| 2239 | |
| 2240 | const QString testName = QLatin1String("data_" ) + QString::number(i) + QLatin1String(" (" ) |
| 2241 | + QLocale::languageToString(language: (QLocale::Language)item.m_language_id) |
| 2242 | + QLatin1Char('/') + QLocale::countryToString(country: (QLocale::Country)item.m_country_id) |
| 2243 | + QLatin1Char(')'); |
| 2244 | QTest::newRow(dataTag: testName.toLatin1().constData()) << (int)item.m_language_id << (int)item.m_country_id; |
| 2245 | } |
| 2246 | } |
| 2247 | |
| 2248 | void tst_QLocale::testNames() |
| 2249 | { |
| 2250 | QFETCH(int, language); |
| 2251 | QFETCH(int, country); |
| 2252 | |
| 2253 | QLocale l1((QLocale::Language)language, (QLocale::Country)country); |
| 2254 | if (language == QLocale::AnyLanguage && country == QLocale::AnyCountry) |
| 2255 | language = QLocale::C; |
| 2256 | QCOMPARE((int)l1.language(), language); |
| 2257 | QCOMPARE((int)l1.country(), country); |
| 2258 | |
| 2259 | QString name = l1.name(); |
| 2260 | |
| 2261 | QLocale l2(name); |
| 2262 | QCOMPARE((int)l2.language(), language); |
| 2263 | QCOMPARE((int)l2.country(), country); |
| 2264 | QCOMPARE(l2.name(), name); |
| 2265 | |
| 2266 | QLocale l3(name + QLatin1String("@foo" )); |
| 2267 | QCOMPARE((int)l3.language(), language); |
| 2268 | QCOMPARE((int)l3.country(), country); |
| 2269 | QCOMPARE(l3.name(), name); |
| 2270 | |
| 2271 | QLocale l4(name + QLatin1String(".foo" )); |
| 2272 | QCOMPARE((int)l4.language(), language); |
| 2273 | QCOMPARE((int)l4.country(), country); |
| 2274 | QCOMPARE(l4.name(), name); |
| 2275 | |
| 2276 | if (language != QLocale::C) { |
| 2277 | int idx = name.indexOf(c: QLatin1Char('_')); |
| 2278 | QVERIFY(idx != -1); |
| 2279 | QString lang = name.left(n: idx); |
| 2280 | |
| 2281 | QCOMPARE((int)QLocale(lang).language(), language); |
| 2282 | QCOMPARE((int)QLocale(lang + QLatin1String("@foo" )).language(), language); |
| 2283 | QCOMPARE((int)QLocale(lang + QLatin1String(".foo" )).language(), language); |
| 2284 | } |
| 2285 | } |
| 2286 | |
| 2287 | void tst_QLocale::dayName_data() |
| 2288 | { |
| 2289 | QTest::addColumn<QString>(name: "locale_name" ); |
| 2290 | QTest::addColumn<QString>(name: "dayName" ); |
| 2291 | QTest::addColumn<int>(name: "day" ); |
| 2292 | QTest::addColumn<QLocale::FormatType>(name: "format" ); |
| 2293 | |
| 2294 | QTest::newRow(dataTag: "no_NO" ) << QString("no_NO" ) << QString("tirsdag" ) << 2 << QLocale::LongFormat; |
| 2295 | QTest::newRow(dataTag: "nb_NO" ) << QString("nb_NO" ) << QString("tirsdag" ) << 2 << QLocale::LongFormat; |
| 2296 | QTest::newRow(dataTag: "nn_NO" ) << QString("nn_NO" ) << QString("tysdag" ) << 2 << QLocale::LongFormat; |
| 2297 | |
| 2298 | QTest::newRow(dataTag: "C long" ) << QString("C" ) << QString("Sunday" ) << 7 << QLocale::LongFormat; |
| 2299 | QTest::newRow(dataTag: "C short" ) << QString("C" ) << QString("Sun" ) << 7 << QLocale::ShortFormat; |
| 2300 | QTest::newRow(dataTag: "C narrow" ) << QString("C" ) << QString("7" ) << 7 << QLocale::NarrowFormat; |
| 2301 | |
| 2302 | QTest::newRow(dataTag: "ru_RU long" ) |
| 2303 | << QString("ru_RU" ) |
| 2304 | << QString::fromUtf8(str: "\320\262\320\276\321\201\320\272\321\200\320" |
| 2305 | "\265\321\201\320\265\320\275\321\214\320\265" ) |
| 2306 | << 7 << QLocale::LongFormat; |
| 2307 | QTest::newRow(dataTag: "ru_RU short" ) |
| 2308 | << QString("ru_RU" ) << QString::fromUtf8(str: "\320\262\321\201" ) << 7 << QLocale::ShortFormat; |
| 2309 | QTest::newRow(dataTag: "ru_RU narrow" ) |
| 2310 | << QString("ru_RU" ) << QString::fromUtf8(str: "\320\262\321\201" ) << 7 << QLocale::NarrowFormat; |
| 2311 | } |
| 2312 | |
| 2313 | void tst_QLocale::dayName() |
| 2314 | { |
| 2315 | QFETCH(QString, locale_name); |
| 2316 | QFETCH(QString, dayName); |
| 2317 | QFETCH(int, day); |
| 2318 | QFETCH(QLocale::FormatType, format); |
| 2319 | |
| 2320 | QLocale l(locale_name); |
| 2321 | QCOMPARE(l.dayName(day, format), dayName); |
| 2322 | |
| 2323 | QLocale ir("ga_IE" ); |
| 2324 | QCOMPARE(ir.dayName(1, QLocale::ShortFormat), QLatin1String("Luan" )); |
| 2325 | QCOMPARE(ir.dayName(7, QLocale::ShortFormat), QLatin1String("Domh" )); |
| 2326 | |
| 2327 | QLocale gr("el_GR" ); |
| 2328 | QCOMPARE(gr.dayName(2, QLocale::ShortFormat), QString::fromUtf8("\316\244\317\201\316\257" )); |
| 2329 | QCOMPARE(gr.dayName(4, QLocale::ShortFormat), QString::fromUtf8("\316\240\316\255\316\274" )); |
| 2330 | QCOMPARE(gr.dayName(6, QLocale::ShortFormat), QString::fromUtf8("\316\243\316\254\316\262" )); |
| 2331 | } |
| 2332 | |
| 2333 | void tst_QLocale::standaloneDayName_data() |
| 2334 | { |
| 2335 | QTest::addColumn<QString>(name: "locale_name" ); |
| 2336 | QTest::addColumn<QString>(name: "dayName" ); |
| 2337 | QTest::addColumn<int>(name: "day" ); |
| 2338 | QTest::addColumn<QLocale::FormatType>(name: "format" ); |
| 2339 | |
| 2340 | QTest::newRow(dataTag: "no_NO" ) << QString("no_NO" ) << QString("tirsdag" ) << 2 << QLocale::LongFormat; |
| 2341 | QTest::newRow(dataTag: "nb_NO" ) << QString("nb_NO" ) << QString("tirsdag" ) << 2 << QLocale::LongFormat; |
| 2342 | QTest::newRow(dataTag: "nn_NO" ) << QString("nn_NO" ) << QString("tysdag" ) << 2 << QLocale::LongFormat; |
| 2343 | |
| 2344 | QTest::newRow(dataTag: "C invalid: 0 long" ) << QString("C" ) << QString() << 0 << QLocale::LongFormat; |
| 2345 | QTest::newRow(dataTag: "C invalid: 0 short" ) << QString("C" ) << QString() << 0 << QLocale::ShortFormat; |
| 2346 | QTest::newRow(dataTag: "C invalid: 0 narrow" ) << QString("C" ) << QString() << 0 << QLocale::NarrowFormat; |
| 2347 | QTest::newRow(dataTag: "C invalid: 8 long" ) << QString("C" ) << QString() << 8 << QLocale::LongFormat; |
| 2348 | QTest::newRow(dataTag: "C invalid: 8 short" ) << QString("C" ) << QString() << 8 << QLocale::ShortFormat; |
| 2349 | QTest::newRow(dataTag: "C invalid: 8 narrow" ) << QString("C" ) << QString() << 8 << QLocale::NarrowFormat; |
| 2350 | |
| 2351 | QTest::newRow(dataTag: "C long" ) << QString("C" ) << QString("Sunday" ) << 7 << QLocale::LongFormat; |
| 2352 | QTest::newRow(dataTag: "C short" ) << QString("C" ) << QString("Sun" ) << 7 << QLocale::ShortFormat; |
| 2353 | QTest::newRow(dataTag: "C narrow" ) << QString("C" ) << QString("S" ) << 7 << QLocale::NarrowFormat; |
| 2354 | |
| 2355 | QTest::newRow(dataTag: "ru_RU long" ) |
| 2356 | << QString("ru_RU" ) |
| 2357 | << QString::fromUtf8(str: "\320\262\320\276\321\201\320\272\321\200\320" |
| 2358 | "\265\321\201\320\265\320\275\321\214\320\265" ) |
| 2359 | << 7 << QLocale::LongFormat; |
| 2360 | QTest::newRow(dataTag: "ru_RU short" ) |
| 2361 | << QString("ru_RU" ) << QString::fromUtf8(str: "\320\262\321\201" ) << 7 << QLocale::ShortFormat; |
| 2362 | QTest::newRow(dataTag: "ru_RU narrow" ) |
| 2363 | << QString("ru_RU" ) << QString::fromUtf8(str: "\320\222" ) << 7 << QLocale::NarrowFormat; |
| 2364 | } |
| 2365 | |
| 2366 | void tst_QLocale::standaloneDayName() |
| 2367 | { |
| 2368 | QFETCH(QString, locale_name); |
| 2369 | QFETCH(QString, dayName); |
| 2370 | QFETCH(int, day); |
| 2371 | QFETCH(QLocale::FormatType, format); |
| 2372 | |
| 2373 | QLocale l(locale_name); |
| 2374 | QCOMPARE(l.standaloneDayName(day, format), dayName); |
| 2375 | } |
| 2376 | |
| 2377 | void tst_QLocale::underflowOverflow() |
| 2378 | { |
| 2379 | QString a(QLatin1String("0." ) + QString(546, QLatin1Char('0')) + QLatin1String("1e10" )); |
| 2380 | bool ok = false; |
| 2381 | double d = a.toDouble(ok: &ok); |
| 2382 | QVERIFY(!ok); |
| 2383 | QCOMPARE(d, 0.0); |
| 2384 | |
| 2385 | a = QLatin1String("1e600" ); |
| 2386 | ok = false; |
| 2387 | d = a.toDouble(ok: &ok); |
| 2388 | QVERIFY(!ok); // detectable overflow |
| 2389 | QVERIFY(qIsInf(d)); |
| 2390 | |
| 2391 | a = QLatin1String("-1e600" ); |
| 2392 | ok = false; |
| 2393 | d = a.toDouble(ok: &ok); |
| 2394 | QVERIFY(!ok); // detectable underflow |
| 2395 | QVERIFY(qIsInf(-d)); |
| 2396 | |
| 2397 | a = QLatin1String("1e-600" ); |
| 2398 | ok = false; |
| 2399 | d = a.toDouble(ok: &ok); |
| 2400 | QVERIFY(!ok); |
| 2401 | QCOMPARE(d, 0.0); |
| 2402 | |
| 2403 | a = QLatin1String("-9223372036854775809" ); |
| 2404 | a.toLongLong(ok: &ok); |
| 2405 | QVERIFY(!ok); |
| 2406 | } |
| 2407 | |
| 2408 | void tst_QLocale::defaultNumberingSystem_data() |
| 2409 | { |
| 2410 | QTest::addColumn<QString>(name: "expect" ); |
| 2411 | |
| 2412 | QTest::newRow(dataTag: "sk_SK" ) << QStringLiteral("123" ); |
| 2413 | QTest::newRow(dataTag: "ta_IN" ) << QStringLiteral("123" ); |
| 2414 | QTest::newRow(dataTag: "te_IN" ) << QStringLiteral("123" ); |
| 2415 | QTest::newRow(dataTag: "hi_IN" ) << QStringLiteral("123" ); |
| 2416 | QTest::newRow(dataTag: "gu_IN" ) << QStringLiteral("123" ); |
| 2417 | QTest::newRow(dataTag: "kn_IN" ) << QStringLiteral("123" ); |
| 2418 | QTest::newRow(dataTag: "pa_IN" ) << QStringLiteral("123" ); |
| 2419 | QTest::newRow(dataTag: "ne_IN" ) << QString::fromUtf8(str: "१२३" ); |
| 2420 | QTest::newRow(dataTag: "mr_IN" ) << QString::fromUtf8(str: "१२३" ); |
| 2421 | QTest::newRow(dataTag: "ml_IN" ) << QStringLiteral("123" ); |
| 2422 | QTest::newRow(dataTag: "kok_IN" ) << QStringLiteral("123" ); |
| 2423 | } |
| 2424 | |
| 2425 | void tst_QLocale::defaultNumberingSystem() |
| 2426 | { |
| 2427 | QFETCH(QString, expect); |
| 2428 | QLatin1String name(QTest::currentDataTag()); |
| 2429 | QLocale locale(name); |
| 2430 | QCOMPARE(locale.toString(123), expect); |
| 2431 | } |
| 2432 | |
| 2433 | void tst_QLocale::ampm_data() |
| 2434 | { |
| 2435 | QTest::addColumn<QString>(name: "morn" ); |
| 2436 | QTest::addColumn<QString>(name: "even" ); |
| 2437 | |
| 2438 | QTest::newRow(dataTag: "C" ) << QStringLiteral("AM" ) << QStringLiteral("PM" ); |
| 2439 | QTest::newRow(dataTag: "de_DE" ) << QStringLiteral("AM" ) << QStringLiteral("PM" ); |
| 2440 | QTest::newRow(dataTag: "sv_SE" ) << QStringLiteral("fm" ) << QStringLiteral("em" ); |
| 2441 | QTest::newRow(dataTag: "nl_NL" ) << QStringLiteral("a.m." ) << QStringLiteral("p.m." ); |
| 2442 | QTest::newRow(dataTag: "uk_UA" ) << QString::fromUtf8(str: "\320\264\320\277" ) |
| 2443 | << QString::fromUtf8(str: "\320\277\320\277" ); |
| 2444 | QTest::newRow(dataTag: "tr_TR" ) << QString::fromUtf8(str: "\303\226\303\226" ) |
| 2445 | << QString::fromUtf8(str: "\303\226\123" ); |
| 2446 | QTest::newRow(dataTag: "id_ID" ) << QStringLiteral("AM" ) << QStringLiteral("PM" ); |
| 2447 | QTest::newRow(dataTag: "ta_LK" ) << QString::fromUtf8(str: "முற்பகல்" ) << QString::fromUtf8(str: "பிற்பகல்" ); |
| 2448 | } |
| 2449 | |
| 2450 | void tst_QLocale::ampm() |
| 2451 | { |
| 2452 | QFETCH(QString, morn); |
| 2453 | QFETCH(QString, even); |
| 2454 | QLatin1String name(QTest::currentDataTag()); |
| 2455 | QLocale locale(name == QLatin1String("C" ) ? QLocale(QLocale::C) : QLocale(name)); |
| 2456 | QCOMPARE(locale.amText(), morn); |
| 2457 | QCOMPARE(locale.pmText(), even); |
| 2458 | } |
| 2459 | |
| 2460 | void tst_QLocale::dateFormat() |
| 2461 | { |
| 2462 | const QLocale c(QLocale::C); |
| 2463 | // check that the NarrowFormat is the same as ShortFormat. |
| 2464 | QCOMPARE(c.dateFormat(QLocale::NarrowFormat), c.dateFormat(QLocale::ShortFormat)); |
| 2465 | |
| 2466 | const QLocale no("no_NO" ); |
| 2467 | QCOMPARE(no.dateFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy" )); |
| 2468 | QCOMPARE(no.dateFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy" )); |
| 2469 | QCOMPARE(no.dateFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy" )); |
| 2470 | |
| 2471 | const QLocale ca("en_CA" ); |
| 2472 | QCOMPARE(ca.dateFormat(QLocale::ShortFormat), QLatin1String("yyyy-MM-dd" )); |
| 2473 | QCOMPARE(ca.dateFormat(QLocale::LongFormat), QLatin1String("dddd, MMMM d, yyyy" )); |
| 2474 | |
| 2475 | const QLocale ja("ja_JP" ); |
| 2476 | QCOMPARE(ja.dateFormat(QLocale::ShortFormat), QLatin1String("yyyy/MM/dd" )); |
| 2477 | |
| 2478 | const QLocale ir("ga_IE" ); |
| 2479 | QCOMPARE(ir.dateFormat(QLocale::ShortFormat), QLatin1String("dd/MM/yyyy" )); |
| 2480 | |
| 2481 | const auto sys = QLocale::system(); // QTBUG-92018, ru_RU on MS |
| 2482 | const QDate date(2021, 3, 17); |
| 2483 | QCOMPARE(sys.toString(date, sys.dateFormat(QLocale::LongFormat)), sys.toString(date)); |
| 2484 | } |
| 2485 | |
| 2486 | void tst_QLocale::timeFormat() |
| 2487 | { |
| 2488 | const QLocale c(QLocale::C); |
| 2489 | // check that the NarrowFormat is the same as ShortFormat. |
| 2490 | QCOMPARE(c.timeFormat(QLocale::NarrowFormat), c.timeFormat(QLocale::ShortFormat)); |
| 2491 | |
| 2492 | const QLocale no("no_NO" ); |
| 2493 | QCOMPARE(no.timeFormat(QLocale::NarrowFormat), QLatin1String("HH:mm" )); |
| 2494 | QCOMPARE(no.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm" )); |
| 2495 | QCOMPARE(no.timeFormat(QLocale::LongFormat), QLatin1String("HH:mm:ss t" )); |
| 2496 | |
| 2497 | const QLocale id("id_ID" ); |
| 2498 | QCOMPARE(id.timeFormat(QLocale::ShortFormat), QLatin1String("HH.mm" )); |
| 2499 | QCOMPARE(id.timeFormat(QLocale::LongFormat), QLatin1String("HH.mm.ss t" )); |
| 2500 | |
| 2501 | const QLocale cat("ca_ES" ); |
| 2502 | QCOMPARE(cat.timeFormat(QLocale::ShortFormat), QLatin1String("H:mm" )); |
| 2503 | QCOMPARE(cat.timeFormat(QLocale::LongFormat), QLatin1String("H:mm:ss (t)" )); |
| 2504 | |
| 2505 | const QLocale bra("pt_BR" ); |
| 2506 | QCOMPARE(bra.timeFormat(QLocale::ShortFormat), QLatin1String("HH:mm" )); |
| 2507 | QCOMPARE(bra.timeFormat(QLocale::LongFormat), QLatin1String("HH:mm:ss t" )); |
| 2508 | } |
| 2509 | |
| 2510 | void tst_QLocale::dateTimeFormat() |
| 2511 | { |
| 2512 | const QLocale c(QLocale::C); |
| 2513 | // check that the NarrowFormat is the same as ShortFormat. |
| 2514 | QCOMPARE(c.dateTimeFormat(QLocale::NarrowFormat), c.dateTimeFormat(QLocale::ShortFormat)); |
| 2515 | |
| 2516 | const QLocale no("no_NO" ); |
| 2517 | QCOMPARE(no.dateTimeFormat(QLocale::NarrowFormat), QLatin1String("dd.MM.yyyy HH:mm" )); |
| 2518 | QCOMPARE(no.dateTimeFormat(QLocale::ShortFormat), QLatin1String("dd.MM.yyyy HH:mm" )); |
| 2519 | QCOMPARE(no.dateTimeFormat(QLocale::LongFormat), QLatin1String("dddd d. MMMM yyyy HH:mm:ss t" )); |
| 2520 | } |
| 2521 | |
| 2522 | void tst_QLocale::monthName() |
| 2523 | { |
| 2524 | const QLocale c(QLocale::C); |
| 2525 | QCOMPARE(c.monthName(0, QLocale::ShortFormat), QString()); |
| 2526 | QCOMPARE(c.monthName(0, QLocale::LongFormat), QString()); |
| 2527 | QCOMPARE(c.monthName(0, QLocale::NarrowFormat), QString()); |
| 2528 | QCOMPARE(c.monthName(13, QLocale::ShortFormat), QString()); |
| 2529 | QCOMPARE(c.monthName(13, QLocale::LongFormat), QString()); |
| 2530 | QCOMPARE(c.monthName(13, QLocale::NarrowFormat), QString()); |
| 2531 | |
| 2532 | QCOMPARE(c.monthName(1, QLocale::LongFormat), QLatin1String("January" )); |
| 2533 | QCOMPARE(c.monthName(1, QLocale::ShortFormat), QLatin1String("Jan" )); |
| 2534 | QCOMPARE(c.monthName(1, QLocale::NarrowFormat), QLatin1String("1" )); |
| 2535 | |
| 2536 | const QLocale de("de_DE" ); |
| 2537 | QCOMPARE(de.monthName(12, QLocale::LongFormat), QLatin1String("Dezember" )); |
| 2538 | QCOMPARE(de.monthName(12, QLocale::ShortFormat), QLatin1String("Dez." )); |
| 2539 | // 'de' locale doesn't have narrow month name |
| 2540 | QCOMPARE(de.monthName(12, QLocale::NarrowFormat), QLatin1String("D" )); |
| 2541 | |
| 2542 | const QLocale ru("ru_RU" ); |
| 2543 | QCOMPARE(ru.monthName(1, QLocale::LongFormat), |
| 2544 | QString::fromUtf8("\321\217\320\275\320\262\320\260\321\200\321\217" )); |
| 2545 | QCOMPARE(ru.monthName(1, QLocale::ShortFormat), |
| 2546 | QString::fromUtf8("\321\217\320\275\320\262\56" )); |
| 2547 | QCOMPARE(ru.monthName(1, QLocale::NarrowFormat), QString::fromUtf8("\320\257" )); |
| 2548 | const auto sys = QLocale::system(); |
| 2549 | if (sys.language() == QLocale::Russian) // QTBUG-92018 |
| 2550 | QVERIFY(sys.monthName(3) != sys.standaloneMonthName(3)); |
| 2551 | |
| 2552 | const QLocale ir("ga_IE" ); |
| 2553 | QCOMPARE(ir.monthName(1, QLocale::ShortFormat), QLatin1String("Ean" )); |
| 2554 | QCOMPARE(ir.monthName(12, QLocale::ShortFormat), QLatin1String("Noll" )); |
| 2555 | |
| 2556 | const QLocale cz("cs_CZ" ); |
| 2557 | QCOMPARE(cz.monthName(1, QLocale::ShortFormat), QLatin1String("led" )); |
| 2558 | QCOMPARE(cz.monthName(12, QLocale::ShortFormat), QLatin1String("pro" )); |
| 2559 | } |
| 2560 | |
| 2561 | void tst_QLocale::standaloneMonthName() |
| 2562 | { |
| 2563 | const QLocale c(QLocale::C); |
| 2564 | QCOMPARE(c.monthName(0, QLocale::ShortFormat), QString()); |
| 2565 | QCOMPARE(c.monthName(0, QLocale::LongFormat), QString()); |
| 2566 | QCOMPARE(c.monthName(0, QLocale::NarrowFormat), QString()); |
| 2567 | QCOMPARE(c.monthName(13, QLocale::ShortFormat), QString()); |
| 2568 | QCOMPARE(c.monthName(13, QLocale::LongFormat), QString()); |
| 2569 | QCOMPARE(c.monthName(13, QLocale::NarrowFormat), QString()); |
| 2570 | |
| 2571 | QCOMPARE(c.standaloneMonthName(1, QLocale::LongFormat), QLatin1String("January" )); |
| 2572 | QCOMPARE(c.standaloneMonthName(1, QLocale::ShortFormat), QLatin1String("Jan" )); |
| 2573 | |
| 2574 | const QLocale de("de_DE" ); |
| 2575 | // For de_DE locale Unicode CLDR database doesn't contain standalone long months |
| 2576 | // so just checking if the return value is the same as in monthName(). |
| 2577 | QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat), QLatin1String("Dezember" )); |
| 2578 | QCOMPARE(de.standaloneMonthName(12, QLocale::LongFormat), |
| 2579 | de.monthName(12, QLocale::LongFormat)); |
| 2580 | QCOMPARE(de.standaloneMonthName(12, QLocale::ShortFormat), QLatin1String("Dez" )); |
| 2581 | QCOMPARE(de.standaloneMonthName(12, QLocale::NarrowFormat), QLatin1String("D" )); |
| 2582 | |
| 2583 | QLocale ru("ru_RU" ); |
| 2584 | QCOMPARE(ru.standaloneMonthName(1, QLocale::LongFormat), |
| 2585 | QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2\xd0\xb0\xd1\x80\xd1\x8c" )); |
| 2586 | QCOMPARE(ru.standaloneMonthName(1, QLocale::ShortFormat), |
| 2587 | QString::fromUtf8("\xd1\x8f\xd0\xbd\xd0\xb2." )); |
| 2588 | QCOMPARE(ru.standaloneMonthName(1, QLocale::NarrowFormat), QString::fromUtf8("\xd0\xaf" )); |
| 2589 | } |
| 2590 | |
| 2591 | void tst_QLocale::currency() |
| 2592 | { |
| 2593 | const QLocale c(QLocale::C); |
| 2594 | QCOMPARE(c.toCurrencyString(qulonglong(1234)), QString("1234" )); |
| 2595 | QCOMPARE(c.toCurrencyString(qlonglong(-1234)), QString("-1234" )); |
| 2596 | QCOMPARE(c.toCurrencyString(double(1234.56)), QString("1234.56" )); |
| 2597 | QCOMPARE(c.toCurrencyString(double(-1234.56)), QString("-1234.56" )); |
| 2598 | QCOMPARE(c.toCurrencyString(double(-1234.5678)), QString("-1234.57" )); |
| 2599 | QCOMPARE(c.toCurrencyString(double(-1234.5678), NULL, 4), QString("-1234.5678" )); |
| 2600 | QCOMPARE(c.toCurrencyString(double(-1234.56), NULL, 4), QString("-1234.5600" )); |
| 2601 | |
| 2602 | const QLocale en_US("en_US" ); |
| 2603 | QCOMPARE(en_US.toCurrencyString(qulonglong(1234)), QString("$1,234" )); |
| 2604 | QCOMPARE(en_US.toCurrencyString(qlonglong(-1234)), QString("($1,234)" )); |
| 2605 | QCOMPARE(en_US.toCurrencyString(double(1234.56)), QString("$1,234.56" )); |
| 2606 | QCOMPARE(en_US.toCurrencyString(double(-1234.56)), QString("($1,234.56)" )); |
| 2607 | QCOMPARE(en_US.toCurrencyString(double(-1234.5678)), QString("($1,234.57)" )); |
| 2608 | QCOMPARE(en_US.toCurrencyString(double(-1234.5678), NULL, 4), QString("($1,234.5678)" )); |
| 2609 | QCOMPARE(en_US.toCurrencyString(double(-1234.56), NULL, 4), QString("($1,234.5600)" )); |
| 2610 | |
| 2611 | const QLocale ru_RU("ru_RU" ); |
| 2612 | QCOMPARE(ru_RU.toCurrencyString(qulonglong(1234)), |
| 2613 | QString::fromUtf8("1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd" )); |
| 2614 | QCOMPARE(ru_RU.toCurrencyString(qlonglong(-1234)), |
| 2615 | QString::fromUtf8("-1" "\xc2\xa0" "234\xc2\xa0\xe2\x82\xbd" )); |
| 2616 | QCOMPARE(ru_RU.toCurrencyString(double(1234.56)), |
| 2617 | QString::fromUtf8("1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd" )); |
| 2618 | QCOMPARE(ru_RU.toCurrencyString(double(-1234.56)), |
| 2619 | QString::fromUtf8("-1" "\xc2\xa0" "234,56\xc2\xa0\xe2\x82\xbd" )); |
| 2620 | |
| 2621 | const QLocale de_DE("de_DE" ); |
| 2622 | QCOMPARE(de_DE.toCurrencyString(qulonglong(1234)), |
| 2623 | QString::fromUtf8("1.234\xc2\xa0\xe2\x82\xac" )); |
| 2624 | QCOMPARE(de_DE.toCurrencyString(qulonglong(1234), QLatin1String("BAZ" )), |
| 2625 | QString::fromUtf8("1.234\xc2\xa0" "BAZ" )); |
| 2626 | QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234)), |
| 2627 | QString::fromUtf8("-1.234\xc2\xa0\xe2\x82\xac" )); |
| 2628 | QCOMPARE(de_DE.toCurrencyString(qlonglong(-1234), QLatin1String("BAZ" )), |
| 2629 | QString::fromUtf8("-1.234\xc2\xa0" "BAZ" )); |
| 2630 | QCOMPARE(de_DE.toCurrencyString(double(1234.56)), |
| 2631 | QString::fromUtf8("1.234,56\xc2\xa0\xe2\x82\xac" )); |
| 2632 | QCOMPARE(de_DE.toCurrencyString(double(-1234.56)), |
| 2633 | QString::fromUtf8("-1.234,56\xc2\xa0\xe2\x82\xac" )); |
| 2634 | QCOMPARE(de_DE.toCurrencyString(double(-1234.56), QLatin1String("BAZ" )), |
| 2635 | QString::fromUtf8("-1.234,56\xc2\xa0" "BAZ" )); |
| 2636 | |
| 2637 | const QLocale es_CR(QLocale::Spanish, QLocale::CostaRica); |
| 2638 | QCOMPARE(es_CR.toCurrencyString(double(1565.25)), |
| 2639 | QString::fromUtf8("\xE2\x82\xA1" "1\xC2\xA0" "565,25" )); |
| 2640 | QCOMPARE(es_CR.toCurrencyString(double(12565.25)), |
| 2641 | QString::fromUtf8("\xE2\x82\xA1" "12\xC2\xA0" "565,25" )); |
| 2642 | |
| 2643 | const QLocale system = QLocale::system(); |
| 2644 | QVERIFY(system.toCurrencyString(1, QLatin1String("FOO" )).contains(QLatin1String("FOO" ))); |
| 2645 | } |
| 2646 | |
| 2647 | void tst_QLocale::quoteString() |
| 2648 | { |
| 2649 | const QString someText("text" ); |
| 2650 | const QLocale c(QLocale::C); |
| 2651 | QCOMPARE(c.quoteString(someText), QString::fromUtf8("\x22" "text" "\x22" )); |
| 2652 | QCOMPARE(c.quoteString(someText, QLocale::AlternateQuotation), |
| 2653 | QString::fromUtf8("\x27" "text" "\x27" )); |
| 2654 | |
| 2655 | const QLocale de_CH("de_CH" ); |
| 2656 | QCOMPARE(de_CH.quoteString(someText), QString::fromUtf8("\xe2\x80\x9e" "text" "\xe2\x80\x9c" )); |
| 2657 | QCOMPARE(de_CH.quoteString(someText, QLocale::AlternateQuotation), |
| 2658 | QString::fromUtf8("\xe2\x80\x9a" "text" "\xe2\x80\x98" )); |
| 2659 | |
| 2660 | } |
| 2661 | |
| 2662 | void tst_QLocale::uiLanguages() |
| 2663 | { |
| 2664 | const QLocale c(QLocale::C); |
| 2665 | QCOMPARE(c.uiLanguages().size(), 1); |
| 2666 | QCOMPARE(c.uiLanguages().at(0), QLatin1String("C" )); |
| 2667 | |
| 2668 | const QLocale en_US("en_US" ); |
| 2669 | QCOMPARE(en_US.uiLanguages().size(), 3); |
| 2670 | QCOMPARE(en_US.uiLanguages().at(0), QLatin1String("en" )); |
| 2671 | QCOMPARE(en_US.uiLanguages().at(1), QLatin1String("en-US" )); |
| 2672 | QCOMPARE(en_US.uiLanguages().at(2), QLatin1String("en-Latn-US" )); |
| 2673 | |
| 2674 | const QLocale en_Latn_US("en_Latn_US" ); |
| 2675 | QCOMPARE(en_Latn_US.uiLanguages().size(), 3); |
| 2676 | QCOMPARE(en_Latn_US.uiLanguages().at(0), QLatin1String("en" )); |
| 2677 | QCOMPARE(en_Latn_US.uiLanguages().at(1), QLatin1String("en-US" )); |
| 2678 | QCOMPARE(en_Latn_US.uiLanguages().at(2), QLatin1String("en-Latn-US" )); |
| 2679 | |
| 2680 | const QLocale en_GB("en_GB" ); |
| 2681 | QCOMPARE(en_GB.uiLanguages().size(), 2); |
| 2682 | QCOMPARE(en_GB.uiLanguages().at(0), QLatin1String("en-GB" )); |
| 2683 | QCOMPARE(en_GB.uiLanguages().at(1), QLatin1String("en-Latn-GB" )); |
| 2684 | |
| 2685 | const QLocale en_Dsrt_US("en_Dsrt_US" ); |
| 2686 | QCOMPARE(en_Dsrt_US.uiLanguages().size(), 2); |
| 2687 | QCOMPARE(en_Dsrt_US.uiLanguages().at(0), QLatin1String("en-Dsrt" )); |
| 2688 | QCOMPARE(en_Dsrt_US.uiLanguages().at(1), QLatin1String("en-Dsrt-US" )); |
| 2689 | |
| 2690 | const QLocale ru_RU("ru_RU" ); |
| 2691 | QCOMPARE(ru_RU.uiLanguages().size(), 3); |
| 2692 | QCOMPARE(ru_RU.uiLanguages().at(0), QLatin1String("ru" )); |
| 2693 | QCOMPARE(ru_RU.uiLanguages().at(1), QLatin1String("ru-RU" )); |
| 2694 | QCOMPARE(ru_RU.uiLanguages().at(2), QLatin1String("ru-Cyrl-RU" )); |
| 2695 | |
| 2696 | const QLocale zh_Hant("zh_Hant" ); |
| 2697 | QCOMPARE(zh_Hant.uiLanguages().size(), 2); |
| 2698 | QCOMPARE(zh_Hant.uiLanguages().at(0), QLatin1String("zh-TW" )); |
| 2699 | QCOMPARE(zh_Hant.uiLanguages().at(1), QLatin1String("zh-Hant-TW" )); |
| 2700 | } |
| 2701 | |
| 2702 | void tst_QLocale::weekendDays() |
| 2703 | { |
| 2704 | const QLocale c(QLocale::C); |
| 2705 | QList<Qt::DayOfWeek> days; |
| 2706 | days << Qt::Monday << Qt::Tuesday << Qt::Wednesday << Qt::Thursday << Qt::Friday; |
| 2707 | QCOMPARE(c.weekdays(), days); |
| 2708 | } |
| 2709 | |
| 2710 | void tst_QLocale::listPatterns() |
| 2711 | { |
| 2712 | QStringList sl1; |
| 2713 | QStringList sl2; |
| 2714 | sl2 << "aaa" ; |
| 2715 | QStringList sl3; |
| 2716 | sl3 << "aaa" << "bbb" ; |
| 2717 | QStringList sl4; |
| 2718 | sl4 << "aaa" << "bbb" << "ccc" ; |
| 2719 | QStringList sl5; |
| 2720 | sl5 << "aaa" << "bbb" << "ccc" << "ddd" ; |
| 2721 | |
| 2722 | const QLocale c(QLocale::C); |
| 2723 | QCOMPARE(c.createSeparatedList(sl1), QString("" )); |
| 2724 | QCOMPARE(c.createSeparatedList(sl2), QString("aaa" )); |
| 2725 | QCOMPARE(c.createSeparatedList(sl3), QString("aaa, bbb" )); |
| 2726 | QCOMPARE(c.createSeparatedList(sl4), QString("aaa, bbb, ccc" )); |
| 2727 | QCOMPARE(c.createSeparatedList(sl5), QString("aaa, bbb, ccc, ddd" )); |
| 2728 | |
| 2729 | const QLocale en_US("en_US" ); |
| 2730 | QCOMPARE(en_US.createSeparatedList(sl1), QString("" )); |
| 2731 | QCOMPARE(en_US.createSeparatedList(sl2), QString("aaa" )); |
| 2732 | QCOMPARE(en_US.createSeparatedList(sl3), QString("aaa and bbb" )); |
| 2733 | QCOMPARE(en_US.createSeparatedList(sl4), QString("aaa, bbb, and ccc" )); |
| 2734 | QCOMPARE(en_US.createSeparatedList(sl5), QString("aaa, bbb, ccc, and ddd" )); |
| 2735 | |
| 2736 | const QLocale zh_CN("zh_CN" ); |
| 2737 | QCOMPARE(zh_CN.createSeparatedList(sl1), QString("" )); |
| 2738 | QCOMPARE(zh_CN.createSeparatedList(sl2), QString("aaa" )); |
| 2739 | QCOMPARE(zh_CN.createSeparatedList(sl3), QString::fromUtf8("aaa" "\xe5\x92\x8c" "bbb" )); |
| 2740 | QCOMPARE(zh_CN.createSeparatedList(sl4), |
| 2741 | QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe5\x92\x8c" "ccc" )); |
| 2742 | QCOMPARE(zh_CN.createSeparatedList(sl5), |
| 2743 | QString::fromUtf8("aaa" "\xe3\x80\x81" "bbb" "\xe3\x80\x81" |
| 2744 | "ccc" "\xe5\x92\x8c" "ddd" )); |
| 2745 | } |
| 2746 | |
| 2747 | void tst_QLocale::measurementSystems_data() |
| 2748 | { |
| 2749 | QTest::addColumn<QLocale>(name: "locale" ); |
| 2750 | QTest::addColumn<QLocale::MeasurementSystem>(name: "system" ); |
| 2751 | QTest::newRow(dataTag: "en_US" ) << QLocale(QLocale::English, QLocale::UnitedStates) << QLocale::ImperialUSSystem; |
| 2752 | QTest::newRow(dataTag: "en_GB" ) << QLocale(QLocale::English, QLocale::UnitedKingdom) << QLocale::ImperialUKSystem; |
| 2753 | QTest::newRow(dataTag: "en_AU" ) << QLocale(QLocale::English, QLocale::Australia) << QLocale::MetricSystem; |
| 2754 | QTest::newRow(dataTag: "de" ) << QLocale(QLocale::German) << QLocale::MetricSystem; |
| 2755 | } |
| 2756 | |
| 2757 | void tst_QLocale::measurementSystems() |
| 2758 | { |
| 2759 | QFETCH(QLocale, locale); |
| 2760 | QFETCH(QLocale::MeasurementSystem, system); |
| 2761 | QCOMPARE(locale.measurementSystem(), system); |
| 2762 | } |
| 2763 | |
| 2764 | void tst_QLocale::QTBUG_26035_positivesign() |
| 2765 | { |
| 2766 | QLocale locale(QLocale::C); |
| 2767 | bool ok (false); |
| 2768 | QCOMPARE(locale.toInt(QString("+100,000" ), &ok), 100000); |
| 2769 | QVERIFY(ok); |
| 2770 | ok = false; |
| 2771 | QCOMPARE(locale.toInt(QString("+100,000,000" ), &ok), 100000000); |
| 2772 | QVERIFY(ok); |
| 2773 | ok = false; |
| 2774 | QCOMPARE(locale.toLongLong(QString("+100,000" ), &ok), (qlonglong)100000); |
| 2775 | QVERIFY(ok); |
| 2776 | ok = false; |
| 2777 | QCOMPARE(locale.toLongLong(QString("+100,000,000" ), &ok), (qlonglong)100000000); |
| 2778 | QVERIFY(ok); |
| 2779 | } |
| 2780 | |
| 2781 | void tst_QLocale::textDirection_data() |
| 2782 | { |
| 2783 | QTest::addColumn<int>(name: "language" ); |
| 2784 | QTest::addColumn<int>(name: "script" ); |
| 2785 | QTest::addColumn<bool>(name: "rightToLeft" ); |
| 2786 | |
| 2787 | for (int language = QLocale::C; language <= QLocale::LastLanguage; ++language) { |
| 2788 | bool rightToLeft = false; |
| 2789 | switch (language) { |
| 2790 | // based on likelySubtags for RTL scripts |
| 2791 | #if QT_DEPRECATED_SINCE(5, 15) |
| 2792 | case QLocale::AncientNorthArabian: |
| 2793 | case QLocale::ClassicalMandaic: |
| 2794 | case QLocale::Lydian: |
| 2795 | case QLocale::ManichaeanMiddlePersian: |
| 2796 | case QLocale::Meroitic: |
| 2797 | case QLocale::OldTurkish: |
| 2798 | case QLocale::Parthian: |
| 2799 | case QLocale::PrakritLanguage: |
| 2800 | case QLocale::Sabaean: |
| 2801 | case QLocale::Samaritan: |
| 2802 | #endif |
| 2803 | case QLocale::AncientGreek: |
| 2804 | case QLocale::Arabic: |
| 2805 | case QLocale::Aramaic: |
| 2806 | case QLocale::Avestan: |
| 2807 | case QLocale::CentralKurdish: |
| 2808 | case QLocale::Divehi: |
| 2809 | // case QLocale::Fulah: |
| 2810 | // case QLocale::Hausa: |
| 2811 | case QLocale::Hebrew: |
| 2812 | // case QLocale::Hungarian: |
| 2813 | case QLocale::Kashmiri: |
| 2814 | // case QLocale::Kurdish: |
| 2815 | case QLocale::Mandingo: |
| 2816 | case QLocale::Mazanderani: |
| 2817 | case QLocale::Mende: |
| 2818 | case QLocale::Nko: |
| 2819 | case QLocale::NorthernLuri: |
| 2820 | case QLocale::Pahlavi: |
| 2821 | case QLocale::Pashto: |
| 2822 | case QLocale::Persian: |
| 2823 | case QLocale::Phoenician: |
| 2824 | case QLocale::Sindhi: |
| 2825 | case QLocale::SouthernKurdish: |
| 2826 | case QLocale::Syriac: |
| 2827 | case QLocale::Uighur: |
| 2828 | case QLocale::Urdu: |
| 2829 | case QLocale::WesternBalochi: |
| 2830 | case QLocale::Yiddish: |
| 2831 | // false if there is no locale data for language: |
| 2832 | rightToLeft = (QLocale(QLocale::Language(language)).language() |
| 2833 | == QLocale::Language(language)); |
| 2834 | break; |
| 2835 | default: |
| 2836 | break; |
| 2837 | } |
| 2838 | const QLatin1String testName = QLocalePrivate::languageToCode(language: QLocale::Language(language)); |
| 2839 | QTest::newRow(qPrintable(testName)) << language << int(QLocale::AnyScript) << rightToLeft; |
| 2840 | } |
| 2841 | QTest::newRow(dataTag: "pa_Arab" ) << int(QLocale::Punjabi) << int(QLocale::ArabicScript) << true; |
| 2842 | QTest::newRow(dataTag: "uz_Arab" ) << int(QLocale::Uzbek) << int(QLocale::ArabicScript) << true; |
| 2843 | } |
| 2844 | |
| 2845 | void tst_QLocale::textDirection() |
| 2846 | { |
| 2847 | QFETCH(int, language); |
| 2848 | QFETCH(int, script); |
| 2849 | QFETCH(bool, rightToLeft); |
| 2850 | |
| 2851 | QLocale locale(QLocale::Language(language), QLocale::Script(script), QLocale::AnyCountry); |
| 2852 | QCOMPARE(locale.textDirection() == Qt::RightToLeft, rightToLeft); |
| 2853 | } |
| 2854 | |
| 2855 | void tst_QLocale::formattedDataSize_data() |
| 2856 | { |
| 2857 | QTest::addColumn<QLocale::Language>(name: "language" ); |
| 2858 | QTest::addColumn<int>(name: "decimalPlaces" ); |
| 2859 | QTest::addColumn<QLocale::DataSizeFormats>(name: "units" ); |
| 2860 | QTest::addColumn<int>(name: "bytes" ); |
| 2861 | QTest::addColumn<QString>(name: "output" ); |
| 2862 | |
| 2863 | struct { |
| 2864 | const char *name; |
| 2865 | QLocale::Language lang; |
| 2866 | const char *bytes; |
| 2867 | const char abbrev; |
| 2868 | const char sep; // decimal separator |
| 2869 | } data[] = { |
| 2870 | { .name: "English" , .lang: QLocale::English, .bytes: "bytes" , .abbrev: 'B', .sep: '.' }, |
| 2871 | { .name: "French" , .lang: QLocale::French, .bytes: "octets" , .abbrev: 'o', .sep: ',' }, |
| 2872 | { .name: "C" , .lang: QLocale::C, .bytes: "bytes" , .abbrev: 'B', .sep: '.' } |
| 2873 | }; |
| 2874 | |
| 2875 | for (const auto row : data) { |
| 2876 | #define ROWB(id, deci, num, text) \ |
| 2877 | QTest::addRow("%s-%s", row.name, id) \ |
| 2878 | << row.lang << deci << format \ |
| 2879 | << num << (QString(text) + QChar(' ') + QString(row.bytes)) |
| 2880 | #define ROWQ(id, deci, num, head, tail) \ |
| 2881 | QTest::addRow("%s-%s", row.name, id) \ |
| 2882 | << row.lang << deci << format \ |
| 2883 | << num << (QString(head) + QChar(row.sep) + QString(tail) + QChar(row.abbrev)) |
| 2884 | |
| 2885 | // Metatype system fails to handle raw enum members as format; needs variable |
| 2886 | { |
| 2887 | const QLocale::DataSizeFormats format = QLocale::DataSizeIecFormat; |
| 2888 | ROWB("IEC-0" , 2, 0, "0" ); |
| 2889 | ROWB("IEC-10" , 2, 10, "10" ); |
| 2890 | ROWQ("IEC-12Ki" , 2, 12345, "12" , "06 Ki" ); |
| 2891 | ROWQ("IEC-16Ki" , 2, 16384, "16" , "00 Ki" ); |
| 2892 | ROWQ("IEC-1235k" , 2, 1234567, "1" , "18 Mi" ); |
| 2893 | ROWQ("IEC-1374k" , 2, 1374744, "1" , "31 Mi" ); |
| 2894 | ROWQ("IEC-1234M" , 2, 1234567890, "1" , "15 Gi" ); |
| 2895 | } |
| 2896 | { |
| 2897 | const QLocale::DataSizeFormats format = QLocale::DataSizeTraditionalFormat; |
| 2898 | ROWB("Trad-0" , 2, 0, "0" ); |
| 2899 | ROWB("Trad-10" , 2, 10, "10" ); |
| 2900 | ROWQ("Trad-12Ki" , 2, 12345, "12" , "06 k" ); |
| 2901 | ROWQ("Trad-16Ki" , 2, 16384, "16" , "00 k" ); |
| 2902 | ROWQ("Trad-1235k" , 2, 1234567, "1" , "18 M" ); |
| 2903 | ROWQ("Trad-1374k" , 2, 1374744, "1" , "31 M" ); |
| 2904 | ROWQ("Trad-1234M" , 2, 1234567890, "1" , "15 G" ); |
| 2905 | } |
| 2906 | { |
| 2907 | const QLocale::DataSizeFormats format = QLocale::DataSizeSIFormat; |
| 2908 | ROWB("Decimal-0" , 2, 0, "0" ); |
| 2909 | ROWB("Decimal-10" , 2, 10, "10" ); |
| 2910 | ROWQ("Decimal-16Ki" , 2, 16384, "16" , "38 k" ); |
| 2911 | ROWQ("Decimal-1234k" , 2, 1234567, "1" , "23 M" ); |
| 2912 | ROWQ("Decimal-1374k" , 2, 1374744, "1" , "37 M" ); |
| 2913 | ROWQ("Decimal-1234M" , 2, 1234567890, "1" , "23 G" ); |
| 2914 | } |
| 2915 | #undef ROWQ |
| 2916 | #undef ROWB |
| 2917 | } |
| 2918 | |
| 2919 | // Languages which don't use a Latin alphabet |
| 2920 | |
| 2921 | const QLocale::DataSizeFormats iecFormat = QLocale::DataSizeIecFormat; |
| 2922 | const QLocale::DataSizeFormats traditionalFormat = QLocale::DataSizeTraditionalFormat; |
| 2923 | const QLocale::DataSizeFormats siFormat = QLocale::DataSizeSIFormat; |
| 2924 | const QLocale::Language lang = QLocale::Russian; |
| 2925 | |
| 2926 | QTest::newRow(dataTag: "Russian-IEC-0" ) << lang << 2 << iecFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B" ); |
| 2927 | QTest::newRow(dataTag: "Russian-IEC-10" ) << lang << 2 << iecFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B" ); |
| 2928 | // CLDR doesn't provide IEC prefixes (yet?) so they aren't getting translated |
| 2929 | QTest::newRow(dataTag: "Russian-IEC-12Ki" ) << lang << 2 << iecFormat << 12345 << QString("12,06 KiB" ); |
| 2930 | QTest::newRow(dataTag: "Russian-IEC-16Ki" ) << lang << 2 << iecFormat << 16384 << QString("16,00 KiB" ); |
| 2931 | QTest::newRow(dataTag: "Russian-IEC-1235k" ) << lang << 2 << iecFormat << 1234567 << QString("1,18 MiB" ); |
| 2932 | QTest::newRow(dataTag: "Russian-IEC-1374k" ) << lang << 2 << iecFormat << 1374744 << QString("1,31 MiB" ); |
| 2933 | QTest::newRow(dataTag: "Russian-IEC-1234M" ) << lang << 2 << iecFormat << 1234567890 << QString("1,15 GiB" ); |
| 2934 | |
| 2935 | QTest::newRow(dataTag: "Russian-Trad-0" ) << lang << 2 << traditionalFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B" ); |
| 2936 | QTest::newRow(dataTag: "Russian-Trad-10" ) << lang << 2 << traditionalFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B" ); |
| 2937 | QTest::newRow(dataTag: "Russian-Trad-12Ki" ) << lang << 2 << traditionalFormat << 12345 << QString("12,06 \u043A\u0411" ); |
| 2938 | QTest::newRow(dataTag: "Russian-Trad-16Ki" ) << lang << 2 << traditionalFormat << 16384 << QString("16,00 \u043A\u0411" ); |
| 2939 | QTest::newRow(dataTag: "Russian-Trad-1235k" ) << lang << 2 << traditionalFormat << 1234567 << QString("1,18 \u041C\u0411" ); |
| 2940 | QTest::newRow(dataTag: "Russian-Trad-1374k" ) << lang << 2 << traditionalFormat << 1374744 << QString("1,31 \u041C\u0411" ); |
| 2941 | QTest::newRow(dataTag: "Russian-Trad-1234M" ) << lang << 2 << traditionalFormat << 1234567890 << QString("1,15 \u0413\u0411" ); |
| 2942 | |
| 2943 | QTest::newRow(dataTag: "Russian-Decimal-0" ) << lang << 2 << siFormat << 0 << QString("0 \u0431\u0430\u0439\u0442\u044B" ); |
| 2944 | QTest::newRow(dataTag: "Russian-Decimal-10" ) << lang << 2 << siFormat << 10 << QString("10 \u0431\u0430\u0439\u0442\u044B" ); |
| 2945 | QTest::newRow(dataTag: "Russian-Decimal-16Ki" ) << lang << 2 << siFormat << 16384 << QString("16,38 \u043A\u0411" ); |
| 2946 | QTest::newRow(dataTag: "Russian-Decimal-1234k" ) << lang << 2 << siFormat << 1234567 << QString("1,23 \u041C\u0411" ); |
| 2947 | QTest::newRow(dataTag: "Russian-Decimal-1374k" ) << lang << 2 << siFormat << 1374744 << QString("1,37 \u041C\u0411" ); |
| 2948 | QTest::newRow(dataTag: "Russian-Decimal-1234M" ) << lang << 2 << siFormat << 1234567890 << QString("1,23 \u0413\u0411" ); |
| 2949 | } |
| 2950 | |
| 2951 | void tst_QLocale::formattedDataSize() |
| 2952 | { |
| 2953 | QFETCH(QLocale::Language, language); |
| 2954 | QFETCH(int, decimalPlaces); |
| 2955 | QFETCH(QLocale::DataSizeFormats, units); |
| 2956 | QFETCH(int, bytes); |
| 2957 | QFETCH(QString, output); |
| 2958 | QCOMPARE(QLocale(language).formattedDataSize(bytes, decimalPlaces, units), output); |
| 2959 | } |
| 2960 | |
| 2961 | void tst_QLocale::bcp47Name_data() |
| 2962 | { |
| 2963 | QTest::addColumn<QString>(name: "expect" ); |
| 2964 | |
| 2965 | QTest::newRow(dataTag: "C" ) << QStringLiteral("en" ); |
| 2966 | QTest::newRow(dataTag: "en" ) << QStringLiteral("en" ); |
| 2967 | QTest::newRow(dataTag: "en_US" ) << QStringLiteral("en" ); |
| 2968 | QTest::newRow(dataTag: "en_GB" ) << QStringLiteral("en-GB" ); |
| 2969 | QTest::newRow(dataTag: "en_DE" ) << QStringLiteral("en-DE" ); |
| 2970 | QTest::newRow(dataTag: "de_DE" ) << QStringLiteral("de" ); |
| 2971 | QTest::newRow(dataTag: "sr_RS" ) << QStringLiteral("sr" ); |
| 2972 | QTest::newRow(dataTag: "sr_Cyrl_RS" ) << QStringLiteral("sr" ); |
| 2973 | QTest::newRow(dataTag: "sr_Latn_RS" ) << QStringLiteral("sr-Latn" ); |
| 2974 | QTest::newRow(dataTag: "sr_ME" ) << QStringLiteral("sr-ME" ); |
| 2975 | QTest::newRow(dataTag: "sr_Cyrl_ME" ) << QStringLiteral("sr-Cyrl-ME" ); |
| 2976 | QTest::newRow(dataTag: "sr_Latn_ME" ) << QStringLiteral("sr-ME" ); |
| 2977 | |
| 2978 | // Fall back to defaults when country isn't in CLDR for this language: |
| 2979 | QTest::newRow(dataTag: "sr_HR" ) << QStringLiteral("sr" ); |
| 2980 | QTest::newRow(dataTag: "sr_Cyrl_HR" ) << QStringLiteral("sr" ); |
| 2981 | QTest::newRow(dataTag: "sr_Latn_HR" ) << QStringLiteral("sr-Latn" ); |
| 2982 | } |
| 2983 | |
| 2984 | void tst_QLocale::bcp47Name() |
| 2985 | { |
| 2986 | QFETCH(QString, expect); |
| 2987 | QCOMPARE(QLocale(QLatin1String(QTest::currentDataTag())).bcp47Name(), expect); |
| 2988 | } |
| 2989 | |
| 2990 | class MySystemLocale : public QSystemLocale |
| 2991 | { |
| 2992 | public: |
| 2993 | MySystemLocale(const QString &locale) : m_name(locale), m_locale(locale) |
| 2994 | { |
| 2995 | } |
| 2996 | |
| 2997 | QVariant query(QueryType type, QVariant /*in*/) const override |
| 2998 | { |
| 2999 | return type == UILanguages ? QVariant(QStringList{m_name}) : QVariant(); |
| 3000 | } |
| 3001 | |
| 3002 | QLocale fallbackUiLocale() const override |
| 3003 | { |
| 3004 | return m_locale; |
| 3005 | } |
| 3006 | |
| 3007 | private: |
| 3008 | const QString m_name; |
| 3009 | const QLocale m_locale; |
| 3010 | }; |
| 3011 | |
| 3012 | void tst_QLocale::systemLocale_data() |
| 3013 | { |
| 3014 | // Test uses MySystemLocale, so is platform-independent. |
| 3015 | QTest::addColumn<QString>(name: "name" ); |
| 3016 | QTest::addColumn<QLocale::Language>(name: "language" ); |
| 3017 | QTest::addColumn<QStringList>(name: "uiLanguages" ); |
| 3018 | |
| 3019 | QTest::addRow(format: "catalan" ) |
| 3020 | << QString("ca" ) << QLocale::Catalan |
| 3021 | << QStringList{QStringLiteral("ca" ), QStringLiteral("ca-ES" ), QStringLiteral("ca-Latn-ES" )}; |
| 3022 | QTest::addRow(format: "ukrainian" ) |
| 3023 | << QString("uk" ) << QLocale::Ukrainian |
| 3024 | << QStringList{QStringLiteral("uk" ), QStringLiteral("uk-UA" ), QStringLiteral("uk-Cyrl-UA" )}; |
| 3025 | QTest::addRow(format: "german" ) |
| 3026 | << QString("de" ) << QLocale::German |
| 3027 | << QStringList{QStringLiteral("de" ), QStringLiteral("de-DE" ), QStringLiteral("de-Latn-DE" )}; |
| 3028 | QTest::addRow(format: "chinese-min" ) |
| 3029 | << QString("zh" ) << QLocale::Chinese |
| 3030 | << QStringList{QStringLiteral("zh" ), QStringLiteral("zh-CN" ), QStringLiteral("zh-Hans-CN" )}; |
| 3031 | QTest::addRow(format: "chinese-full" ) |
| 3032 | << QString("zh-Hans-CN" ) << QLocale::Chinese |
| 3033 | << QStringList{QStringLiteral("zh-Hans-CN" ), QStringLiteral("zh" ), QStringLiteral("zh-CN" )}; |
| 3034 | } |
| 3035 | |
| 3036 | void tst_QLocale::systemLocale() |
| 3037 | { |
| 3038 | QLocale originalLocale; |
| 3039 | QLocale originalSystemLocale = QLocale::system(); |
| 3040 | |
| 3041 | QFETCH(QString, name); |
| 3042 | QFETCH(QLocale::Language, language); |
| 3043 | QFETCH(QStringList, uiLanguages); |
| 3044 | |
| 3045 | { |
| 3046 | MySystemLocale sLocale(name); |
| 3047 | QCOMPARE(QLocale().language(), language); |
| 3048 | QCOMPARE(QLocale::system().language(), language); |
| 3049 | QCOMPARE(QLocale::system().uiLanguages(), uiLanguages); |
| 3050 | } |
| 3051 | |
| 3052 | QCOMPARE(QLocale(), originalLocale); |
| 3053 | QCOMPARE(QLocale::system(), originalSystemLocale); |
| 3054 | } |
| 3055 | |
| 3056 | void tst_QLocale::IndianNumberGrouping() |
| 3057 | { |
| 3058 | QLocale indian(QLocale::Hindi, QLocale::India); |
| 3059 | |
| 3060 | qint8 int8 = 100; |
| 3061 | QString strResult8("100" ); |
| 3062 | QCOMPARE(indian.toString(int8), strResult8); |
| 3063 | QCOMPARE(indian.toShort(strResult8), short(int8)); |
| 3064 | |
| 3065 | quint8 uint8 = 100; |
| 3066 | QCOMPARE(indian.toString(uint8), strResult8); |
| 3067 | QCOMPARE(indian.toShort(strResult8), short(uint8)); |
| 3068 | |
| 3069 | // Boundary case 1000 for short and ushort |
| 3070 | short shortInt = 1000; |
| 3071 | QString strResult16("1,000" ); |
| 3072 | QCOMPARE(indian.toString(shortInt), strResult16); |
| 3073 | QCOMPARE(indian.toShort(strResult16), shortInt); |
| 3074 | |
| 3075 | ushort uShortInt = 1000; |
| 3076 | QCOMPARE(indian.toString(uShortInt), strResult16); |
| 3077 | QCOMPARE(indian.toUShort(strResult16), uShortInt); |
| 3078 | |
| 3079 | shortInt = 10000; |
| 3080 | strResult16 = "10,000" ; |
| 3081 | QCOMPARE(indian.toString(shortInt), strResult16); |
| 3082 | QCOMPARE(indian.toShort(strResult16), shortInt); |
| 3083 | |
| 3084 | uShortInt = 10000; |
| 3085 | QCOMPARE(indian.toString(uShortInt), strResult16); |
| 3086 | QCOMPARE(indian.toUShort(strResult16), uShortInt); |
| 3087 | |
| 3088 | int intInt = 1000000000; |
| 3089 | QString strResult32("1,00,00,00,000" ); |
| 3090 | QCOMPARE(indian.toString(intInt), strResult32); |
| 3091 | QCOMPARE(indian.toInt(strResult32), intInt); |
| 3092 | |
| 3093 | uint uIntInt = 1000000000; |
| 3094 | QCOMPARE(indian.toString(uIntInt), strResult32); |
| 3095 | QCOMPARE(indian.toUInt(strResult32), uIntInt); |
| 3096 | |
| 3097 | QString strResult64("10,00,00,00,00,00,00,00,000" ); |
| 3098 | qint64 int64 = Q_INT64_C(1000000000000000000); |
| 3099 | QCOMPARE(indian.toString(int64), strResult64); |
| 3100 | QCOMPARE(indian.toLongLong(strResult64), int64); |
| 3101 | |
| 3102 | quint64 uint64 = Q_UINT64_C(1000000000000000000); |
| 3103 | QCOMPARE(indian.toString(uint64), strResult64); |
| 3104 | QCOMPARE(indian.toULongLong(strResult64), uint64); |
| 3105 | } |
| 3106 | |
| 3107 | QTEST_MAIN(tst_QLocale) |
| 3108 | #include "tst_qlocale.moc" |
| 3109 | |