aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
diff options
context:
space:
mode:
authorMitch Curtis <mitch.curtis@qt.io>2022-10-03 17:43:50 +0800
committerMitch Curtis <mitch.curtis@qt.io>2022-10-24 19:02:40 +0800
commitab52e478201ec692c1df66a08e01216bc7ea02ec (patch)
treeed76fdf402b2d4cb6970dcff3dbcdc174d5c7705 /tests/auto/qml/qqmllocale/tst_qqmllocale.cpp
parent9ce90305f2836df8afc18db5c0d47ffdc2116a74 (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.cpp157
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();