1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2016 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 | #include <qtest.h> |
29 | #include <QDebug> |
30 | |
31 | #include <QtQml/qqmlengine.h> |
32 | #include <QtQml/qqmlcomponent.h> |
33 | #include <QtQml/qqmlcontext.h> |
34 | #include <QtCore/QDateTime> |
35 | #include <QtCore/qscopeguard.h> |
36 | #include <QtCore/qscopedpointer.h> |
37 | #include <QtCore/qtimezone.h> |
38 | #include <qcolor.h> |
39 | #include "../../shared/util.h" |
40 | |
41 | #include <time.h> |
42 | |
43 | class tst_qqmllocale : public QQmlDataTest |
44 | { |
45 | Q_OBJECT |
46 | public: |
47 | tst_qqmllocale() { } |
48 | |
49 | private slots: |
50 | void defaultLocale(); |
51 | |
52 | void properties_data(); |
53 | void properties(); |
54 | void currencySymbol_data(); |
55 | void currencySymbol(); |
56 | void monthName_data(); |
57 | void monthName(); |
58 | void standaloneMonthName_data(); |
59 | void standaloneMonthName(); |
60 | void dayName_data(); |
61 | void dayName(); |
62 | void standaloneDayName_data(); |
63 | void standaloneDayName(); |
64 | void firstDayOfWeek_data(); |
65 | void firstDayOfWeek(); |
66 | void weekDays_data(); |
67 | void weekDays(); |
68 | void uiLanguages_data(); |
69 | void uiLanguages(); |
70 | void dateFormat_data(); |
71 | void dateFormat(); |
72 | void dateTimeFormat_data(); |
73 | void dateTimeFormat(); |
74 | void timeFormat_data(); |
75 | void timeFormat(); |
76 | #if defined(Q_OS_UNIX) && QT_CONFIG(timezone) |
77 | void timeZoneUpdated(); |
78 | #endif |
79 | |
80 | void dateToLocaleString_data(); |
81 | void dateToLocaleString(); |
82 | void dateToLocaleStringFormatted_data(); |
83 | void dateToLocaleStringFormatted(); |
84 | void dateToLocaleDateString_data(); |
85 | void dateToLocaleDateString(); |
86 | void dateToLocaleDateStringFormatted_data(); |
87 | void dateToLocaleDateStringFormatted(); |
88 | void dateToLocaleTimeString_data(); |
89 | void dateToLocaleTimeString(); |
90 | void dateToLocaleTimeStringFormatted_data(); |
91 | void dateToLocaleTimeStringFormatted(); |
92 | void dateFromLocaleString_data(); |
93 | void dateFromLocaleString(); |
94 | void dateFromLocaleDateString_data(); |
95 | void dateFromLocaleDateString(); |
96 | void dateFromLocaleTimeString_data(); |
97 | void dateFromLocaleTimeString(); |
98 | |
99 | void numberToLocaleString_data(); |
100 | void numberToLocaleString(); |
101 | void numberToLocaleCurrencyString_data(); |
102 | void numberToLocaleCurrencyString(); |
103 | void numberFromLocaleString_data(); |
104 | void numberFromLocaleString(); |
105 | void numberConstToLocaleString(); |
106 | void numberOptions(); |
107 | |
108 | void stringLocaleCompare_data(); |
109 | void stringLocaleCompare(); |
110 | |
111 | void localeAsCppProperty(); |
112 | private: |
113 | void addPropertyData(const QString &l); |
114 | QVariant getProperty(QObject *obj, const QString &locale, const QString &property); |
115 | void addCurrencySymbolData(const QString &locale); |
116 | void addStandardFormatData(); |
117 | void addFormatNameData(const QString &locale); |
118 | void addDateTimeFormatData(const QString &l); |
119 | void addDateFormatData(const QString &l); |
120 | void addTimeFormatData(const QString &l); |
121 | QQmlEngine engine; |
122 | }; |
123 | |
124 | void tst_qqmllocale::defaultLocale() |
125 | { |
126 | QQmlComponent c(&engine, testFileUrl(fileName: "properties.qml")); |
127 | |
128 | QObject *obj = c.create(); |
129 | QVERIFY(obj); |
130 | |
131 | QCOMPARE(obj->property("name").toString(), QLocale().name()); |
132 | } |
133 | |
134 | #define LOCALE_PROP(type,prop) { #prop, QVariant(type(qlocale.prop())) } |
135 | |
136 | void tst_qqmllocale::addPropertyData(const QString &l) |
137 | { |
138 | QLocale qlocale(l); |
139 | |
140 | struct { |
141 | const char *name; |
142 | QVariant value; |
143 | } |
144 | values[] = { |
145 | LOCALE_PROP(QString,name), |
146 | LOCALE_PROP(QString,amText), |
147 | LOCALE_PROP(QString,pmText), |
148 | LOCALE_PROP(QString,nativeLanguageName), |
149 | LOCALE_PROP(QString,nativeCountryName), |
150 | LOCALE_PROP(QString,decimalPoint), |
151 | LOCALE_PROP(QString,groupSeparator), |
152 | LOCALE_PROP(QString,percent), |
153 | LOCALE_PROP(QString,zeroDigit), |
154 | LOCALE_PROP(QString,negativeSign), |
155 | LOCALE_PROP(QString,positiveSign), |
156 | LOCALE_PROP(QString,exponential), |
157 | LOCALE_PROP(int,measurementSystem), |
158 | LOCALE_PROP(int,textDirection), |
159 | { .name: nullptr, .value: QVariant() } |
160 | }; |
161 | |
162 | int i = 0; |
163 | while (values[i].name) { |
164 | QByteArray n = l.toLatin1() + ':' + values[i].name; |
165 | QTest::newRow(dataTag: n.constData()) << l << QByteArray(values[i].name) << values[i].value; |
166 | ++i; |
167 | } |
168 | } |
169 | |
170 | void tst_qqmllocale::properties_data() |
171 | { |
172 | QTest::addColumn<QString>(name: "locale"); |
173 | QTest::addColumn<QByteArray>(name: "property"); |
174 | QTest::addColumn<QVariant>(name: "value"); |
175 | |
176 | addPropertyData(l: "en_US"); |
177 | addPropertyData(l: "de_DE"); |
178 | addPropertyData(l: "ar_SA"); |
179 | addPropertyData(l: "hi_IN"); |
180 | addPropertyData(l: "zh_CN"); |
181 | addPropertyData(l: "th_TH"); |
182 | } |
183 | |
184 | void tst_qqmllocale::properties() |
185 | { |
186 | QFETCH(QString, locale); |
187 | QFETCH(QByteArray, property); |
188 | QFETCH(QVariant, value); |
189 | |
190 | QQmlComponent c(&engine, testFileUrl(fileName: "properties.qml")); |
191 | |
192 | QObject *obj = c.create(); |
193 | QVERIFY(obj); |
194 | |
195 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
196 | Q_ARG(QVariant, QVariant(locale))); |
197 | |
198 | QCOMPARE(obj->property(property), value); |
199 | |
200 | delete obj; |
201 | } |
202 | |
203 | void tst_qqmllocale::addCurrencySymbolData(const QString &l) |
204 | { |
205 | QByteArray locale = l.toLatin1(); |
206 | QTest::newRow(dataTag: locale.constData()) << l << -1; |
207 | QByteArray t(locale); |
208 | t += " CurrencyIsoCode"; |
209 | QTest::newRow(dataTag: t.constData()) << l << (int)QLocale::CurrencyIsoCode; |
210 | t = locale + " CurrencySymbol"; |
211 | QTest::newRow(dataTag: t.constData()) << l << (int)QLocale::CurrencySymbol; |
212 | t = locale + " CurrencyDisplayName"; |
213 | QTest::newRow(dataTag: t.constData()) << l << (int)QLocale::CurrencyDisplayName; |
214 | } |
215 | |
216 | void tst_qqmllocale::currencySymbol_data() |
217 | { |
218 | QTest::addColumn<QString>(name: "locale"); |
219 | QTest::addColumn<int>(name: "param"); |
220 | |
221 | addCurrencySymbolData(l: "en_US"); |
222 | addCurrencySymbolData(l: "de_DE"); |
223 | addCurrencySymbolData(l: "ar_SA"); |
224 | addCurrencySymbolData(l: "hi_IN"); |
225 | addCurrencySymbolData(l: "zh_CN"); |
226 | addCurrencySymbolData(l: "th_TH"); |
227 | } |
228 | |
229 | void tst_qqmllocale::currencySymbol() |
230 | { |
231 | QFETCH(QString, locale); |
232 | QFETCH(int, param); |
233 | |
234 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
235 | |
236 | QObject *obj = c.create(); |
237 | QVERIFY(obj); |
238 | |
239 | QLocale l(locale); |
240 | QVariant val; |
241 | QLocale::CurrencySymbolFormat format = QLocale::CurrencySymbol; |
242 | |
243 | if (param >= 0) |
244 | format = QLocale::CurrencySymbolFormat(param); |
245 | |
246 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
247 | Q_ARG(QVariant, QVariant(locale))); |
248 | |
249 | QMetaObject::invokeMethod(obj, member: "currencySymbol", Qt::DirectConnection, |
250 | Q_RETURN_ARG(QVariant, val), |
251 | Q_ARG(QVariant, QVariant(int(format)))); |
252 | |
253 | QCOMPARE(val.toString(), l.currencySymbol(format)); |
254 | |
255 | delete obj; |
256 | } |
257 | |
258 | void tst_qqmllocale::addFormatNameData(const QString &l) |
259 | { |
260 | QByteArray locale = l.toLatin1(); |
261 | QTest::newRow(dataTag: locale.constData()) << l << -1; |
262 | QByteArray t(locale); |
263 | t += " LongFormat"; |
264 | QTest::newRow(dataTag: t.constData()) << l << (int)QLocale::LongFormat; |
265 | t = locale + " ShortFormat"; |
266 | QTest::newRow(dataTag: t.constData()) << l << (int)QLocale::ShortFormat; |
267 | t = locale + " NarrowFormat"; |
268 | QTest::newRow(dataTag: t.constData()) << l << (int)QLocale::NarrowFormat; |
269 | } |
270 | |
271 | void tst_qqmllocale::addStandardFormatData() |
272 | { |
273 | QTest::addColumn<QString>(name: "locale"); |
274 | QTest::addColumn<int>(name: "param"); |
275 | |
276 | addFormatNameData(l: "en_US"); |
277 | addFormatNameData(l: "de_DE"); |
278 | addFormatNameData(l: "ar_SA"); |
279 | addFormatNameData(l: "hi_IN"); |
280 | addFormatNameData(l: "zh_CN"); |
281 | addFormatNameData(l: "th_TH"); |
282 | } |
283 | |
284 | void tst_qqmllocale::monthName_data() |
285 | { |
286 | addStandardFormatData(); |
287 | } |
288 | |
289 | void tst_qqmllocale::monthName() |
290 | { |
291 | QFETCH(QString, locale); |
292 | QFETCH(int, param); |
293 | |
294 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
295 | |
296 | QObject *obj = c.create(); |
297 | QVERIFY(obj); |
298 | |
299 | QLocale l(locale); |
300 | QVariant val; |
301 | QLocale::FormatType format = QLocale::LongFormat; |
302 | if (param >= 0) |
303 | format = QLocale::FormatType(param); |
304 | |
305 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
306 | Q_ARG(QVariant, QVariant(locale))); |
307 | |
308 | for (int i = 0; i <= 11; ++i) { |
309 | QMetaObject::invokeMethod(obj, member: "monthName", Qt::DirectConnection, |
310 | Q_RETURN_ARG(QVariant, val), |
311 | Q_ARG(QVariant, QVariant(i)), |
312 | Q_ARG(QVariant, QVariant(int(format)))); |
313 | |
314 | // QLocale January == 1, JS Date January == 0 |
315 | QCOMPARE(val.toString(), l.monthName(i+1, format)); |
316 | } |
317 | |
318 | delete obj; |
319 | } |
320 | |
321 | void tst_qqmllocale::standaloneMonthName_data() |
322 | { |
323 | addStandardFormatData(); |
324 | } |
325 | |
326 | void tst_qqmllocale::standaloneMonthName() |
327 | { |
328 | QFETCH(QString, locale); |
329 | QFETCH(int, param); |
330 | |
331 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
332 | |
333 | QObject *obj = c.create(); |
334 | QVERIFY(obj); |
335 | |
336 | QLocale l(locale); |
337 | QVariant val; |
338 | QLocale::FormatType format = QLocale::LongFormat; |
339 | if (param >= 0) |
340 | format = QLocale::FormatType(param); |
341 | |
342 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
343 | Q_ARG(QVariant, QVariant(locale))); |
344 | |
345 | for (int i = 0; i <= 11; ++i) { |
346 | QMetaObject::invokeMethod(obj, member: "standaloneMonthName", Qt::DirectConnection, |
347 | Q_RETURN_ARG(QVariant, val), |
348 | Q_ARG(QVariant, QVariant(i)), |
349 | Q_ARG(QVariant, QVariant(int(format)))); |
350 | |
351 | // QLocale January == 1, JS Date January == 0 |
352 | QCOMPARE(val.toString(), l.standaloneMonthName(i+1, format)); |
353 | } |
354 | |
355 | delete obj; |
356 | } |
357 | |
358 | void tst_qqmllocale::dayName_data() |
359 | { |
360 | addStandardFormatData(); |
361 | } |
362 | |
363 | void tst_qqmllocale::dayName() |
364 | { |
365 | QFETCH(QString, locale); |
366 | QFETCH(int, param); |
367 | |
368 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
369 | |
370 | QObject *obj = c.create(); |
371 | QVERIFY(obj); |
372 | |
373 | QLocale l(locale); |
374 | QVariant val; |
375 | QLocale::FormatType format = QLocale::LongFormat; |
376 | if (param >= 0) |
377 | format = QLocale::FormatType(param); |
378 | |
379 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
380 | Q_ARG(QVariant, QVariant(locale))); |
381 | |
382 | for (int i = 1; i <= 7; ++i) { |
383 | QMetaObject::invokeMethod(obj, member: "dayName", Qt::DirectConnection, |
384 | Q_RETURN_ARG(QVariant, val), |
385 | Q_ARG(QVariant, QVariant(i)), |
386 | Q_ARG(QVariant, QVariant(int(format)))); |
387 | |
388 | QCOMPARE(val.toString(), l.dayName(i, format)); |
389 | } |
390 | |
391 | delete obj; |
392 | } |
393 | |
394 | void tst_qqmllocale::standaloneDayName_data() |
395 | { |
396 | addStandardFormatData(); |
397 | } |
398 | |
399 | void tst_qqmllocale::standaloneDayName() |
400 | { |
401 | QFETCH(QString, locale); |
402 | QFETCH(int, param); |
403 | |
404 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
405 | |
406 | QObject *obj = c.create(); |
407 | QVERIFY(obj); |
408 | |
409 | QLocale l(locale); |
410 | QVariant val; |
411 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
412 | |
413 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
414 | Q_ARG(QVariant, QVariant(locale))); |
415 | |
416 | for (int i = 1; i <= 7; ++i) { |
417 | QMetaObject::invokeMethod(obj, member: "standaloneDayName", Qt::DirectConnection, |
418 | Q_RETURN_ARG(QVariant, val), |
419 | Q_ARG(QVariant, QVariant(i)), |
420 | Q_ARG(QVariant, QVariant(int(format)))); |
421 | |
422 | QCOMPARE(val.toString(), l.standaloneDayName(i, format)); |
423 | } |
424 | |
425 | delete obj; |
426 | } |
427 | |
428 | void tst_qqmllocale::firstDayOfWeek_data() |
429 | { |
430 | QTest::addColumn<QString>(name: "locale"); |
431 | |
432 | QTest::newRow(dataTag: "en_US") << "en_US"; |
433 | QTest::newRow(dataTag: "de_DE") << "de_DE"; |
434 | QTest::newRow(dataTag: "ar_SA") << "ar_SA"; |
435 | QTest::newRow(dataTag: "hi_IN") << "hi_IN"; |
436 | QTest::newRow(dataTag: "zh_CN") << "zh_CN"; |
437 | QTest::newRow(dataTag: "th_TH") << "th_TH"; |
438 | } |
439 | |
440 | void tst_qqmllocale::firstDayOfWeek() |
441 | { |
442 | QFETCH(QString, locale); |
443 | |
444 | QQmlComponent c(&engine, testFileUrl(fileName: "properties.qml")); |
445 | |
446 | QObject *obj = c.create(); |
447 | QVERIFY(obj); |
448 | |
449 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
450 | Q_ARG(QVariant, QVariant(locale))); |
451 | |
452 | QVariant val = obj->property(name: "firstDayOfWeek"); |
453 | QCOMPARE(val.userType(), QMetaType::Int); |
454 | |
455 | int day = int(QLocale(locale).firstDayOfWeek()); |
456 | if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday) |
457 | day = 0; |
458 | QCOMPARE(day, val.toInt()); |
459 | |
460 | delete obj; |
461 | } |
462 | |
463 | void tst_qqmllocale::weekDays_data() |
464 | { |
465 | QTest::addColumn<QString>(name: "locale"); |
466 | |
467 | QTest::newRow(dataTag: "en_US") << "en_US"; |
468 | QTest::newRow(dataTag: "de_DE") << "de_DE"; |
469 | QTest::newRow(dataTag: "ar_SA") << "ar_SA"; |
470 | QTest::newRow(dataTag: "hi_IN") << "hi_IN"; |
471 | QTest::newRow(dataTag: "zh_CN") << "zh_CN"; |
472 | QTest::newRow(dataTag: "th_TH") << "th_TH"; |
473 | } |
474 | |
475 | void tst_qqmllocale::weekDays() |
476 | { |
477 | QFETCH(QString, locale); |
478 | |
479 | QQmlComponent c(&engine, testFileUrl(fileName: "properties.qml")); |
480 | |
481 | QObject *obj = c.create(); |
482 | QVERIFY(obj); |
483 | |
484 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
485 | Q_ARG(QVariant, QVariant(locale))); |
486 | |
487 | QVariant val = obj->property(name: "weekDays"); |
488 | QCOMPARE(val.userType(), qMetaTypeId<QJSValue>()); |
489 | |
490 | QList<QVariant> qmlDays = val.toList(); |
491 | QList<Qt::DayOfWeek> days = QLocale(locale).weekdays(); |
492 | |
493 | QCOMPARE(days.count(), qmlDays.count()); |
494 | |
495 | for (int i = 0; i < days.count(); ++i) { |
496 | int day = int(days.at(i)); |
497 | if (day == 7) // JS Date days in range 0(Sunday) to 6(Saturday) |
498 | day = 0; |
499 | QCOMPARE(day, qmlDays.at(i).toInt()); |
500 | } |
501 | |
502 | delete obj; |
503 | } |
504 | |
505 | void tst_qqmllocale::uiLanguages_data() |
506 | { |
507 | QTest::addColumn<QString>(name: "locale"); |
508 | |
509 | QTest::newRow(dataTag: "en_US") << "en_US"; |
510 | QTest::newRow(dataTag: "de_DE") << "de_DE"; |
511 | QTest::newRow(dataTag: "ar_SA") << "ar_SA"; |
512 | QTest::newRow(dataTag: "hi_IN") << "hi_IN"; |
513 | QTest::newRow(dataTag: "zh_CN") << "zh_CN"; |
514 | QTest::newRow(dataTag: "th_TH") << "th_TH"; |
515 | } |
516 | |
517 | void tst_qqmllocale::uiLanguages() |
518 | { |
519 | QFETCH(QString, locale); |
520 | |
521 | QQmlComponent c(&engine, testFileUrl(fileName: "properties.qml")); |
522 | |
523 | QObject *obj = c.create(); |
524 | QVERIFY(obj); |
525 | |
526 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
527 | Q_ARG(QVariant, QVariant(locale))); |
528 | |
529 | QVariant val = obj->property(name: "uiLanguages"); |
530 | QCOMPARE(val.userType(), qMetaTypeId<QJSValue>()); |
531 | |
532 | QList<QVariant> qmlLangs = val.toList(); |
533 | QStringList langs = QLocale(locale).uiLanguages(); |
534 | |
535 | QCOMPARE(langs.count(), qmlLangs.count()); |
536 | |
537 | for (int i = 0; i < langs.count(); ++i) { |
538 | QCOMPARE(langs.at(i), qmlLangs.at(i).toString()); |
539 | } |
540 | |
541 | delete obj; |
542 | } |
543 | |
544 | |
545 | void tst_qqmllocale::dateTimeFormat_data() |
546 | { |
547 | addStandardFormatData(); |
548 | } |
549 | |
550 | void tst_qqmllocale::dateTimeFormat() |
551 | { |
552 | QFETCH(QString, locale); |
553 | QFETCH(int, param); |
554 | |
555 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
556 | |
557 | QObject *obj = c.create(); |
558 | QVERIFY(obj); |
559 | |
560 | QLocale l(locale); |
561 | QVariant val; |
562 | |
563 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
564 | Q_ARG(QVariant, QVariant(locale))); |
565 | |
566 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
567 | QMetaObject::invokeMethod(obj, member: "dateTimeFormat", Qt::DirectConnection, |
568 | Q_RETURN_ARG(QVariant, val), |
569 | Q_ARG(QVariant, QVariant(param))); |
570 | |
571 | QCOMPARE(val.toString(), l.dateTimeFormat(format)); |
572 | } |
573 | |
574 | void tst_qqmllocale::dateFormat_data() |
575 | { |
576 | addStandardFormatData(); |
577 | } |
578 | |
579 | void tst_qqmllocale::dateFormat() |
580 | { |
581 | QFETCH(QString, locale); |
582 | QFETCH(int, param); |
583 | |
584 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
585 | |
586 | QObject *obj = c.create(); |
587 | QVERIFY(obj); |
588 | |
589 | QLocale l(locale); |
590 | QVariant val; |
591 | |
592 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
593 | Q_ARG(QVariant, QVariant(locale))); |
594 | |
595 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
596 | QMetaObject::invokeMethod(obj, member: "dateFormat", Qt::DirectConnection, |
597 | Q_RETURN_ARG(QVariant, val), |
598 | Q_ARG(QVariant, QVariant(param))); |
599 | |
600 | QCOMPARE(val.toString(), l.dateFormat(format)); |
601 | } |
602 | |
603 | void tst_qqmllocale::timeFormat_data() |
604 | { |
605 | addStandardFormatData(); |
606 | } |
607 | |
608 | void tst_qqmllocale::timeFormat() |
609 | { |
610 | QFETCH(QString, locale); |
611 | QFETCH(int, param); |
612 | |
613 | QQmlComponent c(&engine, testFileUrl(fileName: "functions.qml")); |
614 | |
615 | QObject *obj = c.create(); |
616 | QVERIFY(obj); |
617 | |
618 | QLocale l(locale); |
619 | QVariant val; |
620 | |
621 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
622 | Q_ARG(QVariant, QVariant(locale))); |
623 | |
624 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
625 | QMetaObject::invokeMethod(obj, member: "timeFormat", Qt::DirectConnection, |
626 | Q_RETURN_ARG(QVariant, val), |
627 | Q_ARG(QVariant, QVariant(param))); |
628 | |
629 | QCOMPARE(val.toString(), l.timeFormat(format)); |
630 | } |
631 | |
632 | void tst_qqmllocale::dateToLocaleString_data() |
633 | { |
634 | addStandardFormatData(); |
635 | } |
636 | |
637 | void tst_qqmllocale::dateToLocaleString() |
638 | { |
639 | QFETCH(QString, locale); |
640 | QFETCH(int, param); |
641 | |
642 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
643 | |
644 | QObject *obj = c.create(); |
645 | QVERIFY(obj); |
646 | |
647 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
648 | |
649 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
650 | Q_ARG(QVariant, QVariant(locale))); |
651 | |
652 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
653 | |
654 | QVariant val; |
655 | QMetaObject::invokeMethod(obj, member: "toLocaleString", Qt::DirectConnection, |
656 | Q_RETURN_ARG(QVariant, val), |
657 | Q_ARG(QVariant, QVariant(param))); |
658 | |
659 | QLocale l(locale); |
660 | QCOMPARE(val.toString(), l.toString(dt, format)); |
661 | } |
662 | |
663 | void tst_qqmllocale::addDateTimeFormatData(const QString &l) |
664 | { |
665 | const char *formats[] = { |
666 | "hh:mm dd.MM.yyyy", |
667 | "h:m:sap ddd MMMM d yy", |
668 | "'The date and time is: 'H:mm:ss:zzz dd/MM/yy", |
669 | "MMM d yyyy HH:mm t", |
670 | nullptr |
671 | }; |
672 | QByteArray locale = l.toLatin1(); |
673 | int i = 0; |
674 | while (formats[i]) { |
675 | QByteArray t(locale); |
676 | t += ' '; |
677 | t += formats[i]; |
678 | QTest::newRow(dataTag: t.constData()) << l << QString(formats[i]); |
679 | ++i; |
680 | } |
681 | } |
682 | |
683 | void tst_qqmllocale::dateToLocaleStringFormatted_data() |
684 | { |
685 | QTest::addColumn<QString>(name: "locale"); |
686 | QTest::addColumn<QString>(name: "format"); |
687 | |
688 | addDateTimeFormatData(l: "en_US"); |
689 | addDateTimeFormatData(l: "de_DE"); |
690 | addDateTimeFormatData(l: "ar_SA"); |
691 | addDateTimeFormatData(l: "hi_IN"); |
692 | addDateTimeFormatData(l: "zh_CN"); |
693 | addDateTimeFormatData(l: "th_TH"); |
694 | } |
695 | |
696 | void tst_qqmllocale::dateToLocaleStringFormatted() |
697 | { |
698 | QFETCH(QString, locale); |
699 | QFETCH(QString, format); |
700 | |
701 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
702 | |
703 | QObject *obj = c.create(); |
704 | QVERIFY(obj); |
705 | |
706 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
707 | |
708 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
709 | Q_ARG(QVariant, QVariant(locale))); |
710 | |
711 | QVariant val; |
712 | QMetaObject::invokeMethod(obj, member: "toLocaleString", Qt::DirectConnection, |
713 | Q_RETURN_ARG(QVariant, val), |
714 | Q_ARG(QVariant, QVariant(format))); |
715 | |
716 | QLocale l(locale); |
717 | QCOMPARE(val.toString(), l.toString(dt, format)); |
718 | } |
719 | |
720 | void tst_qqmllocale::dateToLocaleDateString_data() |
721 | { |
722 | addStandardFormatData(); |
723 | } |
724 | |
725 | void tst_qqmllocale::dateToLocaleDateString() |
726 | { |
727 | QFETCH(QString, locale); |
728 | QFETCH(int, param); |
729 | |
730 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
731 | |
732 | QObject *obj = c.create(); |
733 | QVERIFY(obj); |
734 | |
735 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
736 | |
737 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
738 | Q_ARG(QVariant, QVariant(locale))); |
739 | |
740 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
741 | |
742 | QVariant val; |
743 | QMetaObject::invokeMethod(obj, member: "toLocaleDateString", Qt::DirectConnection, |
744 | Q_RETURN_ARG(QVariant, val), |
745 | Q_ARG(QVariant, QVariant(param))); |
746 | |
747 | QLocale l(locale); |
748 | QCOMPARE(val.toString(), l.toString(dt.date(), format)); |
749 | } |
750 | |
751 | void tst_qqmllocale::addDateFormatData(const QString &l) |
752 | { |
753 | const char *formats[] = { |
754 | "dd.MM.yyyy", |
755 | "ddd MMMM d yy", |
756 | "'The date is: 'dd/MM/yy", |
757 | "MMM d yyyy", |
758 | nullptr |
759 | }; |
760 | QByteArray locale = l.toLatin1(); |
761 | int i = 0; |
762 | while (formats[i]) { |
763 | QByteArray t(locale); |
764 | t += ' '; |
765 | t += formats[i]; |
766 | QTest::newRow(dataTag: t.constData()) << l << QString(formats[i]); |
767 | ++i; |
768 | } |
769 | } |
770 | |
771 | void tst_qqmllocale::dateToLocaleDateStringFormatted_data() |
772 | { |
773 | QTest::addColumn<QString>(name: "locale"); |
774 | QTest::addColumn<QString>(name: "format"); |
775 | |
776 | addDateFormatData(l: "en_US"); |
777 | addDateFormatData(l: "de_DE"); |
778 | addDateFormatData(l: "ar_SA"); |
779 | addDateFormatData(l: "hi_IN"); |
780 | addDateFormatData(l: "zh_CN"); |
781 | addDateFormatData(l: "th_TH"); |
782 | } |
783 | |
784 | void tst_qqmllocale::dateToLocaleDateStringFormatted() |
785 | { |
786 | QFETCH(QString, locale); |
787 | QFETCH(QString, format); |
788 | |
789 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
790 | |
791 | QObject *obj = c.create(); |
792 | QVERIFY(obj); |
793 | |
794 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
795 | |
796 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
797 | Q_ARG(QVariant, QVariant(locale))); |
798 | |
799 | QVariant val; |
800 | QMetaObject::invokeMethod(obj, member: "toLocaleString", Qt::DirectConnection, |
801 | Q_RETURN_ARG(QVariant, val), |
802 | Q_ARG(QVariant, QVariant(format))); |
803 | |
804 | QLocale l(locale); |
805 | QCOMPARE(val.toString(), l.toString(dt.date(), format)); |
806 | } |
807 | |
808 | void tst_qqmllocale::dateToLocaleTimeString_data() |
809 | { |
810 | addStandardFormatData(); |
811 | } |
812 | |
813 | void tst_qqmllocale::dateToLocaleTimeString() |
814 | { |
815 | QFETCH(QString, locale); |
816 | QFETCH(int, param); |
817 | |
818 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
819 | |
820 | QObject *obj = c.create(); |
821 | QVERIFY(obj); |
822 | |
823 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
824 | |
825 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
826 | Q_ARG(QVariant, QVariant(locale))); |
827 | |
828 | QLocale::FormatType format = param < 0 ? QLocale::LongFormat : QLocale::FormatType(param); |
829 | |
830 | QVariant val; |
831 | QMetaObject::invokeMethod(obj, member: "toLocaleTimeString", Qt::DirectConnection, |
832 | Q_RETURN_ARG(QVariant, val), |
833 | Q_ARG(QVariant, QVariant(param))); |
834 | |
835 | QLocale l(locale); |
836 | QCOMPARE(val.toString(), l.toString(dt.time(), format)); |
837 | } |
838 | |
839 | void tst_qqmllocale::addTimeFormatData(const QString &l) |
840 | { |
841 | const char *formats[] = { |
842 | "hh:mm", |
843 | "h:m:sap", |
844 | "'The time is: 'H:mm:ss:zzz", |
845 | "HH:mm t", |
846 | nullptr |
847 | }; |
848 | QByteArray locale = l.toLatin1(); |
849 | int i = 0; |
850 | while (formats[i]) { |
851 | QByteArray t(locale); |
852 | t += ' '; |
853 | t += formats[i]; |
854 | QTest::newRow(dataTag: t.constData()) << l << QString(formats[i]); |
855 | ++i; |
856 | } |
857 | } |
858 | |
859 | void tst_qqmllocale::dateToLocaleTimeStringFormatted_data() |
860 | { |
861 | QTest::addColumn<QString>(name: "locale"); |
862 | QTest::addColumn<QString>(name: "format"); |
863 | |
864 | addTimeFormatData(l: "en_US"); |
865 | addTimeFormatData(l: "de_DE"); |
866 | addTimeFormatData(l: "ar_SA"); |
867 | addTimeFormatData(l: "hi_IN"); |
868 | addTimeFormatData(l: "zh_CN"); |
869 | addTimeFormatData(l: "th_TH"); |
870 | } |
871 | |
872 | void tst_qqmllocale::dateToLocaleTimeStringFormatted() |
873 | { |
874 | QFETCH(QString, locale); |
875 | QFETCH(QString, format); |
876 | |
877 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
878 | |
879 | QObject *obj = c.create(); |
880 | QVERIFY(obj); |
881 | |
882 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
883 | |
884 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
885 | Q_ARG(QVariant, QVariant(locale))); |
886 | |
887 | QVariant val; |
888 | QMetaObject::invokeMethod(obj, member: "toLocaleString", Qt::DirectConnection, |
889 | Q_RETURN_ARG(QVariant, val), |
890 | Q_ARG(QVariant, QVariant(format))); |
891 | |
892 | QLocale l(locale); |
893 | QCOMPARE(val.toString(), l.toString(dt, format)); |
894 | } |
895 | |
896 | void tst_qqmllocale::dateFromLocaleString_data() |
897 | { |
898 | QTest::addColumn<QString>(name: "locale"); |
899 | QTest::addColumn<QString>(name: "format"); |
900 | |
901 | QTest::newRow(dataTag: "en_US 1") << "en_US"<< "dddd, MMMM d, yyyy h:mm:ss AP"; |
902 | QTest::newRow(dataTag: "en_US long") << "en_US"<< QLocale( "en_US").dateTimeFormat(); |
903 | QTest::newRow(dataTag: "en_US short") << "en_US"<< QLocale( "en_US").dateTimeFormat(format: QLocale::ShortFormat); |
904 | QTest::newRow(dataTag: "de_DE long") << "de_DE"<< QLocale( "de_DE").dateTimeFormat(); |
905 | QTest::newRow(dataTag: "de_DE short") << "de_DE"<< QLocale( "de_DE").dateTimeFormat(format: QLocale::ShortFormat); |
906 | QTest::newRow(dataTag: "ar_SA long") << "ar_SA"<< QLocale( "ar_SA").dateTimeFormat(); |
907 | QTest::newRow(dataTag: "ar_SA short") << "ar_SA"<< QLocale( "ar_SA").dateTimeFormat(format: QLocale::ShortFormat); |
908 | QTest::newRow(dataTag: "zh_CN long") << "zh_CN"<< QLocale( "zh_CN").dateTimeFormat(); |
909 | QTest::newRow(dataTag: "zh_CN short") << "zh_CN"<< QLocale( "zh_CN").dateTimeFormat(format: QLocale::ShortFormat); |
910 | } |
911 | |
912 | void tst_qqmllocale::dateFromLocaleString() |
913 | { |
914 | QFETCH(QString, locale); |
915 | QFETCH(QString, format); |
916 | |
917 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
918 | |
919 | QObject *obj = c.create(); |
920 | QVERIFY(obj); |
921 | |
922 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
923 | |
924 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
925 | Q_ARG(QVariant, QVariant(locale))); |
926 | |
927 | QLocale l(locale); |
928 | const QString localeText(l.toString(dateTime: dt, format)); |
929 | QVariant val; |
930 | QMetaObject::invokeMethod(obj, member: "fromLocaleString", Qt::DirectConnection, |
931 | Q_RETURN_ARG(QVariant, val), |
932 | Q_ARG(QVariant, QVariant(localeText)), |
933 | Q_ARG(QVariant, QVariant(format))); |
934 | |
935 | QDateTime pd = l.toDateTime(string: localeText, format); |
936 | QCOMPARE(val.toDateTime(), pd); |
937 | } |
938 | |
939 | void tst_qqmllocale::dateFromLocaleDateString_data() |
940 | { |
941 | QTest::addColumn<QString>(name: "locale"); |
942 | QTest::addColumn<QString>(name: "format"); |
943 | |
944 | QTest::newRow(dataTag: "en_US 1") << "en_US"<< "dddd, MMMM d, yyyy h:mm:ss AP"; |
945 | QTest::newRow(dataTag: "en_US long") << "en_US"<< QLocale( "en_US").dateFormat(); |
946 | QTest::newRow(dataTag: "en_US short") << "en_US"<< QLocale( "en_US").dateFormat(format: QLocale::ShortFormat); |
947 | QTest::newRow(dataTag: "de_DE long") << "de_DE"<< QLocale( "de_DE").dateFormat(); |
948 | QTest::newRow(dataTag: "de_DE short") << "de_DE"<< QLocale( "de_DE").dateFormat(format: QLocale::ShortFormat); |
949 | QTest::newRow(dataTag: "ar_SA long") << "ar_SA"<< QLocale( "ar_SA").dateFormat(); |
950 | QTest::newRow(dataTag: "ar_SA short") << "ar_SA"<< QLocale( "ar_SA").dateFormat(format: QLocale::ShortFormat); |
951 | QTest::newRow(dataTag: "zh_CN long") << "zh_CN"<< QLocale( "zh_CN").dateFormat(); |
952 | QTest::newRow(dataTag: "zh_CN short") << "zh_CN"<< QLocale( "zh_CN").dateFormat(format: QLocale::ShortFormat); |
953 | } |
954 | |
955 | void tst_qqmllocale::dateFromLocaleDateString() |
956 | { |
957 | QFETCH(QString, locale); |
958 | QFETCH(QString, format); |
959 | |
960 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
961 | |
962 | QObject *obj = c.create(); |
963 | QVERIFY(obj); |
964 | |
965 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
966 | |
967 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
968 | Q_ARG(QVariant, QVariant(locale))); |
969 | |
970 | QLocale l(locale); |
971 | const QString localeText(l.toString(dateTime: dt, format)); |
972 | QVariant val; |
973 | QMetaObject::invokeMethod(obj, member: "fromLocaleDateString", Qt::DirectConnection, |
974 | Q_RETURN_ARG(QVariant, val), |
975 | Q_ARG(QVariant, QVariant(localeText)), |
976 | Q_ARG(QVariant, QVariant(format))); |
977 | |
978 | QDate pd = l.toDate(string: localeText, format); |
979 | QCOMPARE(val.toDate(), pd); |
980 | } |
981 | |
982 | void tst_qqmllocale::dateFromLocaleTimeString_data() |
983 | { |
984 | QTest::addColumn<QString>(name: "locale"); |
985 | QTest::addColumn<QString>(name: "format"); |
986 | |
987 | QTest::newRow(dataTag: "en_US 1") << "en_US"<< "dddd, MMMM d, yyyy h:mm:ss AP"; |
988 | QTest::newRow(dataTag: "en_US long") << "en_US"<< QLocale( "en_US").timeFormat(); |
989 | QTest::newRow(dataTag: "en_US short") << "en_US"<< QLocale( "en_US").timeFormat(format: QLocale::ShortFormat); |
990 | QTest::newRow(dataTag: "de_DE long") << "de_DE"<< QLocale( "de_DE").timeFormat(); |
991 | QTest::newRow(dataTag: "de_DE short") << "de_DE"<< QLocale( "de_DE").timeFormat(format: QLocale::ShortFormat); |
992 | QTest::newRow(dataTag: "ar_SA long") << "ar_SA"<< QLocale( "ar_SA").timeFormat(); |
993 | QTest::newRow(dataTag: "ar_SA short") << "ar_SA"<< QLocale( "ar_SA").timeFormat(format: QLocale::ShortFormat); |
994 | QTest::newRow(dataTag: "zh_CN long") << "zh_CN"<< QLocale( "zh_CN").timeFormat(); |
995 | QTest::newRow(dataTag: "zh_CN short") << "zh_CN"<< QLocale( "zh_CN").timeFormat(format: QLocale::ShortFormat); |
996 | } |
997 | |
998 | void tst_qqmllocale::dateFromLocaleTimeString() |
999 | { |
1000 | QFETCH(QString, locale); |
1001 | QFETCH(QString, format); |
1002 | |
1003 | QQmlComponent c(&engine, testFileUrl(fileName: "date.qml")); |
1004 | |
1005 | QObject *obj = c.create(); |
1006 | QVERIFY(obj); |
1007 | |
1008 | const QDateTime dt(QDate(2011, 10, 7), QTime(18, 53, 48, 345)); |
1009 | |
1010 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
1011 | Q_ARG(QVariant, QVariant(locale))); |
1012 | |
1013 | QLocale l(locale); |
1014 | const QString localeText(l.toString(dateTime: dt, format)); |
1015 | QVariant val; |
1016 | QMetaObject::invokeMethod(obj, member: "fromLocaleTimeString", Qt::DirectConnection, |
1017 | Q_RETURN_ARG(QVariant, val), |
1018 | Q_ARG(QVariant, QVariant(localeText)), |
1019 | Q_ARG(QVariant, QVariant(format))); |
1020 | |
1021 | QTime pd = l.toTime(string: localeText, format); |
1022 | QCOMPARE(val.toTime(), pd); |
1023 | } |
1024 | |
1025 | void tst_qqmllocale::numberToLocaleString_data() |
1026 | { |
1027 | QTest::addColumn<QString>(name: "locale"); |
1028 | QTest::addColumn<char>(name: "format"); |
1029 | QTest::addColumn<int>(name: "prec"); |
1030 | |
1031 | QTest::newRow(dataTag: "en_US 1") << "en_US"<< 'f' << 2; |
1032 | QTest::newRow(dataTag: "en_US 2") << "en_US"<< 'g' << 3; |
1033 | QTest::newRow(dataTag: "en_US 3") << "en_US"<< 'f' << 0; |
1034 | QTest::newRow(dataTag: "en_US 4") << "en_US"<< 'f' << -1; |
1035 | QTest::newRow(dataTag: "de_DE 1") << "de_DE"<< 'f' << 2; |
1036 | QTest::newRow(dataTag: "de_DE 2") << "de_DE"<< 'g' << 3; |
1037 | QTest::newRow(dataTag: "ar_SA 1") << "ar_SA"<< 'f' << 2; |
1038 | QTest::newRow(dataTag: "ar_SA 2") << "ar_SA"<< 'g' << 3; |
1039 | } |
1040 | |
1041 | void tst_qqmllocale::numberToLocaleString() |
1042 | { |
1043 | QFETCH(QString, locale); |
1044 | QFETCH(char, format); |
1045 | QFETCH(int, prec); |
1046 | |
1047 | QQmlComponent c(&engine, testFileUrl(fileName: "number.qml")); |
1048 | |
1049 | QObject *obj = c.create(); |
1050 | QVERIFY(obj); |
1051 | |
1052 | double number = 2344423.3289; |
1053 | |
1054 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
1055 | Q_ARG(QVariant, QVariant(locale))); |
1056 | |
1057 | QLocale l(locale); |
1058 | QVariant val; |
1059 | QMetaObject::invokeMethod(obj, member: "toLocaleString", Qt::DirectConnection, |
1060 | Q_RETURN_ARG(QVariant, val), |
1061 | Q_ARG(QVariant, QVariant(number)), |
1062 | Q_ARG(QVariant, QVariant(QString(format))), |
1063 | Q_ARG(QVariant, QVariant(prec))); |
1064 | |
1065 | if (prec < 0) prec = 2; |
1066 | QCOMPARE(val.toString(), l.toString(number, format, prec)); |
1067 | } |
1068 | |
1069 | void tst_qqmllocale::numberToLocaleCurrencyString_data() |
1070 | { |
1071 | QTest::addColumn<QString>(name: "locale"); |
1072 | QTest::addColumn<QString>(name: "symbol"); |
1073 | |
1074 | QTest::newRow(dataTag: "en_US 1") << "en_US"<< QString(); |
1075 | QTest::newRow(dataTag: "en_US 2") << "en_US"<< "USD"; |
1076 | QTest::newRow(dataTag: "de_DE") << "de_DE"<< QString(); |
1077 | QTest::newRow(dataTag: "ar_SA") << "ar_SA"<< QString(); |
1078 | QTest::newRow(dataTag: "hi_IN") << "hi_IN"<< QString(); |
1079 | QTest::newRow(dataTag: "zh_CN") << "zh_CN"<< QString(); |
1080 | QTest::newRow(dataTag: "th_TH") << "th_TH"<< QString(); |
1081 | } |
1082 | |
1083 | void tst_qqmllocale::numberToLocaleCurrencyString() |
1084 | { |
1085 | QFETCH(QString, locale); |
1086 | QFETCH(QString, symbol); |
1087 | |
1088 | QQmlComponent c(&engine, testFileUrl(fileName: "number.qml")); |
1089 | |
1090 | QObject *obj = c.create(); |
1091 | QVERIFY(obj); |
1092 | |
1093 | double number = 2344423.3289; |
1094 | |
1095 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
1096 | Q_ARG(QVariant, QVariant(locale))); |
1097 | |
1098 | QLocale l(locale); |
1099 | QVariant val; |
1100 | QMetaObject::invokeMethod(obj, member: "toLocaleCurrencyString", Qt::DirectConnection, |
1101 | Q_RETURN_ARG(QVariant, val), |
1102 | Q_ARG(QVariant, QVariant(number)), |
1103 | Q_ARG(QVariant, QVariant(symbol))); |
1104 | |
1105 | QCOMPARE(val.toString(), l.toCurrencyString(number, symbol)); |
1106 | } |
1107 | |
1108 | void tst_qqmllocale::numberFromLocaleString_data() |
1109 | { |
1110 | QTest::addColumn<QString>(name: "locale"); |
1111 | QTest::addColumn<double>(name: "number"); |
1112 | |
1113 | QTest::newRow(dataTag: "en_US 1") << "en_US"<< 1234567.2345; |
1114 | QTest::newRow(dataTag: "en_US 2") << "en_US"<< 0.234; |
1115 | QTest::newRow(dataTag: "en_US 3") << "en_US"<< 234.0; |
1116 | QTest::newRow(dataTag: "de_DE") << "de_DE"<< 1234567.2345; |
1117 | QTest::newRow(dataTag: "ar_SA") << "ar_SA"<< 1234567.2345; |
1118 | QTest::newRow(dataTag: "hi_IN") << "hi_IN"<< 1234567.2345; |
1119 | QTest::newRow(dataTag: "zh_CN") << "zh_CN"<< 1234567.2345; |
1120 | QTest::newRow(dataTag: "th_TH") << "th_TH"<< 1234567.2345; |
1121 | } |
1122 | |
1123 | void tst_qqmllocale::numberFromLocaleString() |
1124 | { |
1125 | QFETCH(QString, locale); |
1126 | QFETCH(double, number); |
1127 | |
1128 | QQmlComponent c(&engine, testFileUrl(fileName: "number.qml")); |
1129 | |
1130 | QObject *obj = c.create(); |
1131 | QVERIFY(obj); |
1132 | |
1133 | QLocale l(locale); |
1134 | QString strNumber = l.toString(i: number, f: 'f'); |
1135 | |
1136 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
1137 | Q_ARG(QVariant, QVariant(locale))); |
1138 | |
1139 | QVariant val; |
1140 | QMetaObject::invokeMethod(obj, member: "fromLocaleString", Qt::DirectConnection, |
1141 | Q_RETURN_ARG(QVariant, val), |
1142 | Q_ARG(QVariant, QVariant(strNumber))); |
1143 | |
1144 | QCOMPARE(val.toDouble(), l.toDouble(strNumber)); |
1145 | } |
1146 | |
1147 | void tst_qqmllocale::numberConstToLocaleString() |
1148 | { |
1149 | QQmlComponent c(&engine, testFileUrl(fileName: "number.qml")); |
1150 | |
1151 | QObject *obj = c.create(); |
1152 | QVERIFY(obj); |
1153 | |
1154 | QMetaObject::invokeMethod(obj, member: "setLocale", type: Qt::DirectConnection, |
1155 | Q_ARG(QVariant, QVariant("en_US"))); |
1156 | |
1157 | QLocale l("en_US"); |
1158 | QCOMPARE(obj->property("const1").toString(), l.toString(1234.56, 'f', 2)); |
1159 | QCOMPARE(obj->property("const2").toString(), l.toString(1234., 'f', 2)); |
1160 | } |
1161 | |
1162 | void tst_qqmllocale::numberOptions() |
1163 | { |
1164 | QQmlEngine engine; |
1165 | QQmlComponent comp(&engine); |
1166 | comp.setData(R"( |
1167 | import QtQml 2.15 |
1168 | QtObject { |
1169 | id: root |
1170 | property string formatted |
1171 | property bool caughtException: false |
1172 | Component.onCompleted: () => { |
1173 | const myLocale = Qt.locale("de_DE") |
1174 | myLocale.numberOptions = Locale.OmitGroupSeparator | Locale.RejectTrailingZeroesAfterDot |
1175 | root.formatted = Number(10000).toLocaleString(myLocale, 'f', 4) |
1176 | try { |
1177 | Number.fromLocaleString(myLocale, "1,10"); |
1178 | } catch (e) {console.warn(e); root.caughtException = true} |
1179 | } |
1180 | } |
1181 | )", baseUrl: QUrl( "testdata")); |
1182 | QTest::ignoreMessage(type: QtMsgType::QtWarningMsg, message: "Error: Locale: Number.fromLocaleString(): Invalid format"); |
1183 | QScopedPointer<QObject> root {comp.create()}; |
1184 | qDebug() << comp.errorString(); |
1185 | QVERIFY(root); |
1186 | QCOMPARE(root->property("formatted").toString(), QLatin1String( "10000,0000")); |
1187 | QCOMPARE(root->property("caughtException").toBool(), true); |
1188 | |
1189 | } |
1190 | |
1191 | void tst_qqmllocale::stringLocaleCompare_data() |
1192 | { |
1193 | QTest::addColumn<QString>(name: "string1"); |
1194 | QTest::addColumn<QString>(name: "string2"); |
1195 | |
1196 | QTest::newRow(dataTag: "before") << "a"<< "b"; |
1197 | QTest::newRow(dataTag: "equal") << "a"<< "a"; |
1198 | QTest::newRow(dataTag: "after") << "b"<< "a"; |
1199 | |
1200 | // Copied from QString::localeAwareCompare tests |
1201 | // We don't actually change locale - we just care that String.localeCompare() |
1202 | // matches QString::localeAwareCompare(); |
1203 | QTest::newRow(dataTag: "swedish1") << QString::fromLatin1(str: "\xe5") << QString::fromLatin1(str: "\xe4"); |
1204 | QTest::newRow(dataTag: "swedish2") << QString::fromLatin1(str: "\xe4") << QString::fromLatin1(str: "\xf6"); |
1205 | QTest::newRow(dataTag: "swedish3") << QString::fromLatin1(str: "\xe5") << QString::fromLatin1(str: "\xf6"); |
1206 | QTest::newRow(dataTag: "swedish4") << QString::fromLatin1(str: "z") << QString::fromLatin1(str: "\xe5"); |
1207 | |
1208 | QTest::newRow(dataTag: "german1") << QString::fromLatin1(str: "z") << QString::fromLatin1(str: "\xe4"); |
1209 | QTest::newRow(dataTag: "german2") << QString::fromLatin1(str: "\xe4") << QString::fromLatin1(str: "\xf6"); |
1210 | QTest::newRow(dataTag: "german3") << QString::fromLatin1(str: "z") << QString::fromLatin1(str: "\xf6"); |
1211 | } |
1212 | |
1213 | void tst_qqmllocale::stringLocaleCompare() |
1214 | { |
1215 | QFETCH(QString, string1); |
1216 | QFETCH(QString, string2); |
1217 | |
1218 | QQmlComponent c(&engine, testFileUrl(fileName: "localeCompare.qml")); |
1219 | |
1220 | QObject *obj = c.create(); |
1221 | QVERIFY(obj); |
1222 | |
1223 | obj->setProperty(name: "string1", value: string1); |
1224 | obj->setProperty(name: "string2", value: string2); |
1225 | |
1226 | QCOMPARE(obj->property("comparison").toInt(), QString::localeAwareCompare(string1, string2)); |
1227 | } |
1228 | |
1229 | class Calendar : public QObject |
1230 | { |
1231 | Q_OBJECT |
1232 | Q_PROPERTY(QLocale locale READ locale WRITE setLocale) |
1233 | public: |
1234 | Calendar() { |
1235 | } |
1236 | |
1237 | QLocale locale() const { |
1238 | return mLocale; |
1239 | } |
1240 | |
1241 | void setLocale(const QLocale &locale) { |
1242 | mLocale = locale; |
1243 | } |
1244 | private: |
1245 | QLocale mLocale; |
1246 | }; |
1247 | |
1248 | void tst_qqmllocale::localeAsCppProperty() |
1249 | { |
1250 | qmlRegisterType<Calendar>(uri: "Test", versionMajor: 1, versionMinor: 0, qmlName: "Calendar"); |
1251 | QQmlComponent component(&engine, testFileUrl(fileName: "localeAsCppProperty.qml")); |
1252 | QVERIFY2(!component.isError(), qPrintable(component.errorString())); |
1253 | QTRY_VERIFY(component.isReady()); |
1254 | |
1255 | Calendar *item = qobject_cast<Calendar*>(object: component.create()); |
1256 | QCOMPARE(item->property("locale").toLocale().name(), QLatin1String( "en_GB")); |
1257 | |
1258 | QVariant localeVariant(QLocale("nb_NO")); |
1259 | item->setProperty(name: "testLocale", value: localeVariant); |
1260 | QCOMPARE(item->property("testLocale").toLocale().name(), QLatin1String( "nb_NO")); |
1261 | } |
1262 | |
1263 | class DateFormatter : public QObject |
1264 | { |
1265 | Q_OBJECT |
1266 | public: |
1267 | DateFormatter() {} |
1268 | |
1269 | Q_INVOKABLE QString getLocalizedForm(const QString &isoTimestamp); |
1270 | }; |
1271 | |
1272 | QString DateFormatter::getLocalizedForm(const QString &isoTimestamp) |
1273 | { |
1274 | QDateTime input = QDateTime::fromString(s: isoTimestamp, f: Qt::ISODate); |
1275 | QLocale locale; |
1276 | return locale.toString(dateTime: input); |
1277 | } |
1278 | |
1279 | #if defined(Q_OS_UNIX) && QT_CONFIG(timezone) |
1280 | // Currently disabled on Windows as adjusting the timezone |
1281 | // requires additional privileges that aren't normally |
1282 | // enabled for a process. This can be achieved by calling |
1283 | // AdjustTokenPrivileges() and then SetTimeZoneInformation(), |
1284 | // which will require linking to a different library to access that API. |
1285 | static void setTimeZone(const QByteArray &tz) |
1286 | { |
1287 | if (tz.isEmpty()) |
1288 | qunsetenv(varName: "TZ"); |
1289 | else |
1290 | qputenv(varName: "TZ", value: tz); |
1291 | ::tzset(); |
1292 | |
1293 | // following left for future reference, see comment above |
1294 | // #if defined(Q_OS_WIN32) |
1295 | // ::_tzset(); |
1296 | // #endif |
1297 | } |
1298 | |
1299 | void tst_qqmllocale::timeZoneUpdated() |
1300 | { |
1301 | // Note: This test may not reliably hit the QEXPECT_FAIL clauses below if the initial |
1302 | // system time zone is equivalent to either Australia/Brisbane or Asia/Kalkota. |
1303 | |
1304 | // Initialize the system time zone, so that we actually _change_ something below. |
1305 | QVERIFY2(QTimeZone::systemTimeZone().isValid(), |
1306 | "You know, Toto, I do believe we're not in Kansas any more."); |
1307 | |
1308 | QByteArray original(qgetenv(varName: "TZ")); |
1309 | |
1310 | // Set the timezone to Brisbane time, AEST-10:00 |
1311 | setTimeZone(QByteArray("Australia/Brisbane")); |
1312 | |
1313 | QScopedPointer<QObject> obj; |
1314 | auto cleanup = qScopeGuard(f: [&original, &obj] { |
1315 | // Restore to original time zone |
1316 | setTimeZone(original); |
1317 | QMetaObject::invokeMethod(obj: obj.data(), member: "resetTimeZone"); |
1318 | }); |
1319 | |
1320 | DateFormatter formatter; |
1321 | |
1322 | QQmlEngine e; |
1323 | e.rootContext()->setContextObject(&formatter); |
1324 | |
1325 | QQmlComponent c(&e, testFileUrl(fileName: "timeZoneUpdated.qml")); |
1326 | QVERIFY2(!c.isError(), qPrintable(c.errorString())); |
1327 | obj.reset(other: c.create()); |
1328 | QVERIFY(obj); |
1329 | |
1330 | #if !defined(Q_OS_LINUX) || defined(Q_OS_ANDROID) |
1331 | QEXPECT_FAIL("", |
1332 | "Date.timeZoneUpdated() only works on non-Android Linux with QT_CONFIG(timezone).", |
1333 | Continue); |
1334 | #endif |
1335 | QVERIFY(obj->property("success").toBool()); |
1336 | |
1337 | // Change to Indian time, IST-05:30 |
1338 | setTimeZone(QByteArray("Asia/Kolkata")); |
1339 | |
1340 | QMetaObject::invokeMethod(obj: obj.data(), member: "check"); |
1341 | |
1342 | #if !defined(Q_OS_LINUX) || defined(Q_OS_ANDROID) |
1343 | QEXPECT_FAIL("", |
1344 | "Date.timeZoneUpdated() only works on non-Android Linux with QT_CONFIG(timezone).", |
1345 | Continue); |
1346 | #endif |
1347 | QVERIFY(obj->property("success").toBool()); |
1348 | } |
1349 | #endif // Unix && timezone |
1350 | |
1351 | QTEST_MAIN(tst_qqmllocale) |
1352 | |
1353 | #include "tst_qqmllocale.moc" |
1354 |
Definitions
- tst_qqmllocale
- tst_qqmllocale
- defaultLocale
- addPropertyData
- properties_data
- properties
- addCurrencySymbolData
- currencySymbol_data
- currencySymbol
- addFormatNameData
- addStandardFormatData
- monthName_data
- monthName
- standaloneMonthName_data
- standaloneMonthName
- dayName_data
- dayName
- standaloneDayName_data
- standaloneDayName
- firstDayOfWeek_data
- firstDayOfWeek
- weekDays_data
- weekDays
- uiLanguages_data
- uiLanguages
- dateTimeFormat_data
- dateTimeFormat
- dateFormat_data
- dateFormat
- timeFormat_data
- timeFormat
- dateToLocaleString_data
- dateToLocaleString
- addDateTimeFormatData
- dateToLocaleStringFormatted_data
- dateToLocaleStringFormatted
- dateToLocaleDateString_data
- dateToLocaleDateString
- addDateFormatData
- dateToLocaleDateStringFormatted_data
- dateToLocaleDateStringFormatted
- dateToLocaleTimeString_data
- dateToLocaleTimeString
- addTimeFormatData
- dateToLocaleTimeStringFormatted_data
- dateToLocaleTimeStringFormatted
- dateFromLocaleString_data
- dateFromLocaleString
- dateFromLocaleDateString_data
- dateFromLocaleDateString
- dateFromLocaleTimeString_data
- dateFromLocaleTimeString
- numberToLocaleString_data
- numberToLocaleString
- numberToLocaleCurrencyString_data
- numberToLocaleCurrencyString
- numberFromLocaleString_data
- numberFromLocaleString
- numberConstToLocaleString
- numberOptions
- stringLocaleCompare_data
- stringLocaleCompare
- Calendar
- Calendar
- locale
- setLocale
- localeAsCppProperty
- DateFormatter
- DateFormatter
- getLocalizedForm
- setTimeZone
Start learning QML with our Intro Training
Find out more