diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2022-10-03 17:43:50 +0800 |
---|---|---|
committer | Mitch Curtis <mitch.curtis@qt.io> | 2022-10-24 19:02:40 +0800 |
commit | ab52e478201ec692c1df66a08e01216bc7ea02ec (patch) | |
tree | ed76fdf402b2d4cb6970dcff3dbcdc174d5c7705 /tests/auto/qml/qqmllocale/tst_qqmllocale.cpp | |
parent | 9ce90305f2836df8afc18db5c0d47ffdc2116a74 (diff) |
Locale: add toString functions
Currently, it's not possible to show a single localized day number;
Qt.formatDate can show it if "d" is passed as the format string, but
that rules out passing a locale. If a locale is passed instead, you
can only pass e.g. Locale.ShortFormat or another enum value as the
extra argument, as opposed to a format string. This limitation requires
users to implement conversion helpers in C++ that allow accounting
for the locale.
This patch exposes an appropriate subset of the existing date-to-string
conversion functions from QLocale to the QML Locale type.
For completeness, it also exposes the other relevant overloads:
- toString(int i)
- toString(double f, char format = 'g', int precision = 6)
- toString(Date date, string format)
- toString(Date date, FormatType format = LongFormat)
[ChangeLog][QtQml][Locale] Added toString() overloads.
Fixes: QTBUG-105506
Change-Id: I7061c68097cc11b69179117f5825e368bcfc296b
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Nicholas Bennett <nicholas.bennett@qt.io>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
Diffstat (limited to 'tests/auto/qml/qqmllocale/tst_qqmllocale.cpp')
-rw-r--r-- | tests/auto/qml/qqmllocale/tst_qqmllocale.cpp | 157 |
1 files changed, 125 insertions, 32 deletions
diff --git a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp index 2fda8b3bd4..3349f5f9b6 100644 --- a/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp +++ b/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp @@ -9,6 +9,7 @@ #include <QtQml/qqmlcomponent.h> #include <QtQml/qqmlcontext.h> #include <QtCore/QDateTime> +#include <QtCore/qtimezone.h> #include <QtCore/qscopeguard.h> #include <QtCore/qscopedpointer.h> #include <qcolor.h> @@ -66,6 +67,8 @@ private slots: void dayName(); void standaloneDayName_data(); void standaloneDayName(); + void toString_data(); + void toString(); void firstDayOfWeek_data(); void firstDayOfWeek(); void weekDays_data(); @@ -126,6 +129,8 @@ private: void addDateFormatData(const QString &l); void addTimeFormatData(const QString &l); void addFormattedDataSizeDataForLocale(const QString &l); + void testFunctionCall(); + void addTestFunctionCallDataColumns(); QQmlEngine engine; }; @@ -421,6 +426,66 @@ void tst_qqmllocale::standaloneDayName() } } +void tst_qqmllocale::toString_data() +{ + addTestFunctionCallDataColumns(); + + // Test general error conditions which aren't overload or locale-specific. + QString functionCallScript = "locale.toString()"; + QTest::newRow(qPrintable(functionCallScript)) << "en_AU" << functionCallScript + << "QLocale(English, Latin, Australia)" << QString(); + + functionCallScript = "locale.toString(1, 2, 3, 4)"; + QString errorMessage = ".*Locale: toString\\(\\): Expected 1-3 arguments, but received 4"; + QTest::newRow(qPrintable(functionCallScript)) << "en_AU" << functionCallScript << QString() << errorMessage; + + // Test toString(int). + functionCallScript = "locale.toString(123)"; + QTest::newRow(qPrintable(functionCallScript)) << "de_DE" << functionCallScript << "123" << QString(); + + // Test toString(double[, char][, int]). + functionCallScript = "locale.toString(123.456)"; + QTest::newRow(qPrintable(functionCallScript)) << "de_DE" << functionCallScript << "123,456" << QString(); + + functionCallScript = "locale.toString(123.456, 'e')"; + QTest::newRow(qPrintable(functionCallScript)) << "de_DE" << functionCallScript << "1,234560E+02" << QString(); + + functionCallScript = "locale.toString(123.456, 'e', 1)"; + QTest::newRow(qPrintable(functionCallScript)) << "de_DE" << functionCallScript << "1,2E+02" << QString(); + + // Test toString(Date, string) and toString(Date[, FormatType]). + const QDateTime midnight2000(QDate(2000, 1, 1), QTime(0, 0)); + // 12 AM might not exist in this timezone (some timezones have transitions at midnight). + if (midnight2000.isValid()) { + functionCallScript = "locale.toString(new Date(2000, 1, 1))"; + QTest::newRow(qPrintable(functionCallScript)) << "en_AU" << functionCallScript + << QLatin1String("Tuesday, 1 February 2000 12:00:00 AM ") + midnight2000.timeZoneAbbreviation() << QString(); + } + + functionCallScript = "locale.toString(new Date(2022, 7, 16), [])"; + errorMessage = ".*Locale: the second argument to the toString overloads whose " + "first argument is a Date should be a string or FormatType"; + QTest::newRow(qPrintable(functionCallScript)) << "ar" << functionCallScript << QString() << errorMessage; + + functionCallScript = "locale.toString([], 'd')"; + errorMessage = ".*Locale: toString\\(\\) expects either an int, double, or Date as its first argument"; + QTest::newRow(qPrintable(functionCallScript)) << "ar" << functionCallScript << QString() << errorMessage; + + functionCallScript = "locale.toString(new Date(2022, 7, 16), 'd')"; + QTest::newRow(qPrintable(functionCallScript)) << "ar" << functionCallScript << "١٦" << QString(); + + functionCallScript = "locale.toString(new Date(2022, 7, 16), Locale.ShortFormat)"; + QTest::newRow(qPrintable(functionCallScript)) << "en_AU" << functionCallScript << "16/8/22 12:00 AM" << QString(); + + functionCallScript = "locale.toString(new Date(2022, 7, 16, 1, 23, 4), Locale.ShortFormat)"; + QTest::newRow(qPrintable(functionCallScript)) << "en_AU" << functionCallScript << "16/8/22 1:23 AM" << QString(); +} + +void tst_qqmllocale::toString() +{ + testFunctionCall(); +} + void tst_qqmllocale::firstDayOfWeek_data() { QTest::addColumn<QString>("locale"); @@ -658,39 +723,16 @@ void tst_qqmllocale::addFormattedDataSizeDataForLocale(const QString &localeStr) QTest::newRow(qPrintable(makeTag())) << localeStr << functionCallScript << expectedResult << expectedErrorMessage; } -void tst_qqmllocale::formattedDataSize_data() -{ - QTest::addColumn<QString>("localeStr"); - QTest::addColumn<QString>("functionCallScript"); - QTest::addColumn<QString>("expectedResult"); - QTest::addColumn<QString>("expectedErrorMessagePattern"); - - addFormattedDataSizeDataForLocale("en_US"); - addFormattedDataSizeDataForLocale("de_DE"); - addFormattedDataSizeDataForLocale("ar_SA"); - addFormattedDataSizeDataForLocale("hi_IN"); - addFormattedDataSizeDataForLocale("zh_CN"); - addFormattedDataSizeDataForLocale("th_TH"); +#define STOP_ON_FAILURE \ + if (QTest::currentTestFailed()) \ + return; - // Test error conditions (which aren't locale-specific). - QString functionCallScript = "locale.formattedDataSize()"; - QString errorMessage = ".*Locale: formattedDataSize\\(\\): Expected 1-3 arguments, but received 0"; - QTest::newRow("too few args") << "en_AU" << functionCallScript << QString() << errorMessage; - - functionCallScript = "locale.formattedDataSize(10, 1, Locale.DataSizeIecFormat, \"foo\")"; - errorMessage = ".*Locale: formattedDataSize\\(\\): Expected 1-3 arguments, but received 4"; - QTest::newRow("too many args") << "en_AU" << functionCallScript << QString() << errorMessage; - - functionCallScript = "locale.formattedDataSize(10, \"no\")"; - errorMessage = ".*Locale: formattedDataSize\\(\\): Invalid argument \\('precision' must be an int\\)"; - QTest::newRow("precision wrong type") << "en_AU" << functionCallScript << QString() << errorMessage; - - functionCallScript = "locale.formattedDataSize(10, 1, \"no\")"; - errorMessage = ".*Locale: formattedDataSize\\(\\): Invalid argument \\('format' must be DataSizeFormat\\)"; - QTest::newRow("format wrong type") << "en_AU" << functionCallScript << QString() << errorMessage; -} - -void tst_qqmllocale::formattedDataSize() +/*! + To simplify the tests, this function calls a function and checks the + return value (a string). If it's expected that it fails, it checks + that the expected error message was printed. +*/ +void tst_qqmllocale::testFunctionCall() { QFETCH(QString, localeStr); QFETCH(QString, functionCallScript); @@ -699,15 +741,18 @@ void tst_qqmllocale::formattedDataSize() QQmlComponent component(&engine, testFileUrl("functions.qml")); QVERIFY2(component.isReady(), qPrintable(component.errorString())); + STOP_ON_FAILURE QScopedPointer<QObject> object(component.create()); QVERIFY(object); + STOP_ON_FAILURE QLocale locale(localeStr); QVariant returnValue; QVERIFY(QMetaObject::invokeMethod(object.data(), "setLocale", Qt::DirectConnection, Q_ARG(QVariant, QVariant(localeStr)))); + STOP_ON_FAILURE // Make sure that we use the object's context rather than the root context, // so that e.g. enums from the Locale type are available (QTBUG-91747). @@ -715,18 +760,66 @@ void tst_qqmllocale::formattedDataSize() const QVariant evaluationResult = qmlExpression.evaluate(); if (expectedErrorMessagePattern.isEmpty()) { QVERIFY2(!qmlExpression.hasError(), qPrintable(qmlExpression.error().toString())); + STOP_ON_FAILURE QVERIFY(evaluationResult.canConvert<QString>()); + STOP_ON_FAILURE QCOMPARE(evaluationResult.toString(), expectedResult); + STOP_ON_FAILURE } else { QVERIFY(qmlExpression.hasError()); + STOP_ON_FAILURE QRegularExpression errorRegex(expectedErrorMessagePattern); QVERIFY(errorRegex.isValid()); + STOP_ON_FAILURE QVERIFY2(errorRegex.match(qmlExpression.error().toString()).hasMatch(), qPrintable(QString::fromLatin1("Mismatch in actual vs expected error message:\n Actual: %1\n Expected: %2") .arg(qmlExpression.error().toString()).arg(expectedErrorMessagePattern))); + STOP_ON_FAILURE } } +void tst_qqmllocale::addTestFunctionCallDataColumns() +{ + QTest::addColumn<QString>("localeStr"); + QTest::addColumn<QString>("functionCallScript"); + QTest::addColumn<QString>("expectedResult"); + QTest::addColumn<QString>("expectedErrorMessagePattern"); +} + +void tst_qqmllocale::formattedDataSize_data() +{ + addTestFunctionCallDataColumns(); + + addFormattedDataSizeDataForLocale("en_US"); + addFormattedDataSizeDataForLocale("de_DE"); + addFormattedDataSizeDataForLocale("ar_SA"); + addFormattedDataSizeDataForLocale("hi_IN"); + addFormattedDataSizeDataForLocale("zh_CN"); + addFormattedDataSizeDataForLocale("th_TH"); + + // Test error conditions (which aren't locale-specific). + QString functionCallScript = "locale.formattedDataSize()"; + QString errorMessage = ".*Locale: formattedDataSize\\(\\): Expected 1-3 arguments, but received 0"; + QTest::newRow("too few args") << "en_AU" << functionCallScript << QString() << errorMessage; + + functionCallScript = "locale.formattedDataSize(10, 1, Locale.DataSizeIecFormat, \"foo\")"; + errorMessage = ".*Locale: formattedDataSize\\(\\): Expected 1-3 arguments, but received 4"; + QTest::newRow("too many args") << "en_AU" << functionCallScript << QString() << errorMessage; + + functionCallScript = "locale.formattedDataSize(10, \"no\")"; + errorMessage = ".*Locale: formattedDataSize\\(\\): Invalid argument \\('precision' must be an int\\)"; + QTest::newRow("precision wrong type") << "en_AU" << functionCallScript << QString() << errorMessage; + + functionCallScript = "locale.formattedDataSize(10, 1, \"no\")"; + errorMessage = ".*Locale: formattedDataSize\\(\\): Invalid argument \\('format' must be DataSizeFormat\\)"; + QTest::newRow("format wrong type") << "en_AU" << functionCallScript << QString() << errorMessage; +} + +void tst_qqmllocale::formattedDataSize() +{ + testFunctionCall(); +} + void tst_qqmllocale::dateToLocaleString_data() { addStandardFormatData(); |